import axios, {
  AxiosInstance,
  AxiosResponse,
  AxiosRequestConfig,
} from "axios";
import { v4 } from "uuid";
import { SignUtil } from "./SignUtil";
import {
  ApiRequestBase,
  ApiRequest,
  ApiResponse,
  GetConfigInfoResponse,
  GetDeviceListRequest,
  GetParkingNodeRequest,
  GetParkingNodeResponse,
  AddCarCardNoRequest,
  GetCarCardInfoRequest,
  GetCarCardInfoResponse,
  ModifyCarCardNoRequest,
  DelCarCardInfoRequest,
  PayCarCardFeeRequest,
  RefundCarCardFeeRequest,
  AuditCardRechargeRequest,
  RechargeInvoiceRequest,
  ModifyCardStatusRequest,
  ReserveSpaceRequest,
  ReserveSpaceChangeTimeRequest,
  CancelReserveSpaceRequest,
  GetReservableInfoRequest,
  GetParkingPaymentInfoRequest,
  PayParkingFeeRequest,
  SyncChargePilePayRequest,
  UnlicensedCarInoutRequest,
  SigningRequest,
  GetFeeDetailReq,
  GetFeeDetailRes,
  QueryCarInfoRequest,
  GetFreeSpaceNumRequest,
  GetFreeSpaceNumResponse,
  GetDeviceStatusRequest,
  GetCarInfoByNodeIdRequest,
  GetNodeCarInfoRequest,
  RemoteOpenRequest,
  ModifyCarInfoRequest,
  AddVirtualTrafficRequest,
  RecaptureRequest,
  AddCarBlackInfoRequest,
  DelCarBlackInfoRequest,
  QueryCarBlackInfoRequest,
  LockCarplateRequest,
  UnlockCarplateRequest,
  QueryCurrentUserRequest,
  QueryCurrentUserResponse,
  QueryRecordByIdRequest,
  QueryRecordByIdResponse,
  GetMyBaseInfoRequest,
  GetMyBaseInfoReponse,
  FindLotRolesRequest,
  FindLotRolesResponse,
  FindListByLotIdPageRequest,
  FindListByLotIdPageResponse,
  SaveLogRequest,
  Recharge3rdByUnityRequest,
  QueryLotMer4UnityRequest,
  CarLeaveRequest,
  PushServiceDateRequest,
  ModifyValidTimeRequest,
  ReqBookingRefund,
  ReStatisticsRequest,
  ChannelSendReuqst,
} from "./Dto";

export type Options = {
  /**
   * 接口根地址
   */
  url: string;

  appId: string;
  appSecret: string;

  /**
   * 接口版本号，默认1.0.0
   */
  version?: string;

  /**
   * 语种，默认zh-CN
   */
  lang?: string;

  /**
   * 超时时间(毫秒)，默认20秒
   */
  timeout?: number;
};

/**
 * 统一接口客户端
 */
export class ApiClient {
  public readonly axiosInstance: AxiosInstance;

  constructor(opts: Options) {
    let axiosInstance = axios.create({
      baseURL: opts.url,
      timeout: opts.timeout || 20 * 1000,
      headers: {
        "Content-Type": "application/json;charset=utf-8",
        version: opts.version || "1.0.0",
        "accept-language": opts.lang || "zh-CN",
      },
    });

    axiosInstance.interceptors.request.use((config) => {
      let headers = config.headers || {};
      if (!headers["trace-id"]) headers["trace-id"] = v4();
      config.headers = headers;

      let data = (config.data || {}) as ApiRequestBase;

      //填充serviceCode
      if (!data.serviceCode && config.url) {
        let serviceCode = config.url.split("/").pop();
        data.serviceCode =
          serviceCode.charAt(0).toLowerCase() + serviceCode.slice(1);
      }

      //签名
      if (!data.key) {
        data.appId = opts.appId;
        if (!data.reqId) data.reqId = v4();
        data.ts = Date.now().toString();
        data.key = SignUtil.sign(data, opts.appSecret);
      }

      config.data = data;
      return config;
    });

    this.axiosInstance = axiosInstance;
  }

  async post<T = any, D = ApiRequest>(
    url: string,
    data?: D,
    config?: AxiosRequestConfig & {
      /**
       * api描述，仅为记录日志
       */
      apiDesc?: string;
    }
  ) {
    let res = await this.axiosInstance.post<
      ApiResponse<T>,
      AxiosResponse<ApiResponse<T>>
    >(url, data, config);
    return res.data;
  }

  /**
   * 2.0.1 获取平台配置信息
   */
  async getConfigInfo() {
    let res = await this.post<GetConfigInfoResponse>(
      "config/platform/GetConfigInfo",
      null,
      { apiDesc: "2.0.1获取平台配置信息" }
    );

    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data;
  }

  /**
   * SQL通道-list
   * @param sql
   * @param parkId
   * @param timeout 超时时间(毫秒)
   * @returns
   */
  async list<T = any>(sql: string, parkId: number | string, 
    opts?: {
      timeout?: number
    }) {
    let res = await this.post<T[]>(
      "dbproxy/list",
      { parkId, sql },
      {
        headers: { "kt-lotcodes": parkId, version: "1.0" },
        apiDesc: "sql通道-list",
        timeout: opts?.timeout,
      }
    );

    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data;
  }

  /**
   * SQL通道-selectOne
   * @param sql
   * @param parkId
   * @param timeout 超时时间(毫秒)，默认20秒
   * @returns
   */
  async selectOne<T = any>(
    sql: string,
    parkId: number | string,
    opts?: {
      timeout?: number
    }
  ) {
    let res = await this.post<T>(
      "dbproxy/selectOne",
      { parkId, sql },
      {
        headers: { "kt-lotcodes": parkId, version: "1.0" },
        apiDesc: "sql通道-selectOne",
        timeout: opts?.timeout,
      }
    );

    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data;
  }

  /**
   * SQL通道-execute
   */
  /**
   * SQL通道-execute
   */
  async execute(
    sql: string | string[],
    parkId: number | string,
    opts?: {
      openTx?: 1 | 0,
      timeout?: number
    }
  ) {
    return await this.post(
      "dbproxy/execute",
      {
        sqlList: typeof sql === "string" ? [sql] : sql,
        parkId,
        openTx: opts?.openTx,
      },
      {
        headers: { "kt-lotcodes": parkId, version: "1.0" },
        apiDesc: "sql通道-execute",
        timeout: opts?.timeout,
      }
    );
  }

  /**
   * 2.1.1获取停车场列表
   */
  async getParkingLotList(request: { pageIndex: any; pageSize: any }): Promise<{
    pageIndex: any;
    pageSize: any;
    totalCount: number;
    parkingList: any;
  }> {
    let res = await this.post("api/wec/GetParkingLotList", request, {
      apiDesc: "2.1.1获取停车场列表",
    });
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data;
  }

  /**
   * 2.1.2停车场信息查询接口
   */
  async getParkingLotInfo(request: {
    /**
     * 车场id
     */
    parkId: any;
  }): Promise<{
    /**
     * 车场id
     */
    parkId: any;
    /**
     * 车场名称
     */
    parkName: string;
    /**
     * 总车位数
     */
    totalSpaceNum: number;
  }> {
    let res = await this.post("api/wec/GetParkingLotInfo", request, {
      apiDesc: "2.1.2停车场信息查询接口",
    });
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.1.3车场终端设备查询接口
   * 获取车场终端设备信息列表
   */
  async getDeviceList(request?: GetDeviceListRequest): Promise<{
    deviceList: {
      /**
       * 设备编码（此设备编号为设备的id（数据库主键））
       */
      deviceCode: string;

      /**
       * 设备Ip
       */
      deviceIp: string;

      /**
       * 设备名称
       */
      deviceName: string;

      /**
       * 设备类型 详见参数枚举1.6.6
       */
      deviceType: number;
    }[];
  }> {
    let res = await this.post<string>("api/wec/GetDeviceList", request, {
      apiDesc: "2.1.3车场终端设备查询接口",
    });
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.1.5通道信息
   * 获取通道信息
   */
  async getParkingNode(
    request: GetParkingNodeRequest
  ): Promise<GetParkingNodeResponse> {
    let res = await this.post<string>("api/wec/GetParkingNode", request, {
      apiDesc: "2.1.5通道信息",
    });
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.1.6停车场信息查询扩展接口
   */
  async getParkingLotInfoExt(request: { parkId: any }): Promise<{
    parkId: any;
    parkName: string;
    totalSpaceNum: number;
    limitL: number;
    limitW: number;
    limitH: number;
    lon: string;
    lat: string;
    addr: string;
    tel: string;
    imgUrl: string;
    workTime: string;
    payRule: string;
    province: string;
    city: string;
    area: string;
  }> {
    let res = await this.post("api/wec/GetParkingLotInfoExt", request, {
      apiDesc: "2.1.6停车场信息查询扩展接口",
    });
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.2.1固定车新增接口
   */
  async addCarCardNo(
    request: AddCarCardNoRequest
  ) {
    return await this.post<string>("api/wec/AddCarCardNo", request, {
      apiDesc: "2.2.1固定车新增接口",
    });
  }

  /**
   * 2.2.2固定车查询接口
   */
  async getCarCardInfo(
    request: GetCarCardInfoRequest
  ): Promise<GetCarCardInfoResponse> {
    let res = await this.post<string>("api/wec/GetCarCardInfo", request, {
      apiDesc: "2.2.2固定车查询接口",
    });
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.2.3固定车修改接口
   */
  async modifyCarCardNo(request: ModifyCarCardNoRequest) {
    return await this.post("api/wec/ModifyCarCardNo", request, {
      apiDesc: "2.2.3固定车修改接口",
    });
  }

  /**
   * 2.2.4固定车删除接口
   */
  async delCarCardInfo(request: DelCarCardInfoRequest) {
    return await this.post("api/wec/DelCarCardInfo", request, {
      apiDesc: "2.2.4固定车删除接口",
    });
  }

  /**
   * 2.2.6固定车充值接口
   */
  async payCarCardFee(request: PayCarCardFeeRequest) {
    return await this.post("api/wec/PayCarCardFee", request, {
      apiDesc: "2.2.6固定车充值接口",
    });
  }

  /**
  * 2.2.7 获取图片存储根地址
  */
  async getImageBaseUrl(request: { parkId: any; serviceCode?: 'GetImageBaseUrl' }) {
    return await this.post<ApiResponse>('nkcInnerApi/normal/getImageBaseUrl', request, { apiDesc: '2.2.7 获取图片存储根地址' });
  }

  async getCarCardChargeList(request: any) {
    let res = await this.post<string>("api/wec/GetCarCardChargeList", request, {
      apiDesc: "2.2.8查询固定车充值信息",
    });
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.2.9固定车退款接口
   */
  async refundCarCardFee(
    request: RefundCarCardFeeRequest
  ) {
    return await this.post("api/wec/RefundCarCardFee", request, {
      apiDesc: "2.2.9固定车退款接口",
    });
  }

  /**
   * 2.2.10固定车审核
   */
  async auditCardRecharge(
    request: AuditCardRechargeRequest
  ) {
    return await this.post("api/wec/AuditCardRecharge", request, {
      apiDesc: "2.2.10固定车审核",
    });
  }

  /**
   * 2.2.11固定车充值开票
   */
  async rechargeInvoice(request: RechargeInvoiceRequest) {
    return await this.post("api/wec/RechargeInvoice", request, {
      apiDesc: "2.2.11固定车充值开票",
    });
  }

  /**
   * 2.2.12内部车注销恢复
   */
  async modifyCardStatus(
    request: ModifyCardStatusRequest
  ) {
    return await this.post("api/wec/ModifyCardStatus", request, {
      apiDesc: "2.2.12内部车注销恢复",
    });
  }

  /**
   * 2.3.1查询进出记录
   */
  async getCarInoutInfo(request: {
    parkId: any;
    plateNo?: string;
    cardNo?: string;
    pageIndex: number;
    pageSize: number;
    startTime?: string;
    endTime?: string;
    capFlag?: number;
    passType?: number;
  }): Promise<{
    totalCount: number;
    detailList: any;
  }> {
    let res = await this.post<string>("api/wec/GetCarInoutInfo", request, {
      apiDesc: "2.3.1查询进出记录",
    });
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.3.2查询缴费记录
   */
  async getParkingPaymentList(request: {
    parkId: any;
    plateNo?: string;
    cardNo?: string;
    inTime?: string;
    outTime?: string;
    pageIndex: number;
    pageSize: number;
    startTime?: string;
    endTime?: string;
    payMethod?: number;
  }): Promise<{
    totalCount: number;
    plateList: any;
  }> {
    let res = await this.post<string>(
      "api/wec/GetParkingPaymentList",
      request,
      { apiDesc: "2.3.2查询缴费记录" }
    );
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.3.4获取缴费记录上报所需要的数据
   */
  async getUploadPayList(request: {
    parkId: any;
    /**
     * 支付ID，收费系统6.0不支持此参数
     */
    payDetailId?: string;
    syncBeginTime: string;
    syncEndTime: string;
  }): Promise<{
    payList: any;
  }> {
    let res = await this.post<string>("api/wec/GetUploadPayList", request, {
      apiDesc: "2.3.4获取缴费记录上报所需要的数据",
    });
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.4.1用户车位预订
   *
   * 返回的是json字符串，需要手动转对象
   */
  async reserveSpace(
    request: ReserveSpaceRequest
  ) {
    return await this.post<string>("api/find/ReserveSpace", request, {
      apiDesc: "2.4.1用户车位预订",
    });
  }

  /**
   * 2.4.2修改预约车有效期
   */
  async reserveSpace_ChangeTime(
    request: ReserveSpaceChangeTimeRequest
  ) {
    return await this.post("api/find/ReserveSpace_ChangeTime", request, {
      apiDesc: "2.4.2修改预约车有效期",
    });
  }

  /**
   * 2.4.3车位预订取消接口
   */
  async cancelReserveSpace(
    request: CancelReserveSpaceRequest
  ) {
    return await this.post("api/find/CancelReserveSpace", request, {
      apiDesc: "2.4.3车位预订取消接口",
    });
  }
  /**
   * 2.4.4预订车位查询接口
   */
  async getReservableInfo(
    request: GetReservableInfoRequest
  ) {
    return await this.post("api/find/GetReservableInfo", request, {
      apiDesc: "2.4.4预订车位查询接口",
    });
  }

  /**
     * 2.4.6 在场车辆清理
     */
  async carLeave(request: CarLeaveRequest) {
    return await this.post('nkcInnerApi/carcome/carLeave', request, { apiDesc: '2.4.6 在场车辆清理' });
  }

  /**
 * 2.4.9 下发服务时间
 */
  async pushServiceDate(request: PushServiceDateRequest) {
    return this.post('nkcInnerApi/control/pushServiceDate', request, { apiDesc: '2.4.9 下发服务时间' });
  }

  /**
     * 2.4.12 出口识别车牌修改
     */
  async carInModify(request: {
    parkId: any;
    nodeId: any;
    serial: any;
    carStyle: '';
    carNo: any;
    carNo2?: any;
    carNoColor?: any;
    imgName?: any;
    userId?: any;
    serviceCode: 'CarInModify';
  }) {
    return await this.post('nkcInnerApi/control/carInModify', request, { apiDesc: '2.4.12 出口识别车牌修改' });
  }

  /**
     * 2.4.12 出口识别车牌修改
     */
  async carOutModify(request: {
    parkId: any;
    nodeId: any;
    deviceIp?: string;
    serial: any;
    carStyle?: any;
    carNo?: any;
    carNo2?: any;
    carNoColor?: any;
    carBrand?: any;
    imgName?: any;
    operName?: any;
    recogEnable?: any;
    carOutTime?: any;
    /**
     * 修改项 0-车牌 1-车型  2-车牌颜色 3-车辆品来
     */
    modifyItem: number;
    serviceCode: 'CarOutModify';
  }) {
    return await this.post('nkcInnerApi/control/carOutModify', request, { apiDesc: '2.4.12 出口识别车牌修改' });
  }

  /**
   * 2.5.1账单查询/费用查询
   *
   * data是json字符串(如果有值),需要进行转换GetParkingPaymentInfoRequest
   */
  async getParkingPaymentInfo(
    request: GetParkingPaymentInfoRequest
  ) {
    return await this.post("api/wec/GetParkingPaymentInfo", request, {
      apiDesc: "2.5.1账单查询/费用查询",
    });
  }

  /**
   * 2.5.2停车费支付
   */
  async payParkingFee(request: PayParkingFeeRequest) {
    return await this.post("api/wec/PayParkingFee", request, {
      apiDesc: "2.5.2停车费支付",
    });
  }

  /**
   * 2.5.3查询订单状态
   */
  async getOrderStatus(request: {
    parkId: any;
    orderNo: string;
  }) {
    return await this.post("api/wec/GetOrderStatus", request, {
      apiDesc: "2.5.3查询订单状态",
    });
  }

  /**
   * 2.5.4充电桩抵扣
   */
  async syncChargePilePay(
    request: SyncChargePilePayRequest
  ) {
    return await this.post<ApiResponse>("api/wec/SyncChargePilePay", request, {
      apiDesc: "2.5.4充电桩抵扣",
    });
  }

  /**
   * 2.5.5无牌车扫出入口二维码进出场
   */
  async unlicensedCarInout(
    request: UnlicensedCarInoutRequest
  ) {
    return this.post("api/wec/UnlicensedCarInout", request, {
      apiDesc: "2.5.5无牌车扫出入口二维码进出场",
    });
  }

  /**
   * 2.5.6车辆无感支付签约变更通知接口
   */
  async signing(request: SigningRequest) {
    return this.post<string>("api/nosense/Signing", request, {
      apiDesc: "2.5.6车辆无感支付签约变更通知接口",
    });
  }

  async getInvoiceData(request: {
    parkId: any;
    plateNo?: string;
    cardNo?: string;
    beginTime: string;
    endTime: string;
  }) {
    return await this.post("api/wec/GetInvoiceData", request, {
      apiDesc: "2.5.9获取可开票的缴费记录",
    });
  }

  async syncInvoiceInfo(request: {
    parkId: any;
    plateNo?: string;
    cardNo?: string;
    invoiceNo: string;
    invoiceTime: string;
    invoiceStatus: number;
    totalMoney: number;
    /**
     * 数组字符串
     * type:number;//0：结算表纪录，1：提前缴费记录（5.x）
     * billId:string;
     */
    payList: any;
  }) {
    return await this.post<ApiResponse>("api/wec/SyncInvoiceInfo", request, {
      apiDesc: "2.5.10同步开票信息",
    });
  }

  async cancelInvoice(request: {
    parkId: any;
    invoiceNo: string;
  }) {
    return await this.post("api/wec/CancelInvoice", request, {
      apiDesc: "2.5.11取消开票信息",
    });
  }

  async syncRefundState(request: {
    parkId: any;
    orderNo: string;
    refundNo: string;
    refundType: any;
    state: any;
    remark: string;
    refundTime: string;
    refundMerchantNo?: string;
    merchantNo?: string;
  }) {
    return await this.post("api/wec/SyncRefundState", request, {
      apiDesc: "2.5.14退款状态同步",
    });
  }

  async syncRefundAudit(request: {
    parkId: any;
    refundNo: string;
    auditState: any;
    auditName: string;
    auditTime: string;
    remark: string;
  }) {
    return await this.post("api/wec/SyncRefundAudit", request, {
      apiDesc: "2.5.15退款审核状态下发(审核流程)",
    });
  }

  /**
   * 2.5.17 获取计费详情GetFeeDetailRes
   */
  async getFeeDetail(
    request: GetFeeDetailReq
  ) {
    return await this.post<string>("nkcInnerApi/bill/getFeeDetail", request, {
      apiDesc: "2.5.17 获取计费详情",
    });
  }

  /**
   * 2.6.1在场车辆查询
   */
  async queryCarInfo(request: QueryCarInfoRequest) {
    let res = await this.post<string>("api/wec/QueryCarInfo", request, {
      apiDesc: "2.6.1在场车辆查询",
    });
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.6.2剩余车位查询GetFreeSpaceNumResponse
   */
  async getFreeSpaceNum(
    request: GetFreeSpaceNumRequest
  ): Promise<GetFreeSpaceNumResponse> {
    let res = await this.post<string>("api/wec/GetFreeSpaceNum", request, {
      apiDesc: "2.6.2剩余车位查询",
    });
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.6.3设备状态查询GetDeviceStatusRequest
   */
  async getDeviceStatus(request?: GetDeviceStatusRequest) {
    // deviceCode: string;
    // deviceIp: string;
    // deviceName: string;
    // deviceType: string;
    // deviceStatus: string;
    // deviceTime: string
    let res = await this.post<string>("api/wec/GetDeviceStatus", request, {
      apiDesc: "2.6.3设备状态查询",
    });
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data;
  }

  /**
   * 2.6.4根据通道获取当前车辆GetCarInfoByNodeIdRequest
   */
  async getCarInfoByNodeId(
    request?: GetCarInfoByNodeIdRequest
  ) {
    return await this.post<string>("api/wec/GetCarInfoByNodeId", request, {
      apiDesc: "2.6.4根据通道获取当前车辆",
    });
  }

  /**
   * 2.6.6获取车辆图片信息
   */
  async getParkingImg(request: {
    parkId: any;
    imgName: string;
    type: number;
  }): Promise<{
    imgUrl: string;
  }> {
    let res = await this.post<string>("api/wec/GetParkingImg", request, {
      apiDesc: "2.6.6获取车辆图片信息",
    });
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.6.9查询车辆当前所在车场
   */
  async getCarLocatePartId(request: { plateNo: string }): Promise<{
    parkId: any;
  }> {
    let res = await this.post<string>(
      "config/platform/GetCarLocatePartId",
      request,
      { apiDesc: "2.6.9查询车辆当前所在车场" }
    );
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.6.10区域剩余车位查询
   */
  async getAreaFreeSpaceNum(request: { parkId: any }): Promise<{
    areaInfo: any;
  }> {
    let res = await this.post<string>("api/wec/GetAreaFreeSpaceNum", request, {
      apiDesc: "2.6.10区域剩余车位查询",
    });
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.6.16根据通道获取当前车辆(地感车辆信息)
   */
  async getNodeCarInfo(request: GetNodeCarInfoRequest): Promise<{
    carPlateNum: string;
    capTime: string;
    serial: string;
    imgName: string; //图片地址
    carNoColor: string; //车牌颜色
  }> {
    let res = await this.post<string>("api/wec/GetNodeCarInfo", request, {
      apiDesc: "2.6.16根据通道获取当前车辆(地感车辆信息)",
    });
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.7.1空闲车位修改
   */
  async modifyFreeSpace(request: {
    parkId: any;
    areaCode?: any;
    freeSpaceNum: number;
  }) {
    return await this.post("api/control/ModifyFreeSpace", request, {
      apiDesc: "2.7.1空闲车位修改",
    });
  }

  /**
   * 2.7.2道闸控制
   */
  async gateControl(request: {
    parkId: any;
    nodeId: any;
    type: any;
  }) {
    return await this.post("api/control/GateControl", request, {
      apiDesc: "2.7.2道闸控制",
    });
  }

  /**
   * 2.7.3显示屏推送
   */
  async pushScreenMsg(request: {
    parkId: any;
    deviceType: any;
    deviceCode: any;
    showInfo: string;
  }) {
    return await this.post("api/control/PushScreenMsg", request, {
      apiDesc: "2.7.3显示屏推送",
    });
  }

  /**
   * 2.7.4车牌修改
   */
  async modifyCarNo(request: {
    parkId: any;
    oldplateNo: string;
    plateNo: string;
  }) {
    return await this.post<ApiResponse>("api/control/ModifyCarNo", request, {
      apiDesc: "2.7.4车牌修改",
    });
  }

  /**
   * 2.7.5远程开闸
   */
  async remoteOpen(request: RemoteOpenRequest) {
    return await this.post("api/control/RemoteOpen", request, {
      apiDesc: "2.7.5远程开闸",
    });
  }

  /**
   * 2.7.6修改场内车数据
   */
  async modifyCarInfo(request: ModifyCarInfoRequest) {
    return await this.post("api/control/ModifyCarInfo", request, {
      apiDesc: "2.7.6修改场内车数据",
    });
  }

  /**
   * 2.7.11显示屏推送扩展接口（LED全彩屏)
   */
  async pushLedScreenMsg(request: {
    parkId: any;
    deviceType: any;
    deviceCode: any;
    msgInfo: string;
  }) {
    return await this.post("api/control/PushLedScreenMsg", request, {
      apiDesc: "2.7.11显示屏推送扩展接口（LED全彩屏)",
    });
  }

  /**
   * 2.7.12显示屏推送扩展接口（LCD）
   */
  async pushLcdScreenMsg(request: {
    parkId: any;
    deviceType: any;
    deviceCode: any;
    scene: number;
    msgInfo: string;
  }) {
    return await this.post("api/control/PushLcdScreenMsg", request, {
      apiDesc: "2.7.12显示屏推送扩展接口（LCD）",
    });
  }

  /**
   * 2.7.13显示屏推送扩展接口（LED单红屏）
   */
  async pushSrsScreenMsg(request: {
    parkId: any;
    deviceType: any;
    deviceCode: any;
    msgMode?: number;
    msgInfo: string;
  }) {
    return await this.post("api/control/PushSrsScreenMsg", request, {
      apiDesc: "2.7.13显示屏推送扩展接口（LED单红屏）",
    });
  }

  /**
   * 2.7.14显示屏推送扩展接口（LED单红屏-剩余车位）
   */
  async pushSrsScreenLotMsg(request: {
    parkId: any;
    deviceType: any;
    deviceCode: any;
    freeLots: string;
  }) {
    return await this.post("api/control/PushSrsScreenLotMsg", request, {
      apiDesc: "2.7.14显示屏推送扩展接口（LED单红屏-剩余车位）",
    });
  }

  /**
   * 2.7.15新增虚拟进出场
   */
  async addVirtualTraffic(
    request: AddVirtualTrafficRequest
  ) {
    return await this.post("api/traffic/AddVirtualTraffic", request, {
      apiDesc: "2.7.15新增虚拟进出场",
    });
  }

  /**
   * 2.7.16进出场重新抓拍接口
   */
  async recapture(request: RecaptureRequest) {
    return await this.post("api/traffic/Recapture", request, {
      apiDesc: "2.7.16进出场重新抓拍接口",
    });
  }

  /**
   * 2.8.1新增黑名单车牌信息
   */
  async addCarBlackInfo(request: AddCarBlackInfoRequest) {
    return await this.post("api/blacklist/AddCarBlackInfo", request, {
      apiDesc: "2.8.1新增黑名单车牌信息",
    });
  }

  /**
   * 2.8.2修改黑名单车牌信息AddCarBlackInfoRequest
   */
  async modifyCarBlackInfo(
    request: AddCarBlackInfoRequest
  ) {
    return await this.post("api/blacklist/ModifyCarBlackInfo", request, {
      apiDesc: "2.8.2修改黑名单车牌信息",
    });
  }

  /**
   * 2.8.3删除黑名单车牌信息
   */
  async delCarBlackInfo(request: DelCarBlackInfoRequest) {
    return await this.post("api/blacklist/DelCarBlackInfo", request, {
      apiDesc: "2.8.3删除黑名单车牌信息",
    });
  }

  /**
   * 2.8.4查询黑名单列表
   */
  async queryCarBlackInfo(
    request: QueryCarBlackInfoRequest
  ) {
    let res = await this.post<string>(
      "api/blacklist/QueryCarBlackInfo",
      request,
      { apiDesc: "2.8.4查询黑名单列表" }
    );
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.9.1锁车接口
   */
  async lockCarplate(request: LockCarplateRequest) {
    return await this.post("api/card/LockCarplate", request, {
      apiDesc: "2.9.1锁车接口",
    });
  }

  /**
   * 2.9.2解锁接口
   */
  async unlockCarplate(request: UnlockCarplateRequest) {
    return await this.post("api/card/UnlockCarplate", request, {
      apiDesc: "2.9.2解锁接口",
    });
  }

  /**
   * 统一找车接口
   */
  async getFloorList(request: any) {
    return await this.post<string>("findCar/GetFloorList", request, {
      apiDesc: "2.10.1楼层列表查询接口",
    });
  }

  /**
   * 统一找车接口
   */
  async getAreaList(request: any) {
    return await this.post<string>("findCar/GetAreaList", request, {
      apiDesc: "2.10.2区域列表查询接口",
    });
  }

  /**
   * 统一找车接口
   */
  async getCarLocInfo(request: any) {
    return await this.post<string>("findCar/GetCarLocInfo", request, {
      apiDesc: "2.10.3车辆停放位置查询接口(精准)",
    });
  }

  /**
   * 统一找车接口
   */
  async getSpaceInfo(request: any) {
    return await this.post<string>("findCar/GetSpaceInfo", request, {
      apiDesc: "2.10.5楼层车位状态查询接口",
    });
  }

  /**
   * 统一找车接口
   */
  async getCarRoute(request: any) {
    return await this.post<string>("findCar/GetCarRoute", request, {
      apiDesc: "2.10.6车辆线路URL接口(图片)",
    });
  }

  /**
   * 统一找车接口
   */
  async getFindCarFreeSpaceNum(request: any) {
    return await this.post<string>("findCar/GetFreeSpaceNum", request, {
      apiDesc: "2.10.7空余车位数查询接口（找车）",
    });
  }

  /**
   * 统一找车接口
   */
  async GetCarImageUrl(request: any) {
    return await this.post<string>("findCar/GetCarImageUrl", request, {
      apiDesc: "2.10.8车位图片URL接口",
    });
  }

  /**
   * 统一找车接口
   */
  async getNodeDeviceStatus(request: any) {
    return await this.post<string>("findCar/getNodeDeviceStatus", request, {
      apiDesc: "2.10.11 节点设备状态查询接口",
    });
  }

  /**
   * 统一找车接口
   */
  async getSingleNodeDeviceStatus(request: any) {
    return await this.post<string>(
      "findCar/getSingleNodeDeviceStatus",
      request,
      { apiDesc: "2.10.12 单个节点设备状态查询接口" }
    );
  }

  /**
   * 统一找车接口
   */
  async updateLightScheme(request: any) {
    return await this.post<string>("findCar/updateLightScheme", request, {
      apiDesc: "2.10.13 根据车位编号修改车位灯方案",
    });
  }

  /**
   * 统一找车接口
   */
  async updateParkType(request: any) {
    return await this.post<string>("findCar/updateParkType", request, {
      apiDesc: "2.10.14 根据车位编号修改车位类型",
    });
  }

  /**
   * 统一找车接口
   */
  async updateParkStatusBatch(request: any) {
    return await this.post<string>("findCar/updateParkStatusBatch", request, {
      apiDesc: "2.10.15 根据车位地址批量修改车位状态（未开发）",
    });
  }

  /**
   * 统一找车接口
   */
  async getParkListByPlateNo(request: any) {
    return await this.post<string>("findCar/getParkListByPlateNo", request, {
      apiDesc: "2.10.16 根据车牌查车位（模糊）",
    });
  }

  /**
   * 统一找车接口
   */
  async parkCameraSnapPicture(request: any) {
    return await this.post<string>("findCar/parkCameraSnapPicture", request, {
      apiDesc: "2.10.17 车位相机抓拍接口",
    });
  }

  /**
   * 统一找车接口
   */
  async listInOutCarInfo(request: any) {
    return await this.post<string>("findCar/listInOutCarInfo", request, {
      apiDesc: "2.10.18 历史进出车明细查询",
    });
  }

  /**
   * 统一找车接口
   */
  async getPlateRecognitionRecord(request: any) {
    return await this.post<string>(
      "findCar/getPlateRecognitionRecord",
      request,
      { apiDesc: "2.10.22 车牌识别记录查询" }
    );
  }

  /**
   * 2.10.9车位图片URL接口
   */
  async getCarImageUrl(request: any) {
    return await this.post<string>("findCar/GetCarImageUrl", request, {
      apiDesc: "2.10.9车位图片URL接口",
    });
  }

  /**
   * 科拓统一对外接口协议（速停车相关接口仅针对国内）
   * 2.12.1预下单接口
   */
  async prepay(request: any) {
    return await this.post("ttp/order/Prepay", request, {
      apiDesc: "2.12.1预下单接口",
    });
  }

  /**
   * 科拓统一对外接口协议（速停车相关接口仅针对国内）
   * 2.12.2根据ttpOrderNo订单号查询订单状态
   */
  async queryPrepayOrder(request: any) {
    return await this.post("ttp/order/QueryPrepayOrder", request, {
      apiDesc: "2.12.2根据ttpOrderNo订单号查询订单状态",
    });
  }

  /**
   * 科拓统一对外接口协议（速停车相关接口仅针对国内）
   * 2.12.3充值预下单接口
   */
  async rechargePrepay(request: any) {
    return await this.post("stcttp/recharge/prepay", request, {
      apiDesc: "2.12.3充值预下单接口",
    });
  }

  /**
   * 科拓统一对外接口协议（速停车相关接口仅针对国内）
   * 2.12.4查询充值订单状态
   */
  async queryRechargePrepayOrder(request: any) {
    return await this.post("stcttp/recharge/query", request, {
      apiDesc: "2.12.4查询充值订单状态",
    });
  }

  /**
   * 科拓统一对外接口协议（速停车相关接口仅针对国内）
   * 2.12.5第三方应用获取临时访问令牌
   */
  async getTicket(request: any) {
    return await this.post("ttp-ticket/service/getTicket", request, {
      apiDesc: "2.12.5第三方应用获取临时访问令牌",
    });
  }

  /**
   * 科拓统一对外接口协议（速停车相关接口仅针对国内）
   * 2.12.6第三方发放优惠券
   */
  async grantCoupon(request: any) {
    return await this.post(
      "cn.keytop.stc.cp.external.coupon.GrantCoupon/1.0",
      request,
      { apiDesc: "2.12.6第三方发放优惠券" }
    );
  }

  /**
   * 科拓统一对外接口协议（速停车相关接口仅针对国内）
   * 2.12.7第三方查询优惠券
   */
  async queryCoupon(request: any) {
    return await this.post(
      "cn.keytop.stc.cp.external.coupon.QueryCoupon/1.0",
      request,
      { apiDesc: "2.12.7第三方查询优惠券" }
    );
  }

  /**
   * 科拓统一对外接口协议（速停车相关接口仅针对国内）
   * 2.12.8临停订单退款接口
   */
  async orderRefund(request: any) {
    return await this.post("stcttp/order/refund", request, {
      apiDesc: "2.12.8临停订单退款接口",
    });
  }

  /**
   * 科拓统一对外接口协议（速停车相关接口仅针对国内）
   * 2.12.9临停订单退款查询接口
   */
  async orderRefundQuery(request: any) {
    return await this.post("stcttp/order/refund/query", request, {
      apiDesc: "2.12.9临停订单退款查询接口",
    });
  }

  async getCardInfoByUser(request: { parkId: any; plateNo: string }) {
    return await this.post("api/carCard/GetCardInfoByUser", request, {
      apiDesc: "2.13.1根据车牌获取内部车信息",
    });
  }

  async getRechargeRuleByUser(request: {
    parkId: any;
    cardId: number;
    cardType: number;
  }) {
    return await this.post("api/carCard/GetRechargeRuleByUser", request, {
      apiDesc: "2.13.2根据车位获取充值规则",
    });
  }

  async getRechargePreDataByUser(request: {
    parkId: any;
    plateNo?: string;
    cardId: number;
    cardType: number;
    rechargeNumber: number;
    rechargeUnit: number;
    ruleId: number;
    deviceTypeId?: number;
    deviceIp?: string;
  }) {
    return await this.post("api/carCard/GetRechargePreDataByUser", request, {
      apiDesc: "2.13.3预充值接口",
    });
  }

  async rechargeByUser(request: any) {
    return await this.post("api/carCard/RechargeByUser", request, {
      apiDesc: "2.13.4内部车充值",
    });
  }

  async getCardInfoFromCardNoByUser(request: { parkId: any; cardNo: string }) {
    return await this.post("api/carCard/GetCardInfoFromCardNoByUser", request, {
      apiDesc: "2.13.5根据卡号获取内部车信息",
    });
  }

  async addByUser(request: any) {
    return await this.post("api/carCard/AddByUser", request, {
      apiDesc: "2.13.6内部车申请",
    });
  }

  async getCardConfigList(request: { parkId: any }) {
    return await this.post("api/carCard/GetCardConfigList", request, {
      apiDesc: "2.13.7获取内部车配置信息",
    });
  }

  async getPreOrderCache(request: { parkId: any; orderNo: string }) {
    return await this.post("api/carCard/GetPreOrderCache", request, {
      apiDesc: "2.13.8获取内部车预充值缓存信息",
    });
  }

  /**
   * 2.14.9获取当前用户信息
   */
  async queryCurrentUser(
    token: string,
    request?: QueryCurrentUserRequest
  ): Promise<QueryCurrentUserResponse> {
    let config = {
      headers: {
        "kt-token": token,
        Cookie: "mer=" + token,
        "content-type": "application/json;charset=UTF-8",
        "access-control-allow-credentials": true,
        "access-control-allow-headers":
          "Origin,Content-Type,Accept,token,X-Requested-With,cookie,lotId",
      },
      apiDesc: "2.14.9获取当前用户信息",
    };

    let res = await this.post<string>(
      "mercoupon/unity/queryCurrentUser",
      request,
      config
    );
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.14.12 根据抵扣劵号查询抵扣明细
   */
  async queryRecordById(
    request: QueryRecordByIdRequest
  ): Promise<QueryRecordByIdResponse> {
    let res = await this.post<QueryRecordByIdResponse>(
      "kosCouponConsole/service/open/queryRecordById",
      request,
      { apiDesc: "2.14.12 根据抵扣劵号查询抵扣明细" }
    );
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data;
  }

  //SAAS接口
  async queryAllLotCoupon4Unity(request: any) {
    let res = await this.post<string>(
      "mercoupon/unity/queryAllLotCoupon4Unity",
      request,
      { apiDesc: "2.14.13查看车场所有抵扣券模板" }
    );
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
   * 2.15.10获取用户信息
   */
  async getMyBaseInfo(
    request: GetMyBaseInfoRequest,
    token: string
  ): Promise<GetMyBaseInfoReponse> {
    let config = {
      headers: { "kt-token": token },
      apiDesc: "2.15.10获取用户信息",
    };
    let res = await this.post<GetMyBaseInfoReponse>(
      "unity/service/open/user/getMyBaseInfo",
      request,
      config
    );
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data;
  }

  /**
   * 2.15.4停车场与角色关系查询
   */
  async findLotRoles(
    request: FindLotRolesRequest
  ): Promise<FindLotRolesResponse> {
    let res = await this.post<FindLotRolesResponse>(
      "unity/service/open/role/findLotRoles",
      request,
      { apiDesc: "2.15.4停车场与角色关系查询" }
    );
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data;
  }

  /**
   * 2.15.8停车场与用户关系查询
   */
  async findListByLotIdPage(
    request: FindListByLotIdPageRequest
  ): Promise<FindListByLotIdPageResponse> {
    let res = await this.post<FindListByLotIdPageResponse>(
      "unity/service/open/user/findListByLotIdPage",
      request,
      { apiDesc: "2.15.8停车场与用户关系查询" }
    );
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data;
  }

  /**
   * 2.15.12 外部系统日志保存
   */
  async saveLog(request: SaveLogRequest) {
    return await this.post("unity/log/saveLog", request, {
      apiDesc: "2.15.12 外部系统日志保存",
    });
  }

  /**
   * 第三方充值抵扣券
   */
  async recharge3rdByUnity(
    request: Recharge3rdByUnityRequest
  ) {
    return await this.post("mercoupon/unity/recharge3rdByUnity", request, {
      apiDesc: "第三方充值抵扣券",
    });
  }

  /**
   * 查看车场商户信息
   */
  async queryLotMer4Unity(request: QueryLotMer4UnityRequest): Promise<[]> {
    let res = await this.post<string>(
      "mercoupon/unity/queryLotMer4Unity",
      request,
      { apiDesc: "查看车场商户信息" }
    );
    if (!ApiResponse.isSuccess(res))
      return Promise.reject(res.resMsg || res.resCode);

    return res.data ? JSON.parse(res.data) : null;
  }

  /**
     * 2.5.4 内部车修改有效期
     */
  async modifyValidTime(request: ModifyValidTimeRequest) {
    return await this.post('nkcInnerApi/card/ModifyValidTime', request, { apiDesc: '2.5.4 内部车修改有效期' });
  }

  /**
  * 2.11.1 预约车退款状态回调
  */
  async parkingBookingRefundCallback(request: ReqBookingRefund) {
    return await this.post('nkcInnerApi/booking/parkingBookingRefundCallback', request, { apiDesc: '2.11.1 预约车退款状态回调' });
  }

  /**
   * 2.13.2 重新统计汇总报表
   */
  async reStatistics(request: ReStatisticsRequest) {
    return await this.post('nkcInnerApi/report/reStatistics', request, { apiDesc: '2.13.2 重新统计汇总报表' });
  }

  /**
   * SAAS统一接口协议-2.16.1系统公告推送
   */
  async addSysNotice(request: {
    parkId: any;
    serviceCode: 'addSysNotice';
    allRole: string;
    classId: string;
    content: string;
    enabledTimeStart: string;
    enabledTimeEnd: string;
    lotIds: any;
    lotVersion: string;
    sendStatus: any;
    spLot: string;
    title: string;
  }) {
    let config: any = { apiDesc: '2.16.1系统公告推送', headers: { KT_LOT_ID: request.parkId } };
    return await this.post<string>('saas/saas-inner-api/notice/addSysNotice', request, config);
  }

  /**
   * SAAS统一接口协议-停车场云助手app模板消息发送
   */
  async messageSend(request: {
    parkId: any;
    serviceCode: 'saasMessageSend';
    templateId: string;
    parmMap: any;
    appLinkUrl?: string;
    pcLinkUrl?: string;
  }) {
    let config: any = { apiDesc: '停车场云助手app模板消息发送', headers: { KT_LOT_ID: request.parkId } };
    return await this.post<string>('saasConsole/kos_platform_api/service/open/message/send', request, config);
  }

  /**
   * MQ透传接口
   */
  async msgToLocal(request: any, config: AxiosRequestConfig) {
    return await this.post<string>('non_standard/MsgToLocal', request, config);
  }

  /**
   * 3.1
   * 通道接口
   * 这是一个大类接口，子接口见ChannelApi
   */
  async channelSend(request: ChannelSendReuqst) {
    return await this.post('nkcInnerApi/normal/ChannelSend', request, { apiDesc: '3.1 通道接口' });
  }
}
