
/**
 * 说明：
 * * 不同服务器的请求模块。
 */

import ApiCofig from "@/common/config/ApiCofig";
import { isDev } from "../common/config/AppCofig";
import { BaseAppServerRequestModule } from "./BaseAppServerRequestModule";
import type { DataModel, NewDataModel } from "@imengyu/js-request-transform";
import { appendGetUrlParams, appendPostParams, defaultResponseDataHandlerCatch, RandomUtils, RequestApiConfig, RequestApiError, RequestApiResult, RequestCoreInstance, RequestOptions, RequestResponse, type RequestApiInfoStruct } from "@imengyu/imengyu-utils";


/**
 * 主应用服务请求模块
 */
export class AppServerRequestModule<T extends DataModel> extends BaseAppServerRequestModule<T> {
  constructor() {
    super(isDev ? ApiCofig.server.Dev : ApiCofig.server.Prod);
  }
}

/**
 * 地图服务请求模块
 */
export class MengyuServerRequestModule<T extends DataModel> extends BaseAppServerRequestModule<T> {
  constructor() {
    super('https://update-server1.imengyu.top');
    //super('http://localhost:3012');
    this.config.requestInterceptor = (url, req) => {
      req.headers['token'] = getApp().globalData?.token ?? '';
      if (req.method == 'GET') {
        url = appendGetUrlParams(url, 'deviceUid', this.getDeviceUid());
      } else {
        req.data = appendPostParams(req.data, 'deviceUid', this.getDeviceUid());
      }
      return { newUrl: url, newReq: req };
    };
    this.config.responseDataHandler = async function responseDataHandler<T extends DataModel>(response: RequestResponse, req: RequestOptions, resultModelClass: NewDataModel | undefined, instance: RequestCoreInstance<T>, apiInfo: RequestApiInfoStruct): Promise<RequestApiResult<T>> {
      const method = req.method || 'GET';
      try {
        const json = await response.json();
        if (response.ok) {
          if (!json) {
            throw new RequestApiError(
              'businessError',
              '后端未返回数据',
              '',
              response.status,
              null,
              null,
              response.headers,
              apiInfo
            );
          }
          if (!json.success)
            throw new RequestApiError(
              'businessError',
              json.message,
              json.code.toString(),
              json.code,
              json,
              json,
              response.headers,
              apiInfo
            );
          
          return new RequestApiResult(
            resultModelClass ?? instance.config.modelClassCreator,
            json?.code || response.status,
            json.message,
            json.data,
            json,
            response.headers,
            apiInfo
          );
        }
        else {
          throw json;
        }

      } catch (err) {
        if (err instanceof RequestApiError) {
          throw response;
        }
        //错误统一处理
        return new Promise<RequestApiResult<T>>((resolve, reject) => {
          defaultResponseDataHandlerCatch(method, req, response, null, err as any, apiInfo, response.url, reject, instance);
        });
      }
    };
  }

  private static readonly DEVICE_UID_KEY = 'deviceUid';
  private uid = '';

  getDeviceUid() {
    if (!this.uid) {
      this.uid = uni.getStorageSync(MengyuServerRequestModule.DEVICE_UID_KEY);
      if (!this.uid) {
        this.uid = RandomUtils.genNonDuplicateID(20);
        uni.setStorageSync(MengyuServerRequestModule.DEVICE_UID_KEY, this.uid);
      }
    }
    return this.uid;
  }
}

/**
 * 腾讯地图服务请求模块
 */
export class TencentMengyuServerRequestModule<T extends DataModel> extends BaseAppServerRequestModule<T> {
  constructor() {
    super("https://apis.map.qq.com");
    this.config.requestInterceptor = (url, req) => {
      url = appendGetUrlParams(url, 'key', ApiCofig.mapKey);
      return { newUrl: url, newReq: req };
    };
    this.config.responseDataHandler = async function responseDataHandler<T extends DataModel>(response: RequestResponse, req: RequestOptions, resultModelClass: NewDataModel | undefined, instance: RequestCoreInstance<T>, apiInfo: RequestApiInfoStruct): Promise<RequestApiResult<T>> {
      const method = req.method || 'GET';
      try {
        const json = await response.json();
        if (response.ok) {
          if (!json) {
            throw new RequestApiError(
              'businessError',
              '后端未返回数据',
              '',
              response.status,
              null,
              null,
              response.headers,
              apiInfo
            );
          }
          if (json.status !== 0)
            throw new RequestApiError(
              'businessError',
              json.message,
              json.status.toString(),
              json.status,
              json,
              json,
              response.headers,
              apiInfo
            );
          
          return new RequestApiResult(
            resultModelClass ?? instance.config.modelClassCreator,
            json?.status || response.status,
            json.message,
            json.result,
            json,
            response.headers,
            apiInfo
          );
        }
        else {
          throw json;
        }

      } catch (err) {
        if (err instanceof RequestApiError) {
          throw response;
        }
        //错误统一处理
        return new Promise<RequestApiResult<T>>((resolve, reject) => {
          defaultResponseDataHandlerCatch(method, req, response, null, err as any, apiInfo, response.url, reject, instance);
        });
      }
    };
  }
}