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

const BASE = "/v1/agent"

function pageResult<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,
  }
}

function defaultOverview(value: AgentOverview | null | undefined): AgentOverview {
  return {
    agent: value?.agent ?? null,
    customer_count: Number(value?.customer_count ?? 0) || 0,
    pending_profit: Number(value?.pending_profit ?? 0) || 0,
    total_sales: Number(value?.total_sales ?? 0) || 0,
    total_profit: Number(value?.total_profit ?? 0) || 0,
    invite_code: value?.invite_code ?? null,
    invite_code_edit_enabled: Boolean(value?.invite_code_edit_enabled),
    invite_code_change_count: Number(value?.invite_code_change_count ?? 0) || 0,
    invite_code_change_limit: Number(value?.invite_code_change_limit ?? 3) || 3,
    invite_code_change_remaining: Number(value?.invite_code_change_remaining ?? 0) || 0,
    member_commission_rate: Number(value?.member_commission_rate ?? 0) || 0,
    available_points: Number(value?.available_points ?? 0) || 0,
    total_points: Number(value?.total_points ?? 0) || 0,
  }
}

export interface AgentOverview {
  agent: AgentInfo | null
  customer_count: number
  pending_profit: number
  total_sales: number
  total_profit: number
  invite_code: string | null
  invite_code_edit_enabled: boolean
  invite_code_change_count: number
  invite_code_change_limit: number
  invite_code_change_remaining: number
  member_commission_rate: number
  available_points?: number
  total_points?: number
}

export interface AgentInfo {
  id: number
  user_id: number
  agent_tier_id: number | null
  status: string
  invite_code: string | null
  total_sales: number
  total_profit: number
  total_subsidy: number
  agent_balance: number
  agent_frozen_balance: number
  approved_at: string | null
  observe_started_at?: string | null
  observe_until?: string | null
  risk_locked_at?: string | null
  risk_reason?: string | null
  last_evaluated_at?: string | null
  last_evaluation_snapshot?: Record<string, unknown> | null
  reject_reason: string | null
  remark: string | null
  review_message: string | null
  apply_tier: string | null
  apply_reason: string | null
  apply_channels: string | null
  created_at: string
  agent_tier: AgentTier | null
}

export interface AgentTier {
  id: number
  name: string
  code: string
  cost_rate: number
  min_member_level: number
  min_total_spend: number
  max_coupon_discount_rate?: number
  max_monthly_coupon_count?: number
  sort_order: number
  enabled: boolean
  description: string | null
}

export interface AgentCustomerItem {
  id: number
  agent_user_id: number
  customer_user_id: number
  bind_source: string
  bound_at: string
  first_order_id: number | null
  status: string
  customer: {
    id: number
    username: string
    email: string | null
    phone: string | null
    nickname: string | null
    balance: number
    created_at: string
  } | null
}

export interface AgentSettlementItem {
  id: number
  order_id: number
  order_no: string
  settlement_type: "agent_profit" | "agent_subsidy" | "member_commission"
  user_id: number
  customer_user_id: number | null
  standard_amount: number
  customer_pay_amount: number
  agent_cost_rate: number | null
  agent_cost_amount: number | null
  delta_amount: number
  commission_rate: number | null
  status: string
  frozen_until: string | null
  points_amount: number
  point_log_id: number | null
  settled_at: string | null
  reversed_at: string | null
  remark: string | null
  created_at: string
}

export interface AffiliateInfo {
  aff_code: string
  agent_name: string | null
  agent_tier: string | null
}

export async function getAgentOverview(): Promise<ApiResponse<AgentOverview>> {
  const { data } = await client.get<ApiResponse<AgentOverview>>(`${BASE}/me`)
  return { ...data, data: defaultOverview(data.data) }
}

export async function listPublicAgentTiers(): Promise<ApiResponse<AgentTier[]>> {
  const { data } = await client.get<ApiResponse<AgentTier[]>>(`${BASE}/tiers`)
  return { ...data, data: Array.isArray(data.data) ? data.data : [] }
}

export async function getAgentCustomers(offset = 0, limit = 20): Promise<ApiResponse<{ items: AgentCustomerItem[]; total: number }>> {
  const { data } = await client.get<ApiResponse<{ items: AgentCustomerItem[]; total: number }>>(`${BASE}/customers`, { params: { offset, limit } })
  return { ...data, data: pageResult<AgentCustomerItem>(data.data) }
}

export async function getAgentSettlements(offset = 0, limit = 20): Promise<ApiResponse<{ items: AgentSettlementItem[]; total: number }>> {
  const { data } = await client.get<ApiResponse<{ items: AgentSettlementItem[]; total: number }>>(`${BASE}/settlements`, { params: { offset, limit } })
  return { ...data, data: pageResult<AgentSettlementItem>(data.data) }
}

export async function getInviteCode(): Promise<ApiResponse<{ invite_code: string; invite_link: string; register_link: string }>> {
  const { data } = await client.get<ApiResponse<{ invite_code: string; invite_link: string; register_link: string }>>(`${BASE}/invite-code`)
  return data
}

export async function applyAgent(tier: string, reason: string, channels: string): Promise<ApiResponse<AgentInfo>> {
  const { data } = await client.post<ApiResponse<AgentInfo>>(`${BASE}/apply`, { tier, reason, channels })
  return data
}

export async function getAffiliateInfo(code: string): Promise<ApiResponse<AffiliateInfo>> {
  const { data } = await client.get<ApiResponse<AffiliateInfo>>(`${BASE}/aff-info`, { params: { code } })
  return data
}

export async function recordAffClick(
  affCode: string,
  extra?: {
    ref?: string
    coupon?: string
    utm_source?: string
    utm_medium?: string
    utm_campaign?: string
    utm_content?: string
    utm_term?: string
    landing_url?: string
  },
): Promise<ApiResponse<{ ok: boolean }>> {
  const { data } = await client.post<ApiResponse<{ ok: boolean }>>(`${BASE}/aff-click`, {
    aff_code: affCode,
    ...extra,
  })
  return data
}
