import client from "./client"
import type { CaptchaResult } from "../utils/geetest"

function listResult<T>(value: unknown): { items: T[]; total: number } {
  const data = value as { items?: unknown; total?: unknown } | null | undefined
  return {
    items: Array.isArray(data?.items) ? data.items as T[] : [],
    total: Number(data?.total ?? 0) || 0,
  }
}

export interface PromotionOverview {
  invite_code: string
  invite_link: string
  register_link: string
  invite_code_edit_enabled: boolean
  invite_code_change_count: number
  invite_code_change_limit: number
  invite_code_change_remaining: number
  click_count: number
  registered_count: number
  reward_points: number
  settled_reward_points: number
  frozen_reward_points: number
  reversed_reward_points: number
  reward_rate: number
  available_points: number
  member_level: number | null
  member_level_name: string | null
}

export interface PromotionReward {
  id: string
  source: "settlement" | "point_log" | string
  order_id: number | null
  ref_no: string | null
  remark: string | null
  points: number
  status: "pending" | "frozen" | "settled" | "reversed" | string
  status_label: string
  frozen_until: string | null
  settled_at: string | null
  reversed_at: string | null
  created_at: string | null
}

export interface PromotionCoupon {
  id: number
  code: string
  description: string | null
  issuer_type: "member" | "agent" | string | null
  issuer_user_id: number | null
  point_cost: number
  point_refunded: number
  refundable_points: number
  type: "fixed" | "threshold_fixed" | "percent" | "override" | string
  value: number
  threshold_amount: number
  max_discount_amount: number
  discount_level: string
  scope: string
  claim_method: "code" | "mall"
  starts_at: string | null
  expires_at: string | null
  max_uses: number
  max_uses_per_user: number
  used_count: number
  new_users_only: boolean
  applies_to_renewals: boolean
  is_stackable: boolean
  is_enabled: boolean
  created_at: string | null
}

export interface CreatePromotionCouponPayload {
  code?: string
  description?: string
  type: "fixed" | "threshold_fixed" | "percent"
  value: number
  threshold_amount?: number | null
  max_discount_amount?: number | null
  max_uses: number
  max_uses_per_user: number
  expires_at?: string | null
  claim_method: "code" | "mall"
  list_on_mall: boolean
  points_price?: number | null
  stock_total?: number | null
  mall_title?: string | null
  mall_subtitle?: string | null
  mall_cover_image?: string | null
  mall_category?: string | null
  mall_scope?: "public" | "agent_subordinates"
  mall_sort_order?: number
}

export async function getPromotionOverview() {
  const res = await client.get("/v1/promotion/me")
  return res.data.data as PromotionOverview
}

export async function getPromotionCoupons(limit = 50, offset = 0) {
  const res = await client.get("/v1/promotion/coupons", {
    params: { limit, offset },
  })
  return listResult<PromotionCoupon>(res.data.data)
}

export async function createPromotionCoupon(payload: CreatePromotionCouponPayload) {
  const res = await client.post("/v1/promotion/coupons", payload)
  return res.data.data as {
    coupon: PromotionCoupon
    available_points?: number
    agent_balance?: number
    mall_item?: {
      id: number
      title?: string
      points_price: number
      stock_total: number
      stock_remaining: number
      status: string
      scope: string
      category?: string | null
    }
  }
}

export async function disablePromotionCoupon(couponId: number) {
  const res = await client.post(`/v1/promotion/coupons/${couponId}/disable`)
  return res.data.data as { coupon: PromotionCoupon; refunded_points: number; available_points?: number; agent_balance?: number }
}

export interface MallCouponItem {
  id: number
  promo_code_id: number
  title?: string
  subtitle?: string | null
  cover_image?: string | null
  description: string | null
  issuer_user_id: number
  issuer_name?: string
  issuer_type: string
  points_price: number
  stock_remaining: number
  scope: string
  category?: string | null
  max_claims_per_user: number
  max_claims_per_user_per_day: number
  required_member_level: number
  required_member_level_name: string | null
  is_hot: boolean
  type: string
  value: number
  threshold_amount: number
  max_discount_amount: number
  expires_at: string | null
  claimed: boolean
}

export interface MallItemsParams {
  limit?: number
  offset?: number
  scope?: "public" | "agent_subordinates"
  q?: string
  type?: "fixed" | "threshold_fixed" | "percent"
  min_points?: number
  max_points?: number
  is_hot?: boolean
  sort_by?: "points" | "expires" | "sort_order"
}

export async function getMallItems(params: MallItemsParams = {}) {
  const res = await client.get("/v1/promotion/mall/items", { params })
  return listResult<MallCouponItem>(res.data.data)
}

export async function claimMallCoupon(mallItemId: number, captcha: CaptchaResult | null) {
  const res = await client.post("/v1/promotion/mall/claim", { mall_item_id: mallItemId, captcha })
  return res.data.data as { claim_id: number; code: string; points_paid: number; available_points: number }
}

export interface MallClaimRecord {
  id: number
  mall_item_id: number
  promo_code_id: number
  title: string | null
  subtitle: string | null
  cover_image: string | null
  description: string | null
  category: string | null
  points_price: number
  stock_remaining: number
  scope: string
  max_claims_per_user: number
  max_claims_per_user_per_day: number
  required_member_level: number
  required_member_level_name: string | null
  is_hot: boolean
  issuer_name: string
  points_paid: number
  status: string
  used_at: string | null
  order_id: number | null
  type: string
  value: number
  threshold_amount: number
  max_discount_amount: number
  expires_at: string | null
}

export async function getMyMallClaims(status?: string) {
  const res = await client.get("/v1/promotion/mall/my-claims", { params: status ? { status } : undefined })
  return listResult<MallClaimRecord>(res.data.data)
}

export async function getPromotionRewards(limit = 20, offset = 0) {
  const res = await client.get("/v1/promotion/rewards", {
    params: { limit, offset },
  })
  return Array.isArray(res.data.data) ? res.data.data as PromotionReward[] : []
}

export async function updatePromotionInviteCode(inviteCode: string) {
  const res = await client.patch("/v1/promotion/invite-code", {
    invite_code: inviteCode,
  })
  return res.data.data as Pick<
    PromotionOverview,
    "invite_code" | "invite_link" | "register_link" | "invite_code_edit_enabled" | "invite_code_change_count" | "invite_code_change_limit" | "invite_code_change_remaining"
  >
}
