import Http from "../utils/http";
import { host } from "../utils/constant";
const cHttp = new Http(host);

export function startCharge(sn: string) {
  return cHttp.get<{
    ConnectorID: string;
    FailReason: number;
    StartChargeSeq: string;
    StartChargeSeqStat: number;
    SuccStat: number;
  }>(`/charge/startCharge?connector_id=${sn}`, {
    statusCodeHandle: false,
  });
}

export function fetchStationPriceDesc(ConnectorID: string, StationID?: string) {
  return cHttp
    .get(`/charge/businessPolicy?connector_id=${ConnectorID}`)
    .then((res) => {
      const nowHour = new Date().getHours();
      let currentPrice = 0;
      let currentTime = "00:00～24:00";
      if (res && res.PolicyInfos && res.PolicyInfos.length) {
        res.PolicyInfos.forEach((item: any, index: number) => {
          const hour = item.StartTime.substring(0, 2);
          const min = item.StartTime.substring(2, 4);
          if (index >= res.PolicyInfos.length - 1) {
            // 最后一个
            item.StartTimeFormat = `${hour}:${min}~24:00`;
            if (Number(hour) <= nowHour) {
              currentPrice = Number(
                Number(item.ElecPrice + item.SevicePrice).toFixed(2)
              );
              currentTime = `${hour}:${min}~24:00`;
            }
          } else {
            const nhour = res.PolicyInfos[index + 1].StartTime.substring(0, 2);
            const nmin = res.PolicyInfos[index + 1].StartTime.substring(2, 4);
            item.StartTimeFormat = `${hour}:${min}~${nhour}:${nmin}`;
            if (nowHour >= Number(hour) && nowHour < Number(nhour)) {
              currentPrice = Number(
                Number(item.ElecPrice + item.SevicePrice).toFixed(2)
              );
              currentTime = `${hour}:${min}~${nhour}:${nmin}`;
            }
          }
        });
      }
      res.CurrentPrice = currentPrice;
      res.CurrentTime = currentTime;
      if (StationID) {
        res.StationID = StationID;
      }
      return res;
    });
}

export function cancelCharge(sn: string) {
  return cHttp.get(`/charge/stopCharge?connector_id=${sn}`, {
    statusCodeHandle: false,
  });
}

export function fetchChargeStatus() {
  return cHttp.get("/charge/chargeStatus", {
    statusCodeHandle: false,
  });
}

export function fetchStations(
  page: number,
  pageSize: number,
  latitude?: number,
  longitude?: number,
  baseLatitude?: number,
  baseLongitude?: number,
  options?: {
    distance?: number;
    status?: number;
  }
): Promise<any[]> {
  return fetchAllStations()
    .then((res) => {
      // console.log(latitude, longitude);
      let list = JSON.parse(JSON.stringify(res));
      const data: any[] = [];
      const start = (page - 1) * pageSize;
      const end = start + pageSize;
      if (latitude && longitude) {
        list.forEach((item: any) => {
          item.StationLatDistance = _getDistance(
            latitude,
            longitude,
            item.StationLat,
            item.StationLng
          );
        });
        list.sort((item1: any, item2: any) => {
          return item1.StationLatDistance - item2.StationLatDistance;
        });
      }
      if (options) {
        if (options.distance) {
          list = list.filter(
            (item: any) => item.StationLatDistance <= (options.distance || 20)
          );
        }
      }
      list.forEach((item: any, index: number) => {
        if (index >= start && index < end) {
          data.push(item);
        }
      });
      if (baseLatitude && baseLongitude) {
        data.forEach((item: any) => {
          item.StationLatDistance = _getDistance(
            baseLatitude,
            baseLongitude,
            item.StationLat,
            item.StationLng
          );
        });
      }
      return _fetchStationStatus(data);
    })
    .then((list) => {
      if (options && options.status) {
        let res = false;
        list = list.filter((item: any) => {
          res = false;
          item.EquipmentInfos.forEach((eqInfo: any) => {
            eqInfo.ConnectorInfos.forEach((coInfo: any) => {
              if (
                !res &&
                options.status === 1 &&
                coInfo.ConnectorStatusInfo &&
                coInfo.ConnectorStatusInfo.Status === 1
              ) {
                res = true;
              }
              if (
                !res &&
                options.status === 2 &&
                coInfo.ConnectorStatusInfo &&
                coInfo.ConnectorStatusInfo.Status !== 1
              ) {
                res = true;
              }
            });
          });
          return res;
        });
      }
      return list;
    });
}

export function fetchStation(id: number) {
  return fetchAllStations()
    .then((res) => {
      const findIndex = res.findIndex((item) => Number(item.StationID) === id);
      if (findIndex < 0) {
        throw {
          errMsg: "not found",
        };
      }
      return _fetchStationStatus([res[findIndex]]);
    })
    .then((list) => {
      return list[0];
    });
}

export function fetchStationByIds(ids: number[]) {
  return fetchAllStations().then((res) => {
    const list = res.filter((item) => ids.includes(Number(item.StationID)));
    return _fetchStationStatus(list);
  });
}

export function searchStation(keyword: string) {
  return fetchAllStations().then((res) => {
    const reg = new RegExp(keyword, "ig");
    const list = res.filter(
      (item) => reg.test(item.StationName) || reg.test(item.Address)
    );
    return _fetchStationStatus(list);
  });
}

export function fetchAllStations(): Promise<any[]> {
  if (getApp().globalData.stations.length > 0) {
    return Promise.resolve(getApp().globalData.stations);
  }
  const page = 1;
  const page_size = 99;
  return new Promise((resolve, reject) => {
    _fetchAllStations(page, page_size, [])
      .then((list) => {
        // if (!isProduction) {
        //   list.push({
        //     ...list[0],
        //     StationName: '这是模拟数据，不要使用充电',
        //     Address: '这是模拟数据，测试一下附近的点',
        //     StationLat: 22.540545,
        //     StationLng: 113.942695,
        //     StationID: '0000'
        //   })
        // }
        getApp().globalData.stations = list;
        resolve(list);
      })
      .catch(reject);
  });
}

function _fetchAllStations(
  page: number,
  pageSize: number,
  list: any[]
): Promise<any[]> {
  return _fetchStations(page, pageSize).then((res) => {
    list = list.concat(res);
    if (res.length >= pageSize) {
      return _fetchAllStations(page + 1, pageSize, list);
    } else {
      // eslint-disable-next-line promise/no-return-wrap
      return Promise.resolve(list);
    }
  });
}

function _fetchStations(page: number, pageSize: number) {
  return cHttp
    .get<{
      StationInfos: any[];
    }>(`/charge/stationList?page_no=${page}&page_size=${pageSize}`)
    .then((res) => {
      res.StationInfos &&
        res.StationInfos.forEach((item) => {
          item.fastEquipmentInfos = [];
          item.slowEquipmentInfos = [];
          item.TotalFee = Number(
            Number(
              Number(item.ElectricityFee) +
                Number(item.ParkFee) +
                Number(item.ServiceFee)
            ).toFixed(2)
          );
        });

      return (res.StationInfos || []).filter((item: any) => {
        return !["1657"].includes(item.StationID);
      });
    });
}

function _getDistance(lat1: number, lng1: number, lat2: number, lng2: number) {
  var radLat1 = (lat1 * Math.PI) / 180.0;
  var radLat2 = (lat2 * Math.PI) / 180.0;
  var a = radLat1 - radLat2;
  var b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0;
  var s =
    2 *
    Math.asin(
      Math.sqrt(
        Math.pow(Math.sin(a / 2), 2) +
          Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)
      )
    );
  s = s * 6378.137; // EARTH_RADIUS;
  s = Math.round(s * 10000) / 10000;
  return s;
}

function _fetchStationStatus(list: any[]) {
  if (list.length <= 0) {
    return Promise.resolve([]);
  }
  let _list: any[] = [];
  return cHttp
    .get(
      `/charge/stationStatus?station_ids=${list
        .filter((item) => item.StationID !== "0000")
        .map((item) => item.StationID)
        .join(",")}`
    )
    .then((res) => {
      const StationStatusInfos = res.StationStatusInfos || [];
      const ConnectorIDs: string[] = [];
      const StationIDs: string[] = [];
      list.forEach((item: any) => {
        item.fastEquipmentInfos = [];
        item.slowEquipmentInfos = [];
        const StationStatusInfo = StationStatusInfos.find(
          (status: any) => status.StationID === Number(item.StationID)
        );
        let ConnectorID = "";
        item.EquipmentInfos.forEach((eqInfo: any) => {
          eqInfo.ConnectorInfos.forEach((coInfo: any) => {
            if (StationStatusInfo) {
              const ConnectorStatusInfo =
                StationStatusInfo.ConnectorStatusInfos.find(
                  (costatus: any) => costatus.ConnectorID === coInfo.ConnectorID
                );
              if (ConnectorStatusInfo) {
                coInfo.ConnectorStatusInfo = ConnectorStatusInfo;
              }
            }
            if (!ConnectorID) {
              ConnectorID = coInfo.ConnectorID;
            }
          });
          if ([1].includes(Number(eqInfo.EquipmentType))) {
            item.fastEquipmentInfos.push(eqInfo);
          } else {
            item.slowEquipmentInfos.push(eqInfo);
          }
        });
        if (ConnectorID) {
          ConnectorIDs.push(ConnectorID);
          StationIDs.push(item.StationID);
        }
      });
      _list = list;
      return Promise.all(
        ConnectorIDs.map((cid, cindex) => {
          return fetchStationPriceDesc(cid, StationIDs[cindex]);
        })
      );
    })
    .then((res) => {
      // console.log('我要看的数据', res)
      if (res && res.length) {
        _list.forEach((item) => {
          const i = res.findIndex((r) => r.StationID === item.StationID);
          if (i >= 0) {
            item.TotalFee = res[i].CurrentPrice;
          }
        });
      }
      return _list;
    });
}
