import { getCsrfToken } from '@shared/api/csrf'
import { refreshAccessToken } from '@shared/api/tokenStore'

const PAYMENT_API_URL = 'https://app.payment.elcsa.ru'

async function doPaymentRequest<T>(
  path: string,
  options: RequestInit,
  allowRetry: boolean,
): Promise<T> {
  const csrf = await getCsrfToken()

  const res = await fetch(`${PAYMENT_API_URL}${path}`, {
    ...options,
    credentials: 'include',
    headers: {
      'X-CSRF-Token': csrf,
      ...options.headers,
    },
  })

  if (res.status === 401 && allowRetry) {
    try {
      await refreshAccessToken()
      return doPaymentRequest<T>(path, options, false)
    } catch {
      throw new Error('Unauthorized')
    }
  }

  const data = await res.json()
  if (!res.ok) throw data
  return data as T
}

export interface PaymentConfig {
  status_code: number
  usdt_exchange_rate: string
  gas_fee: string
  service_fee_rate: string
  one_usdt_service_fee: string
  one_usdt_total_price: string
  created_at: string
}

export interface PaymentQuote {
  status_code: number
  usdt_amount: string
  usdt_exchange_rate: string
  gas_fee: string
  service_fee: string
  total_price: string
  service_fee_rate: string
  created_at: string
}

export function getPaymentConfig(): Promise<PaymentConfig> {
  return doPaymentRequest('/payment/config', {}, true)
}

export function getPaymentQuote(usdtAmount: number): Promise<PaymentQuote> {
  return doPaymentRequest(`/payment/quote?usdt_amount=${usdtAmount}`, {}, true)
}

export function getPaymentQuoteByRub(rubAmount: number): Promise<PaymentQuote> {
  return doPaymentRequest(`/payment/quote/rub?total_rub=${rubAmount}`, {}, true)
}

export interface CreateOrderPayload {
  usdt_amount: number
  usdt_exchange_rate: number
  gas_fee: number
  total_price: number
}

export interface OrderResult {
  status_code: number
  order: {
    id: string
    created_at: string
    updated_at: string
    user_id: string
    usdt_amount: string
    usdt_exchange_rate: string
    gas_fee: string
    total_price: string
    service_fee: string
    status: string
    client_payment_id: string
    itpay_payment_qr_url_desktop: string
    itpay_payment_qr_url_android: string
    itpay_payment_qr_url_ios: string
    itpay_payment_qr_image_desktop: string
    itpay_payment_qr_image_android: string
    itpay_payment_qr_image_ios: string
    itpay_id: string
    itpay_qr_id: string
    itpay_amount: string
    itpay_created_at: string
  }
}

export function createOrder(payload: CreateOrderPayload): Promise<OrderResult> {
  return doPaymentRequest('/order/create', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload),
  }, true)
}

export type OrderStatus = 'pending' | 'rejected' | 'completed' | 'cancelled' | 'error'

export type PaymentStatus =
  | 'pending'
  | 'money_accepted'
  | 'web3_processing'
  | 'web3_hash_error'
  | 'web3_balance_problem'
  | 'receipt_error'
  | 'completed'
  | 'usdt_delivered'

export interface Order {
  id: string
  created_at: string
  updated_at: string
  user_id: string
  usdt_amount: string
  usdt_exchange_rate: string
  gas_fee: string
  total_price: string
  service_fee: string
  status: OrderStatus
  client_payment_id: string
  itpay_payment_qr_url_desktop: string
  itpay_payment_qr_url_android: string
  itpay_payment_qr_url_ios: string
  itpay_payment_qr_image_desktop: string
  itpay_payment_qr_image_android: string
  itpay_payment_qr_image_ios: string
  itpay_id: string
  itpay_qr_id: string
  itpay_amount: string
  itpay_created_at: string
}

export interface Payment {
  id: string
  created_at: string
  updated_at: string
  user_id: string
  order_id: string
  status: PaymentStatus
  receipt_cloudekassir_id: string
  receipt_cloudekassir_link: string
  itpay_payment_id: string
  itpay_paid_amount: string
  transaction_id: string
  web3_transaction_hash: string
  paid_at: string
  expired_date: string
}

export interface OrderWithPayment {
  order: Order
  payment: Payment | null
}

export interface OrdersResponse {
  orders: OrderWithPayment[]
}

export const ORDERS_LIMIT = 20

export function getOrders(offset: number, limit: number = ORDERS_LIMIT): Promise<OrdersResponse> {
  return doPaymentRequest(`/payment/orders?offset=${offset}&limit=${limit}`, {}, true)
}
