import { computeDateRange, toDateOnly } from './dateRange.uts'
import { rpcOrEmptyArray, rpcOrNull } from './rpc.uts'

export type TrendData = { x: Array<string>; gmv: Array<number>; orders: Array<number> }

export type SalesKpis = {
  gmv: number
  gmv_growth: number
  orders: number
  order_growth: number
  conversion_rate: number
  conversion_growth: number
  avg_order_amount: number
  avg_order_growth: number
}

export type ProductRank = { id: string; rank: number; name: string; sales: number }
export type MerchantRank = { id: string; rank: number; name: string; sales: number; growth: number }

function safeNumber(v: any): number {
  const n = Number(v)
  return isFinite(n) ? n : 0
}

export async function fetchSalesKpis(period: string, range?: { start: string; end: string } | null): Promise<SalesKpis> {
  let startIso: string;
  let endIso: string;

  if (range != null && range.start && range.end) {
    startIso = range.start;
    endIso = range.end;
  } else {
    const computedRange = computeDateRange(period);
    startIso = computedRange.startIso;
    endIso = computedRange.endIso;
  }
  const row = await rpcOrNull('rpc_analytics_sales_kpis', {
    p_start_date: toDateOnly(startIso),
    p_end_date: toDateOnly(endIso)
  } as any)

  const obj: any = row != null ? row : ({} as any)
  const gmv = safeNumber(obj.getAny?.('gmv') ?? 0)
  const orders = safeNumber(obj.getAny?.('orders') ?? 0)
  const avgOrder = orders > 0 ? gmv / orders : 0

  return {
    gmv: Math.round(gmv),
    gmv_growth: safeNumber(obj.getAny?.('gmv_growth') ?? 0),
    orders: Math.round(orders),
    order_growth: safeNumber(obj.getAny?.('order_growth') ?? 0),
    conversion_rate: safeNumber(obj.getAny?.('conversion_rate') ?? 0),
    conversion_growth: safeNumber(obj.getAny?.('conversion_growth') ?? 0),
    avg_order_amount: avgOrder,
    avg_order_growth: safeNumber(obj.getAny?.('avg_order_growth') ?? obj.getAny?.('gmv_growth') ?? 0)
  }
}

export async function fetchSalesTrend(period: string, range?: { start: string; end: string } | null): Promise<TrendData> {
  let startIso: string;
  let endIso: string;

  if (range != null && range.start && range.end) {
    startIso = range.start;
    endIso = range.end;
  } else {
    const computedRange = computeDateRange(period);
    startIso = computedRange.startIso;
    endIso = computedRange.endIso;
  }
  const rows = await rpcOrEmptyArray('rpc_analytics_sales_trend', {
    p_start_date: toDateOnly(startIso),
    p_end_date: toDateOnly(endIso)
  } as any)

  const x: Array<string> = []
  const gmvArr: Array<number> = []
  const orderArr: Array<number> = []

  for (let i = 0; i < rows.length; i++) {
    const r: any = rows[i]
    const d = `${r.getAny?.('date') ?? ''}`
    x.push(d.length >= 10 ? d.slice(5) : d)
    gmvArr.push(safeNumber(r.getAny?.('gmv') ?? 0))
    orderArr.push(safeNumber(r.getAny?.('orders') ?? 0))
  }

  return { x, gmv: gmvArr, orders: orderArr }
}

export async function fetchSalesTopProducts(period: string, limit: number = 50, range?: { start: string; end: string } | null): Promise<Array<ProductRank>> {
  let startIso: string;
  let endIso: string;

  if (range != null && range.start && range.end) {
    startIso = range.start;
    endIso = range.end;
  } else {
    const computedRange = computeDateRange(period);
    startIso = computedRange.startIso;
    endIso = computedRange.endIso;
  }
  const rows = await rpcOrEmptyArray('rpc_analytics_top_products', {
    p_start_date: toDateOnly(startIso),
    p_end_date: toDateOnly(endIso),
    p_limit: limit
  } as any)

  const list: Array<ProductRank> = []
  for (let i = 0; i < rows.length; i++) {
    const r: any = rows[i]
    list.push({
      id: `${r.getAny?.('id') ?? i}`,
      rank: i + 1,
      name: `${r.getAny?.('name') ?? ''}`,
      sales: safeNumber(r.getAny?.('sales') ?? 0)
    })
  }
  return list
}

export async function fetchSalesTopMerchants(period: string, limit: number = 50, range?: { start: string; end: string } | null): Promise<Array<MerchantRank>> {
  let startIso: string;
  let endIso: string;

  if (range != null && range.start && range.end) {
    startIso = range.start;
    endIso = range.end;
  } else {
    const computedRange = computeDateRange(period);
    startIso = computedRange.startIso;
    endIso = computedRange.endIso;
  }
  const rows = await rpcOrEmptyArray('rpc_analytics_top_merchants', {
    p_start_date: toDateOnly(startIso),
    p_end_date: toDateOnly(endIso),
    p_limit: limit
  } as any)

  const list: Array<MerchantRank> = []
  for (let i = 0; i < rows.length; i++) {
    const r: any = rows[i]
    list.push({
      id: `${r.getAny?.('id') ?? i}`,
      rank: i + 1,
      name: `${r.getAny?.('name') ?? ''}`,
      sales: safeNumber(r.getAny?.('sales') ?? 0),
      growth: safeNumber(r.getAny?.('growth') ?? 0)
    })
  }
  return list
}
