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/${sn}`, {
    statusCodeHandle: false,
  });
}

export function fetchStationPriceDesc(ConnectorID: string, StationID?: string) {
  return cHttp.get(`/charge/businessPolicy/${ConnectorID}`).then((res) => {
    const nowHour = new Date().getHours();
    let maxPrice = 0;
    let minPrice = 9;
    let currentPrice = 0;
    let currentTime = "00:00～24:00";
    res.useTime = "";
    if (res && res.policyInfoss && res.policyInfoss.length) {
      res.policyInfoss.forEach((item: any, index: number) => {
        const hour = item.startTime.substring(0, 2);
        const min = item.startTime.substring(3, 5);
        if (index === 0) {
          res.useTime = `${hour}:${min}~24:00`;
        }
        let tempPrice = Number(
          Number(item.elecPrice + item.servicePrice).toFixed(2)
        );
        if (tempPrice > maxPrice) {
          maxPrice = tempPrice;
        }
        if (tempPrice < minPrice) {
          minPrice = tempPrice;
        }
        if (index >= res.policyInfoss.length - 1) {
          // 最后一个
          item.startTimeFormat = `${hour}:${min}~24:00`;
          if (Number(hour) <= nowHour) {
            currentPrice = tempPrice;
            currentTime = `${hour}:${min}~24:00`;
          }
        } else {
          const nhour = res.policyInfoss[index + 1].startTime.substring(0, 2);
          const nmin = res.policyInfoss[index + 1].startTime.substring(3, 5);
          item.startTimeFormat = `${hour}:${min}~${nhour}:${nmin}`;
          if (nowHour >= Number(hour) && nowHour < Number(nhour)) {
            currentPrice = tempPrice;
            currentTime = `${hour}:${min}~${nhour}:${nmin}`;
          }
        }
      });
    }
    res.maxPrice = maxPrice;
    res.minPrice = minPrice;
    res.currentPrice = currentPrice;
    res.currentTime = currentTime;
    if (StationID) {
      res.StationID = StationID;
    }
    return res;
  });
}

export function cancelCharge(sn: string) {
  return cHttp.get(`/charge/stopCharge/${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.location.stationLat,
            item.location.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.location.stationLat,
            item.location.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<any>().globalData.stations.length > 0) {
    return Promise.resolve(getApp<any>().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'
        //   })
        // }
        console.log("所有电站数据", list);
        getApp<any>().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(`/charge/listStation?pageNum=${page}&pageSize=${pageSize}`)
    .then((res) => {
      const data = res || [];
      data.forEach((item: any) => {
        item.StationID = item.stationId;
        item.fastEquipmentInfos = [];
        item.slowEquipmentInfos = [];
        item.totalFee = Number(
          Number(
            Number(item.electricityFee) +
              Number(item.parkFee) +
              Number(item.serviceFee)
          ).toFixed(2)
        );
      });
      return data.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?stationIds=${list
        .filter((item) => item.StationID !== "0000")
        .map((item) => item.StationID)
        .join(",")}`
    )
    .then((res) => {
      const StationStatusInfos = res || [];
      const ConnectorIDs: string[] = [];
      const StationIDs: string[] = [];
      list.forEach((item: any) => {
        item.fastEquipmentInfos = [];
        item.slowEquipmentInfos = [];
        const StationStatusInfo = StationStatusInfos.find(
          (status: any) => Number(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) => {
      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;
    });
}
