/**
 * @file 请求助手
 * @description 提供链式调用的请求处理助手
 * @author JunBin.Yang
 */

import { Unknown } from "@core/common";
import { NetworkResult } from './NetworkResult';
import { ResponseParser } from './ResponseParser';
import { DefaultResponseParser } from './DefaultResponseParser';
import { NetworkConfig } from './NetworkConfig';
import { ToastUtils } from "@core/util";
import { getContainer, CoreServiceKeys } from "@core/di";

/**
 * 请求助手类
 * 提供链式调用的请求处理能力
 * @template T 响应数据类型
 */
export class RequestHelper<T> {
  /**
   * 原始请求 Promise(可能是原始响应或 NetworkResult)
   */
  private source: Promise<Unknown>;

  /**
   * 响应解析器
   */
  private parser: ResponseParser<T>;

  /**
   * 是否已经是 NetworkResult
   */
  private isNetworkResult: boolean = false;

  /**
   * 是否显示 loading
   */
  private useLoading: boolean = false;

  /**
   * 是否自动 toast 错误
   */
  private useToast: boolean = true;

  /**
   * 请求开始前的回调
   */
  private beforeStart?: () => void;

  /**
   * loading 显示回调
   */
  private showLoadingCallback?: () => void = () => {
    ToastUtils.showLoading();
  };

  /**
   * loading 隐藏回调
   */
  private hideLoadingCallback?: () => void = () => {
    ToastUtils.hide();
  };

  /**
   * toast 错误回调
   */
  private toastErrorCallback?: (message: string) => void = (message: string) => {
    ToastUtils.showError(message);
  };

  /**
   * 构造函数
   * @param promise 原始请求 Promise
   * @param parser 响应解析器
   * @param isNetworkResult 是否已经是 NetworkResult
   */
  private constructor(promise: Promise<Unknown>, parser?: ResponseParser<T>, isNetworkResult: boolean = false) {
    this.source = promise;
    this.parser = parser ?? this.createDefaultParser();
    this.isNetworkResult = isNetworkResult;
  }

  /**
   * 创建默认解析器
   * 优先从 DI 容器获取 NetworkConfig,如果失败则使用默认配置
   * @returns 响应解析器
   */
  private createDefaultParser(): ResponseParser<T> {
    try {
      const config = getContainer().tryResolve<NetworkConfig>(CoreServiceKeys.ConfigManager);
      if (config) {
        return new DefaultResponseParser<T>(config.responseParser);
      }
    } catch (e) {
      // 如果获取配置失败,使用默认配置
    }
    return new DefaultResponseParser<T>();
  }

  /**
   * 创建请求助手(从原始响应)
   * @param promise 原始请求 Promise
   * @param parser 响应解析器
   * @returns RequestHelper 实例
   */
  static from<T>(promise: Promise<Unknown>, parser?: ResponseParser<T>): RequestHelper<T> {
    return new RequestHelper<T>(promise, parser, false);
  }

  /**
   * 创建请求助手(从 NetworkResult)
   * @param promise NetworkResult Promise
   * @returns RequestHelper 实例
   */
  static fromResult<T>(promise: Promise<NetworkResult<T>>): RequestHelper<T> {
    return new RequestHelper<T>(promise as Promise<Unknown>, undefined, true);
  }

  /**
   * 设置请求开始前执行的回调
   * @param handler 前置回调
   * @returns 当前实例
   */
  start(handler: () => void): RequestHelper<T> {
    this.beforeStart = handler;
    return this;
  }

  /**
   * 配置是否展示 loading
   * @param enable 是否展示
   * @returns 当前实例
   */
  loading(enable: boolean = true): RequestHelper<T> {
    this.useLoading = enable;
    return this;
  }

  /**
   * 配置是否自动 toast 错误
   * @param enable 是否展示
   * @returns 当前实例
   */
  toast(enable: boolean = true): RequestHelper<T> {
    this.useToast = enable;
    return this;
  }

  /**
   * 设置 loading 回调
   * @param show 显示回调
   * @param hide 隐藏回调
   * @returns 当前实例
   */
  onLoading(show: () => void, hide: () => void): RequestHelper<T> {
    this.showLoadingCallback = show;
    this.hideLoadingCallback = hide;
    return this;
  }

  /**
   * 设置 toast 错误回调
   * @param callback toast 回调
   * @returns 当前实例
   */
  onError(callback: (message: string) => void): RequestHelper<T> {
    this.toastErrorCallback = callback;
    return this;
  }

  /**
   * 执行请求,返回数据
   * @returns 数据 Promise
   */
  async execute(): Promise<T> {
    const result = await this.executeInternal();
    if (!result.isSuccess) {
      throw new Error(result.message ?? '请求失败');
    }
    return result.data as T;
  }

  /**
   * 执行请求,返回完整响应
   * @returns NetworkResult Promise
   */
  async response(): Promise<NetworkResult<T>> {
    return this.executeInternal();
  }

  /**
   * 内部执行逻辑
   * @returns NetworkResult Promise
   */
  private async executeInternal(): Promise<NetworkResult<T>> {
    // 执行前置回调
    if (this.beforeStart) {
      this.beforeStart();
    }

    // 显示 loading
    if (this.useLoading && this.showLoadingCallback) {
      this.showLoadingCallback();
    }

    try {
      const rawResponse: Unknown = await this.source;

      // 如果已经是 NetworkResult,直接使用
      let result: NetworkResult<T>;
      if (this.isNetworkResult) {
        result = rawResponse as NetworkResult<T>;
      } else {
        // 否则创建新的 NetworkResult
        result = new NetworkResult<T>(rawResponse, this.parser);
      }

      if (!result.isSuccess && this.useToast && this.toastErrorCallback) {
        this.toastErrorCallback(result.message ?? '请求失败');
      }

      return result;
    } catch (e) {
      const error = e instanceof Error ? e : new Error('网络异常');

      console.log("####",JSON.stringify(error))
      if (this.useToast && this.toastErrorCallback) {
        this.toastErrorCallback(error.message);
      }

      return NetworkResult.error<T>(error);
    } finally {
      // 隐藏 loading
      if (this.useLoading && this.hideLoadingCallback) {
        this.hideLoadingCallback();
      }
    }
  }
}