import { apiClient } from '@/shared/api/client'
import type { ApiResponse } from '@/shared/types/types'

export interface PaymentConfig {
  id: number
  name: string
  provider: string
  merchant_id: string
  gateway_url: string
  sign_key?: string
  notify_key?: string
  notify_url: string
  jump_url: string
  pay_way: string
  jspay_flag: string
  sign_type: string
  extra_config: Record<string, any> | null
  is_default: boolean
  status: string
  environment: string
  business_tags: string[] | null
  reference_count: number
  total_transactions: number
  total_amount_cent: number
  last_used_at: string | null
  created_by: number | null
  updated_by: number | null
  created_at: string
  updated_at: string
}

export interface PaymentConfigListResponse {
  items: PaymentConfig[]
  total: number
  page: number
  page_size: number
}

export interface PaymentConfigImportResult {
  total: number
  created: number
  updated: number
}

export interface CreatePaymentConfigRequest {
  name: string
  provider: string
  merchant_id: string
  gateway_url?: string
  sign_key?: string
  notify_key?: string
  notify_url?: string
  jump_url?: string
  pay_way?: string
  jspay_flag?: string
  sign_type?: string
  extra_config?: Record<string, any>
  is_default?: boolean
  status?: string
  environment?: string
  business_tags?: string[]
}

export interface UpdatePaymentConfigRequest {
  name?: string
  merchant_id?: string
  gateway_url?: string
  sign_key?: string
  notify_key?: string
  notify_url?: string
  jump_url?: string
  pay_way?: string
  jspay_flag?: string
  sign_type?: string
  extra_config?: Record<string, any>
  is_default?: boolean
  status?: string
  environment?: string
  business_tags?: string[]
}

export async function fetchPaymentConfigs(params?: {
  provider?: string
  pay_way?: string
  status?: string
  environment?: string
  page?: number
  page_size?: number
}) {
  const { data } = await apiClient.get<ApiResponse<PaymentConfigListResponse>>(
    '/admin/payment-configs',
    {
      params,
    }
  )
  return data.data
}

export async function fetchPaymentConfig(id: number, includeSecret = false) {
  const { data } = await apiClient.get<ApiResponse<PaymentConfig>>(`/admin/payment-configs/${id}`, {
    params: { include_secret: includeSecret },
  })
  return data.data
}

export async function exportPaymentConfigBackup() {
  const response = await apiClient.get<Blob>('/admin/payment-configs/export', {
    responseType: 'blob',
  })
  return {
    blob: response.data,
    filename:
      readDownloadFilename(response.headers['content-disposition']) || fallbackBackupFilename(),
  }
}

export async function importPaymentConfigBackup(payload: unknown) {
  const { data } = await apiClient.post<ApiResponse<PaymentConfigImportResult>>(
    '/admin/payment-configs/import',
    payload
  )
  return data.data
}

export async function createPaymentConfig(payload: CreatePaymentConfigRequest) {
  const { data } = await apiClient.post<ApiResponse<PaymentConfig>>(
    '/admin/payment-configs',
    payload
  )
  return data.data
}

export async function updatePaymentConfig(id: number, payload: UpdatePaymentConfigRequest) {
  const { data } = await apiClient.put<ApiResponse<PaymentConfig>>(
    `/admin/payment-configs/${id}`,
    payload
  )
  return data.data
}

export async function deletePaymentConfig(id: number) {
  const { data } = await apiClient.delete<ApiResponse<{ message: string }>>(
    `/admin/payment-configs/${id}`
  )
  return data.data
}

function readDownloadFilename(contentDisposition: unknown) {
  if (typeof contentDisposition !== 'string') return ''
  const encoded = contentDisposition.match(/filename\*=UTF-8''([^;]+)/i)?.[1]
  if (encoded) return decodeURIComponent(encoded)
  return contentDisposition.match(/filename="?([^";]+)"?/i)?.[1] || ''
}

function fallbackBackupFilename() {
  const stamp = new Date()
    .toISOString()
    .replace(/[-:]/g, '')
    .replace(/\.\d{3}Z$/, '')
  return `payment-config-backup-${stamp}.json`
}
