import client from "./client"
import type { ApiResponse } from "../types"
import type { UpstreamActionLog } from "./upstreamActions"

export interface CheckoutResponse {
  order_id: number
  out_order_no: string
  total_amount: number
  discount_amount: number
  coupon_discount_amount: number
  points_discount_amount: number
  paid_amount: number
  instance_count: number
  coupon?: CouponApplication | null
}

export interface CouponApplication {
  description: string | null
  type: string
  value: number
  discount_level: "order" | "product" | string
  target_cart_item_id: number | null
  target_product_id: number | null
  order_amount: number
  eligible_amount: number
  discount_amount: number
  item_discounts: Record<string, number>
  final_amount?: number
}

export interface CouponTargetOption {
  cart_item_id: number
  product_id: number
  product_name: string
  sku: string | null
  cycle: string
  quantity: number
  item_total: number
  discount_amount: number
  final_amount: number
}

export interface AvailableCoupon {
  id: number
  description: string | null
  type: string
  value: number
  threshold_amount: number
  max_discount_amount: number
  discount_level: "order" | "product" | string
  scope: string
  expires_at: string | null
}

export interface CouponPreviewResponse {
  total_amount: number
  coupon_discount_amount: number
  points_discount_amount: number
  discount_amount: number
  final_amount: number
  actual_use_points: number
  coupon: CouponApplication | null
  requires_target_selection?: boolean
  target_options?: CouponTargetOption[]
}

export interface OrderInstance {
  id: number
  status: string
  main_ip: string | null
  hostname: string | null
  expires_at: string | null
}

export interface ServiceOrderInstance extends OrderInstance {
  alias: string | null
  cycle: string
  unit_price: number
  created_at: string | null
  terminated_at: string | null
  cpu: number | null
  memory: number | null
  system_disk_size: number | null
  data_disk_size: number | null
  in_bw: number | null
  out_bw: number | null
  ip_num: number | null
  os_image: string | null
}

export interface ServiceOrderRefund {
  id: number
  refund_no: string
  refund_type: "full" | "prorated" | "no_refund" | string
  refund_amount: number
  status: string
  resource_status: "none" | "running" | "failed" | "finished" | "manual_handled" | "ignored" | string
  resource_error: string | null
  resource_completed_at: string | null
  reason: string | null
  created_at: string | null
}

export interface ServiceOrderRefundPolicy {
  action_allowed: boolean
  refund_type: "full" | "prorated" | "no_refund" | "unavailable" | string
  refund_amount: number
  paid_amount: number
  reason: string
  points_claimed: boolean
  full_refund_used: number
  full_refund_limit: number
  full_refund_days: number
  full_refund_unlimited?: boolean
  within_full_refund_window: boolean
  latest_refund?: ServiceOrderRefund | null
}

export interface ServiceOrderTimelineItem {
  key: string
  kind: "order" | "instance" | "points" | "refund" | "resource" | string
  type?: string
  title: string
  description?: string | null
  message?: string | null
  status?: string | null
  at?: string | null
  created_at?: string | null
  completed_at?: string | null
  ref_id?: number | null
}

export interface ServiceOrder {
  id: number
  out_order_no: string
  status: "pending" | "paid" | "cancelled" | "refunded" | string
  total_amount: number
  discount_amount: number
  paid_amount: number
  created_at: string | null
  remark: string | null
  items_snapshot: unknown[]
  order_type?: string
  dependency_rank?: number
  instance_ids?: number[]
  content: string[]
  instances: ServiceOrderInstance[]
  point_rewards: unknown[]
  upstream_actions: UpstreamActionLog[]
  timeline?: ServiceOrderTimelineItem[]
  points_claimed: boolean
  refund_policy: ServiceOrderRefundPolicy
  refund: ServiceOrderRefund | null
}

export interface UnsubscribeOrderResult {
  refund: ServiceOrderRefund
  refunds: ServiceOrderRefund[]
  total_refund: number
  instance_deleted: boolean
  order: ServiceOrder
}

export interface Order {
  id: number
  out_order_no: string
  status: "pending" | "paid" | "cancelled" | "refunded"
  total_amount: number
  discount_amount: number
  created_at: string
  items_snapshot?: unknown[]
  instances?: OrderInstance[]
}

export interface CheckoutOptions {
  coupon_code?: string | null
  coupon_id?: number | null
  coupon_target_cart_item_id?: number | null
  use_points?: number
}

export function checkout(cartItemIds: number[], options: CheckoutOptions = {}) {
  return client.post<ApiResponse<CheckoutResponse>>("/v1/orders/checkout", {
    cart_item_ids: cartItemIds,
    ...options,
  })
}

export function previewCoupon(cartItemIds: number[], options: CheckoutOptions = {}) {
  return client.post<ApiResponse<CouponPreviewResponse>>("/v1/orders/coupons/preview", {
    cart_item_ids: cartItemIds,
    ...options,
  })
}

export function claimActivityCoupon(promoCodeId: number, activityId?: number | null) {
  return client.post<ApiResponse<{ claim_id: number; promo_code_id: number }>>("/v1/orders/coupons/claim-activity", {
    promo_code_id: promoCodeId,
    activity_id: activityId ?? null,
  })
}

export async function getAvailableCoupons() {
  const res = await client.get<ApiResponse<{ items: AvailableCoupon[]; agent_disabled?: boolean }>>("/v1/orders/coupons/available")
  return {
    items: res.data.data?.items ?? [],
    agentDisabled: res.data.data?.agent_disabled ?? false,
  }
}

export function listOrders() {
  return client.get<ApiResponse<Order[]>>("/v1/orders")
}

export function getOrder(orderId: number) {
  return client.get<ApiResponse<Order>>(`/v1/orders/${orderId}`)
}

export async function listServiceOrders(limit = 100, offset = 0): Promise<ApiResponse<ServiceOrder[]>> {
  const { data } = await client.get<ApiResponse<ServiceOrder[]>>(
    `/v1/orders/service-orders?limit=${limit}&offset=${offset}`,
  )
  return data
}

export async function unsubscribeOrder(orderId: number): Promise<ApiResponse<UnsubscribeOrderResult>> {
  const { data } = await client.post<ApiResponse<UnsubscribeOrderResult>>(
    `/v1/orders/${orderId}/unsubscribe`,
  )
  return data
}
