/**
 * Stage demo seeder: запуск + проверка наполнения + идемпотентность.
 */
import { login, makeClient } from '../lib/api.js'
import type { CheckResult, Step, Report } from '../lib/report.js'

type Ctx = {
  apiOnly: boolean
  ts: number
  email?: string
  password?: string
  token?: string
  initialSummary?: SeedSummary
}
interface SeedSummary {
  alreadySeeded: boolean
  groups: number; products: number; counterparties: number
  supplies: number; sales: number; demands: number
  losses: number; transfers: number; inventories: number; stores: number
}
interface StepCtx { ctx: Ctx; step: Step; report: Report }

const TS = Date.now()
function check(step: Step, c: CheckResult) { step.checks.push(c) }
function asString(x: unknown): string {
  if (x == null) return ''
  return typeof x === 'string' ? x : JSON.stringify(x)
}

async function bootstrap(ctx: Ctx): Promise<void> {
  if (ctx.token) return
  const api = makeClient()
  ctx.email = `stage-seed-${TS}@food-market.local`
  ctx.password = 'StageSeed12345!'
  let r = await api.post('/api/auth/signup', {
    email: ctx.email, password: ctx.password,
    organizationName: `Seed ${TS}`, phone: '+77011190001', plan: 'start',
  })
  for (let i = 0; i < 5 && r.status === 429; i++) {
    await new Promise(res => setTimeout(res, 15000))
    r = await api.post('/api/auth/signup', {
      email: ctx.email, password: ctx.password,
      organizationName: `Seed ${TS}`, phone: '+77011190001', plan: 'start',
    })
  }
  if (r.status !== 200) throw new Error(`signup: ${r.status} ${JSON.stringify(r.data)}`)
  const sess = await login(ctx.email, ctx.password)
  ctx.token = sess.accessToken
}

// ---------------------------------------------------------------------------

export async function seed01_status_empty({ ctx, step, report }: StepCtx) {
  ctx.ts = TS
  await bootstrap(ctx)
  const api = makeClient(ctx.token)
  const r = await api.get('/api/admin/seed-demo/status')
  check(step, { kind: 'api', description: 'GET /status → 200', ok: r.status === 200, detail: `${r.status}` })
  ctx.initialSummary = r.data as SeedSummary
  check(step, { kind: 'api', description: 'alreadySeeded = false', ok: r.data?.alreadySeeded === false, detail: `already=${r.data?.alreadySeeded}` })
  check(step, { kind: 'api', description: 'products = 0', ok: r.data?.products === 0, detail: `products=${r.data?.products}` })
}

// ---------------------------------------------------------------------------

export async function seed02_run({ ctx, step, report }: StepCtx) {
  if (!ctx.token) { step.status = 'skip'; return }
  const api = makeClient(ctx.token)
  const r = await api.post('/api/admin/seed-demo', {})
  check(step, { kind: 'api', description: 'POST /seed-demo → 200', ok: r.status === 200, detail: `${r.status} ${asString(r.data).slice(0, 250)}` })
  if (r.status !== 200) return
  const s = r.data as SeedSummary
  check(step, { kind: 'api', description: 'alreadySeeded в ответе = false (только что заполнили)', ok: s.alreadySeeded === false, detail: `already=${s.alreadySeeded}` })
  check(step, { kind: 'api', description: 'products = 50', ok: s.products === 50, detail: `products=${s.products}` })
  check(step, { kind: 'api', description: 'groups = 5', ok: s.groups === 5, detail: `groups=${s.groups}` })
  check(step, { kind: 'api', description: 'counterparties = 10', ok: s.counterparties === 10, detail: `cp=${s.counterparties}` })
  check(step, { kind: 'api', description: 'supplies = 5, sales = 30', ok: s.supplies === 5 && s.sales === 30, detail: `sup=${s.supplies} sales=${s.sales}` })
  check(step, { kind: 'api', description: 'demands=1, losses=1, transfers=1, inventories=1', ok: s.demands === 1 && s.losses === 1 && s.transfers === 1 && s.inventories === 1, detail: `dm=${s.demands} loss=${s.losses} tr=${s.transfers} inv=${s.inventories}` })
  check(step, { kind: 'api', description: 'stores >= 2 (main + резерв для transfer)', ok: s.stores >= 2, detail: `stores=${s.stores}` })
}

// ---------------------------------------------------------------------------

export async function seed03_status_after({ ctx, step, report }: StepCtx) {
  if (!ctx.token) { step.status = 'skip'; return }
  const api = makeClient(ctx.token)
  const r = await api.get('/api/admin/seed-demo/status')
  check(step, { kind: 'api', description: 'GET /status → alreadySeeded=true', ok: r.data?.alreadySeeded === true, detail: `already=${r.data?.alreadySeeded}` })
  check(step, { kind: 'api', description: 'products = 50 в статусе', ok: r.data?.products === 50, detail: `products=${r.data?.products}` })
}

// ---------------------------------------------------------------------------

export async function seed04_data_visible_via_normal_apis({ ctx, step, report }: StepCtx) {
  if (!ctx.token) { step.status = 'skip'; return }
  const api = makeClient(ctx.token)
  const [prods, supplies, sales, demands, transfers, invs, cps] = await Promise.all([
    api.get('/api/catalog/products?pageSize=200'),
    api.get('/api/purchases/supplies?pageSize=50'),
    api.get('/api/sales/retail?pageSize=50'),
    api.get('/api/sales/demands?pageSize=50'),
    api.get('/api/inventory/transfers?pageSize=50'),
    api.get('/api/inventory/inventories?pageSize=50'),
    api.get('/api/catalog/counterparties?pageSize=50'),
  ])
  check(step, { kind: 'api', description: 'products total >= 50', ok: (prods.data?.total ?? 0) >= 50, detail: `total=${prods.data?.total}` })
  check(step, { kind: 'api', description: 'supplies total >= 5', ok: (supplies.data?.total ?? 0) >= 5, detail: `total=${supplies.data?.total}` })
  check(step, { kind: 'api', description: 'retail sales total >= 30', ok: (sales.data?.total ?? 0) >= 30, detail: `total=${sales.data?.total}` })
  check(step, { kind: 'api', description: 'demands total >= 1', ok: (demands.data?.total ?? 0) >= 1, detail: `total=${demands.data?.total}` })
  check(step, { kind: 'api', description: 'transfers total >= 1', ok: (transfers.data?.total ?? 0) >= 1, detail: `total=${transfers.data?.total}` })
  check(step, { kind: 'api', description: 'inventories total >= 1', ok: (invs.data?.total ?? 0) >= 1, detail: `total=${invs.data?.total}` })
  check(step, { kind: 'api', description: 'counterparties total >= 10', ok: (cps.data?.total ?? 0) >= 10, detail: `total=${cps.data?.total}` })

  // Проверка: все demo-товары начинаются с DEMO- в article
  const demoCount = (prods.data?.items ?? []).filter((p: { article?: string }) => p.article?.startsWith('DEMO-')).length
  check(step, { kind: 'api', description: 'Все 50 demo-товаров имеют article DEMO-...', ok: demoCount === 50, detail: `demoCount=${demoCount}` })
}

// ---------------------------------------------------------------------------

export async function seed05_idempotent({ ctx, step, report }: StepCtx) {
  if (!ctx.token) { step.status = 'skip'; return }
  const api = makeClient(ctx.token)
  const second = await api.post('/api/admin/seed-demo', {})
  check(step, { kind: 'api', description: 'Повторный POST → 200, alreadySeeded=true', ok: second.status === 200 && second.data?.alreadySeeded === true, detail: `${second.status} already=${second.data?.alreadySeeded}` })
  check(step, { kind: 'api', description: 'products = 50 (не дублировано)', ok: second.data?.products === 50, detail: `products=${second.data?.products}` })

  const prods = await api.get('/api/catalog/products?pageSize=200')
  check(step, { kind: 'api', description: 'products total всё ещё 50', ok: (prods.data?.total ?? 0) === 50, detail: `total=${prods.data?.total}` })
}
