/**
 * 支付模块 API 封装
 * 支持：微信 JSAPI / 支付宝 / Native / 余额
 */
import request from '@/utils/request'
import type { ApiResult } from '@/api'
import { SERVER_API_URL } from '@/config/setting'

/** 支付方式 */
export type PayType = 'wechat' | 'alipay' | 'native' | 'balance' | number

/** 支付渠道 */
export type PayChannel = 'wechat_jsapi' | 'alipay_wap' | 'wechat_native' | 'balance'

/** 支付参数 */
export interface PayParams {
  orderNo: string
  orderId?: number
  payType: PayChannel
  /** 微信 JSAPI 必填：用户 openid */
  openId?: string
  /** 微信 JSAPI 必填：支付主体类型 */
  subject?: string
  /** 支付主体描述 */
  body?: string
  /** 支付金额（分） */
  totalAmount?: number
  /** 前端回调 URL */
  returnUrl?: string
}

/** 微信 JSAPI 支付参数 */
export interface WechatJsapiParams {
  orderNo: string
  openId: string
  subject: string
  body?: string
  totalAmount?: number
  returnUrl?: string
}

/** 支付宝 WAP/Web 支付参数 */
export interface AlipayParams {
  orderNo: string
  subject: string
  body?: string
  totalAmount?: number
  returnUrl?: string
}

/** Native 支付参数 */
export interface NativeParams {
  orderNo: string
  subject: string
  body?: string
  totalAmount?: number
}

/** 支付结果 */
export interface PayResult {
  codeUrl?: string      // Native 支付二维码链接
  qrcode?: string        // 二维码内容
  paymentUrl?: string    // 跳转支付链接
  payUrl?: string        // 支付链接
  prepayId?: string      // 预支付订单号
  mwebUrl?: string       // 微信 H5 支付链接
  tradeNo?: string       // 交易流水号
  orderNo?: string       // 订单号
  orderId?: number       // 订单ID
}

/** 支付状态 */
export interface PayStatus {
  paid: boolean
  payStatus: number       // 0 未支付，1 已支付
  orderStatus: number     // 订单状态
  payTime?: string        // 支付时间
  transactionId?: string  // 微信/支付宝交易号
}

/**
 * 统一支付接口
 * @deprecated 使用具体渠道接口
 */
export async function createPayment(data: Record<string, unknown>): Promise<PayResult> {
  const res = await request.post<ApiResult<PayResult>>(
    SERVER_API_URL + '/system/payment/create',
    data
  )
  if (res.data.code === 0) {
    return res.data.data!
  }
  return Promise.reject(new Error(res.data.message))
}

/**
 * 微信 JSAPI 支付
 * 适用于微信内置浏览器 / 公众号 / 小程序环境
 */
export async function createWechatJsapiPay(params: WechatJsapiParams): Promise<PayResult> {
  const res = await request.post<ApiResult<PayResult>>(
    SERVER_API_URL + '/system/wx-jsapi-pay/unified-order',
    params
  )
  if (res.data.code === 0) {
    return res.data.data!
  }
  return Promise.reject(new Error(res.data.message))
}

/**
 * 微信 H5 支付
 * 适用于非微信浏览器
 */
export async function createWechatH5Pay(params: { orderNo: string; subject: string; body?: string; totalAmount?: number; returnUrl?: string }): Promise<PayResult> {
  const res = await request.post<ApiResult<PayResult>>(
    SERVER_API_URL + '/system/wx-h5-pay/unified-order',
    params
  )
  if (res.data.code === 0) {
    return res.data.data!
  }
  return Promise.reject(new Error(res.data.message))
}

/**
 * 微信 Native 支付（扫码支付）
 */
export async function createWechatNativePay(params: NativeParams): Promise<PayResult> {
  const res = await request.post<ApiResult<PayResult>>(
    SERVER_API_URL + '/system/wx-native-pay/unified-order',
    params
  )
  if (res.data.code === 0) {
    return res.data.data!
  }
  return Promise.reject(new Error(res.data.message))
}

/**
 * 支付宝 WAP/Web 支付
 */
export async function createAlipayPay(params: AlipayParams): Promise<PayResult> {
  const res = await request.post<ApiResult<PayResult>>(
    SERVER_API_URL + '/system/alipay/unified-order',
    params
  )
  if (res.data.code === 0) {
    return res.data.data!
  }
  return Promise.reject(new Error(res.data.message))
}

/**
 * 查询支付状态
 */
export async function queryPayStatus(orderNo: string): Promise<PayStatus> {
  const res = await request.get<ApiResult<PayStatus>>(
    SERVER_API_URL + '/system/payment/query-status',
    { params: { orderNo } }
  )
  if (res.data.code === 0) {
    return res.data.data!
  }
  return Promise.reject(new Error(res.data.message))
}

/**
 * 取消订单
 */
export async function cancelOrder(orderId: number): Promise<void> {
  const res = await request.post<ApiResult<void>>(
    SERVER_API_URL + '/system/order/cancel',
    { orderId }
  )
  if (res.data.code !== 0) {
    return Promise.reject(new Error(res.data.message))
  }
}

/**
 * 申请退款
 */
export async function applyRefund(orderId: number, reason?: string): Promise<void> {
  const res = await request.post<ApiResult<void>>(
    SERVER_API_URL + '/system/order/refund',
    { orderId, reason }
  )
  if (res.data.code !== 0) {
    return Promise.reject(new Error(res.data.message))
  }
}

/**
 * 判断当前环境
 */
export function detectPayEnvironment(): 'wechat' | 'alipay' | 'desktop' | 'mobile' {
  const ua = navigator.userAgent.toLowerCase()

  // 微信环境
  if (/micromessenger/.test(ua)) {
    return 'wechat'
  }

  // 支付宝环境
  if (/alipayclient/.test(ua)) {
    return 'alipay'
  }

  // 移动端
  if (/mobile|android|iphone|ipad|tablet/i.test(ua)) {
    return 'mobile'
  }

  // 桌面端
  return 'desktop'
}

/**
 * 检测是否在微信内置浏览器
 */
export function isWechatBrowser(): boolean {
  return /micromessenger/.test(navigator.userAgent.toLowerCase())
}

/**
 * 检测是否在支付宝内置浏览器
 */
export function isAlipayBrowser(): boolean {
  return /alipayclient/.test(navigator.userAgent.toLowerCase())
}

/**
 * 调起微信 JSAPI 支付
 * 需要先引入微信 JSSDK 并完成签名
 */
export function callWechatJsapi(params: {
  appId: string
  timestamp: string
  nonceStr: string
  package: string
  signType?: string
  paySign: string
}): Promise<'ok'> {
  return new Promise((resolve, reject) => {
    if (typeof window.WeixinJSBridge === 'undefined') {
      // 尝试通过 WeChat JSSDK 调用
      if (typeof window.jWeixin !== 'undefined') {
        window.jWeixin.chooseWXPay({
          ...params,
          success: () => resolve('ok'),
          fail: (err: unknown) => reject(err)
        })
      } else {
        reject(new Error('微信 JSSDK 未加载'))
      }
      return
    }

    window.WeixinJSBridge.invoke(
      'getBrandWCPayRequest',
      {
        appId: params.appId,
        timeStamp: params.timestamp,
        nonceStr: params.nonceStr,
        package: params.package,
        signType: params.signType || 'MD5',
        paySign: params.paySign
      },
      (res: { err_msg: string }) => {
        if (res.err_msg === 'get_brand_wcpay_request:ok') {
          resolve('ok')
        } else if (res.err_msg === 'get_brand_wcpay_request:cancel') {
          reject(new Error('用户取消支付'))
        } else {
          reject(new Error(res.err_msg))
        }
      }
    )
  })
}

// 扩展 Window 类型
declare global {
  interface Window {
    WeixinJSBridge?: {
      invoke: (api: string, params: Record<string, unknown>, callback: (res: { err_msg: string }) => void) => void
    }
    jWeixin?: {
      chooseWXPay: (params: Record<string, unknown> & { success?: () => void; fail?: (err: unknown) => void }) => void
    }
  }
}
