/**
 * Admin tax rates API routes — admin-dashboard.
 * GET  /api/admin/tax-rates?country=IL → grouped list (non-VAT + VAT sections)
 * POST /api/admin/tax-rates            → add a new rate
 */
import { Hono } from 'hono'
import { z } from 'zod'
import { createDb } from '@zync/db/queries'
import {
  listTaxRates,
  addTaxRate,
  listVatRatesForAdmin,
  TaxRateConflictError,
  TaxRateValidationError,
} from '@zync/db/queries'
import { ADMIN_TAX_TYPES } from '@zync/types'
import type { AppEnv } from '../../types'
import { adminAuthMiddleware } from '../../middleware/admin-auth'
import { requireAdminSession } from '../../middleware/guards'
import type { AdminSessionPayload } from '@zync/types'

type AdminSessionWithRole = AdminSessionPayload & {
  permissions?: string[]
  role?: string | null
}

const adminTaxRatesRoutes = new Hono<AppEnv>()

adminTaxRatesRoutes.use('*', adminAuthMiddleware)
adminTaxRatesRoutes.use('*', requireAdminSession())

function requireSuperAdmin(c: { get: (key: 'session') => unknown }) {
  const session = c.get('session') as AdminSessionWithRole | undefined
  return session?.role === 'SUPER_ADMIN'
}

const QuerySchema = z.object({
  country: z.string().length(2).toUpperCase().default('IL'),
})

const AddTaxRateSchema = z.object({
  countryCode: z.string().length(2).toUpperCase(),
  taxType: z.enum(ADMIN_TAX_TYPES),
  rate: z
    .string()
    .regex(/^\d+(\.\d{1,4})?$/, 'Rate must be a decimal fraction, e.g. 0.2300'),
  effectiveFrom: z
    .string()
    .regex(/^\d{4}-\d{2}-\d{2}$/, 'effectiveFrom must be YYYY-MM-DD'),
  thresholdIls: z.string().nullable().optional(),
  notes: z.string().nullable().optional(),
})

// ── List ──────────────────────────────────────────────────────────────────────

adminTaxRatesRoutes.get(
  '/',
  async (c) => {
    if (!requireSuperAdmin(c)) {
      return c.json({ error: 'Forbidden' }, 403)
    }

    const parsed = QuerySchema.safeParse(c.req.query())
    if (!parsed.success) {
      return c.json({ error: 'Invalid query params', details: parsed.error.flatten() }, 400)
    }

    const db = createDb(c.env)
    const [rates, vat] = await Promise.all([
      listTaxRates(db, parsed.data.country),
      listVatRatesForAdmin(db, parsed.data.country),
    ])

    return c.json({ country: parsed.data.country, rates, vat })
  },
)

// ── Add ───────────────────────────────────────────────────────────────────────

adminTaxRatesRoutes.post(
  '/',
  async (c) => {
    if (!requireSuperAdmin(c)) {
      return c.json({ error: 'Forbidden' }, 403)
    }

    const parsed = AddTaxRateSchema.safeParse(await c.req.json())
    if (!parsed.success) {
      return c.json({ error: 'Invalid request', details: parsed.error.flatten() }, 400)
    }

    const session = c.get('session') as AdminSessionWithRole

    try {
      const db = createDb(c.env)
      const result = await addTaxRate(db, {
        countryCode: parsed.data.countryCode,
        taxType: parsed.data.taxType,
        rate: parsed.data.rate,
        effectiveFrom: parsed.data.effectiveFrom,
        thresholdIls: parsed.data.thresholdIls ?? null,
        notes: parsed.data.notes ?? null,
        createdBy: session.sub,
      })

      return c.json(result, 201)
    } catch (err) {
      if (err instanceof TaxRateConflictError) {
        return c.json({ error: err.message }, 409)
      }
      if (err instanceof TaxRateValidationError) {
        return c.json({ error: err.message }, 400)
      }
      throw err
    }
  },
)

export { adminTaxRatesRoutes }
