import { Inject, Provide } from '@midwayjs/decorator';
import { BaseService } from '@cool-midway/core';
import { SunPayService } from './sunpay';
import { ChannelService } from '../channel';
import { HambitBraService } from './hambitBra';
import { HambitInrService } from './hambitInr';
import { WithdrawChannelService } from '../withdrawChannel';
import { AchService } from './ach';

@Provide()
export class DispatchService extends BaseService {
  @Inject()
  sunPayService: SunPayService;

  @Inject()
  channelService: ChannelService;

  @Inject()
  WithdrawChannelService: WithdrawChannelService;

  @Inject()
  hambitBraService: HambitBraService;

  @Inject()
  hambitInrService: HambitInrService;

  @Inject()
  achService: AchService;

  async refund(refund) {
    try {
      const channel = await this.channelService.queryByCode(refund.code);
      if (!this[channel.service] || !this[channel.service].refund) {
        throw new Error('该渠道不支持退款');
      }
      return await this[channel.service].refund(refund);
    } catch (e) {
      throw new Error('请求通道接口失败，失败原因：' + e.message);
    }
  }

  async queryRefund(refund) {
    try {
      const channel = await this.channelService.queryByCode(refund.code);
      if (!this[channel.service] || !this[channel.service].queryRefund) {
        throw new Error('该渠道不支持退款');
      }
      return await this[channel.service].queryRefund(refund);
    } catch (e) {
      throw new Error('请求通道接口失败，失败原因：' + e.message);
    }
  }

  validOrderParam(channel, extra) {
    const validParam = this[channel.service]?.validOrderParam;
    if (validParam) {
      validParam(extra);
    }
  }

  async order(order, channel, extra) {
    try {
      return await this[channel.service].order(order, extra);
    } catch (e) {
      throw new Error('请求通道接口失败，失败原因：' + e.message);
    }
  }

  async query(order) {
    try {
      const channel = await this.channelService.queryByCode(order.code);
      return await this[channel.service].query(order);
    } catch (e) {
      throw new Error('请求通道接口失败，失败原因：' + e.message);
    }
  }

  async queryBalance(code) {
    if (!code) {
      return {
        status: 0,
        message: '通道编码不能为空',
      };
    }
    try {
      const channel = await this.WithdrawChannelService.queryByCode(code);
      if (!this[channel.service] || !this[channel.service].queryBalance) {
        return {
          status: 0,
          message: "代付渠道不支持"
        }
      }
      return await this[channel.service].queryBalance();
    } catch (e) {
      throw new Error('请求余额查询失败，失败原因：' + e.message);
    }
  }

  async withdraw(data) {
    try {
      const channel = await this.WithdrawChannelService.queryByCode(data.code);
      if (!this[channel.service] || !this[channel.service].withdraw) {
        throw new Error('代付渠道不支持');
      }
      return await this[channel.service].withdraw(data);
    } catch (e) {
      throw new Error('代付申请失败，失败原因：' + e.message);
    }
  }

  async queryWithdraw(data) {
    try {
      const channel = await this.WithdrawChannelService.queryByCode(data.code);
      if (!this[channel.service] || !this[channel.service].queryWithdraw) {
        return {
          status: 1,
          message: "代付渠道不支持"
        }
      }
      return await this[channel.service].queryWithdraw(data);
    } catch (e) {
      return {
        status: 1,
        message: e.message
      }
    }
  }

  async handleOrderNotify(code, data, headers) {
    try {
      const channel = await this.channelService.queryByCode(code);
      return await this[channel.service].handleOrderNotify(data, headers);
    } catch (e) {
      throw new Error('交易回调处理接口失败，失败原因：' + e.message);
    }
  }

  async handleWithdrawNotify(code, data, headers) {
    try {
      const channel = await this.WithdrawChannelService.queryByCode(code);
      return await this[channel.service].handleWithdrawNotify(data, headers);
    } catch (e) {
      throw new Error('代付回调处理接口失败，失败原因：' + e.message);
    }
  }


  async getBanks(channel, data) {
    try {
      if (!this[channel.service] || !this[channel.service].queryBanks) {
        return []
      }
      return await this[channel.service].queryBanks(data);
    } catch (e) {
      throw new Error('查询支持银行接口失败，失败原因：' + e.message);
    }
  }
}
