"use client"

import { useEffect, useState } from "react"
import Link from "next/link"
import { ArrowLeft, ChevronDown, ChevronRight, Receipt } from "lucide-react"

import { reportsApi } from "@/lib/api/general-ledger"
import { errorMessage } from "@/lib/error-map"
import { formatAmount, formatReportDate, startOfMonthIso, todayIso } from "@/lib/format"
import { cn } from "@/lib/utils"
import { ReportType, TaxSummaryResponse } from "@/types/general-ledger"

import { Button, buttonVariants } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Skeleton } from "@/components/ui/skeleton"
import { Table, TableBody, TableCell, TableRow } from "@/components/ui/table"
import { DownloadCsvButton } from "@/components/reports/DownloadCsvButton"
import { DownloadPdfButton } from "@/components/reports/DownloadPdfButton"

// Fixed row order + Add:/Less: labels per the confirmed GL contract
// (04_API_Reference_And_Scenarios.md, Module: Reporting — `profitBeforeTax` through
// `balanceTaxPayable`) — GL sends plain numbers, not pre-formatted rows; the prefix/bold treatment
// lives here, not derived from sign. `taxRatePercent` is shown separately below the table (it's a
// percentage, not a currency amount) rather than run through `formatAmount` here.
const ROWS: { key: keyof TaxSummaryResponse; label: string; bold?: boolean }[] = [
  { key: "profitBeforeTax", label: "Profit Before Tax" },
  { key: "nonDeductibleExpenses", label: "Add: Non-Deductible Expenses" },
  { key: "allowableDeductions", label: "Less: Allowable Deductions" },
  { key: "adjustedBusinessProfit", label: "Adjusted Business Profit", bold: true },
  { key: "otherTaxableIncome", label: "Add: Other Taxable Income" },
  { key: "assessableIncome", label: "Assessable Income", bold: true },
  { key: "qualifyingPaymentsReliefs", label: "Less: Qualifying Payments / Reliefs" },
  { key: "taxableIncome", label: "Taxable Income", bold: true },
  { key: "corporateIncomeTax", label: "Corporate Income Tax" },
  { key: "surchargeAmount", label: "Add: Surcharge / Education Levy" },
  { key: "grossTaxLiability", label: "Gross Tax Liability", bold: true },
  { key: "apitCredit", label: "Less: APIT Credit" },
  { key: "whtCredit", label: "Less: WHT Credit" },
  { key: "quarterlyTaxPayments", label: "Less: Quarterly Tax Payments" },
]

export default function TaxReportPage() {
  const [periodStart, setPeriodStart] = useState(startOfMonthIso())
  const [periodEnd, setPeriodEnd] = useState(todayIso())

  const [adjustmentsOpen, setAdjustmentsOpen] = useState(false)
  const [allowableDeductions, setAllowableDeductions] = useState("")
  const [otherTaxableIncome, setOtherTaxableIncome] = useState("")
  const [qualifyingPaymentsReliefs, setQualifyingPaymentsReliefs] = useState("")
  const [surchargeAmount, setSurchargeAmount] = useState("")
  const [taxRateOverride, setTaxRateOverride] = useState("")

  const [report, setReport] = useState<TaxSummaryResponse | null>(null)
  const [error, setError] = useState<string | null>(null)

  // Optional inputs get no client-side default — an untouched field sends nothing (undefined,
  // dropped by lib/api/general-ledger.ts's query builder), letting GL's own server-side
  // defaulting be the single source of truth for what "not supplied" means.
  const params = {
    periodStart,
    periodEnd,
    allowableDeductions: allowableDeductions === "" ? undefined : Number(allowableDeductions),
    otherTaxableIncome: otherTaxableIncome === "" ? undefined : Number(otherTaxableIncome),
    qualifyingPaymentsReliefs: qualifyingPaymentsReliefs === "" ? undefined : Number(qualifyingPaymentsReliefs),
    surchargeAmount: surchargeAmount === "" ? undefined : Number(surchargeAmount),
    taxRateOverride: taxRateOverride === "" ? undefined : Number(taxRateOverride),
  }
  const paramsKey = JSON.stringify(params)

  // Clears stale results the instant a param changes, during the render that reacts to it — not
  // inside the effect below, which would be a synchronous setState-in-effect
  // (react-hooks/set-state-in-effect); this is React's own sanctioned "adjust state during
  // render" pattern instead.
  const [loadedFor, setLoadedFor] = useState<string | null>(null)
  if (loadedFor !== paramsKey) {
    setLoadedFor(paramsKey)
    setReport(null)
    setError(null)
  }

  useEffect(() => {
    if (!periodStart || !periodEnd) return
    let cancelled = false
    reportsApi
      .taxSummary(params)
      .then((res) => {
        if (!cancelled) setReport(res)
      })
      .catch((err) => {
        if (!cancelled) setError(errorMessage(err))
      })
    return () => {
      cancelled = true
    }
    // paramsKey covers every field inside params; re-running on params itself would compare by
    // reference and fire every render, since it's a fresh object literal each time.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [paramsKey, periodStart, periodEnd])

  const isRefund = report !== null && report.balanceTaxPayable < 0
  const finalLabel = isRefund ? "BALANCE TAX REFUNDABLE" : "BALANCE TAX PAYABLE"
  const finalAmount = report ? Math.abs(report.balanceTaxPayable) : 0

  return (
    <div className="flex flex-col gap-6">
      <div className="flex items-center gap-3">
        <Link href="/dashboard/ledgers" className={cn(buttonVariants({ variant: "ghost", size: "icon-lg" }))}>
          <ArrowLeft className="size-5" />
        </Link>
        <div>
          <h1 className="text-2xl font-bold text-foreground">Tax Report</h1>
          <p className="text-base text-muted-foreground">Income Tax Computation for a period.</p>
        </div>
      </div>

      <div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
        <div className="grid grid-cols-2 gap-3 sm:flex sm:items-end">
          <div className="flex flex-col gap-1.5">
            <Label className="text-base">From</Label>
            <Input type="date" value={periodStart} onChange={(e) => setPeriodStart(e.target.value)} className="h-11 text-base" />
          </div>
          <div className="flex flex-col gap-1.5">
            <Label className="text-base">To</Label>
            <Input type="date" value={periodEnd} onChange={(e) => setPeriodEnd(e.target.value)} className="h-11 text-base" />
          </div>
        </div>
        <div className="flex gap-2">
          <DownloadPdfButton reportType={ReportType.TaxSummary} params={params} disabled={!report} />
          <DownloadCsvButton reportType={ReportType.TaxSummary} params={params} disabled={!report} />
        </div>
      </div>

      <div className="rounded-xl border">
        <button
          type="button"
          onClick={() => setAdjustmentsOpen((v) => !v)}
          className="flex w-full items-center gap-2 px-4 py-3 text-left text-base font-semibold"
        >
          {adjustmentsOpen ? <ChevronDown className="size-4" /> : <ChevronRight className="size-4" />}
          Adjustments (optional)
        </button>
        {adjustmentsOpen && (
          <div className="grid grid-cols-1 gap-3 border-t p-4 sm:grid-cols-2 lg:grid-cols-3">
            <div className="flex flex-col gap-1.5">
              <Label className="text-sm">Allowable Deductions</Label>
              <Input
                type="number"
                value={allowableDeductions}
                onChange={(e) => setAllowableDeductions(e.target.value)}
                placeholder="0"
                className="h-10 text-base"
              />
            </div>
            <div className="flex flex-col gap-1.5">
              <Label className="text-sm">Other Taxable Income</Label>
              <Input
                type="number"
                value={otherTaxableIncome}
                onChange={(e) => setOtherTaxableIncome(e.target.value)}
                placeholder="0"
                className="h-10 text-base"
              />
            </div>
            <div className="flex flex-col gap-1.5">
              <Label className="text-sm">Qualifying Payments / Reliefs</Label>
              <Input
                type="number"
                value={qualifyingPaymentsReliefs}
                onChange={(e) => setQualifyingPaymentsReliefs(e.target.value)}
                placeholder="System default"
                className="h-10 text-base"
              />
            </div>
            <div className="flex flex-col gap-1.5">
              <Label className="text-sm">Surcharge / Education Levy</Label>
              <Input
                type="number"
                value={surchargeAmount}
                onChange={(e) => setSurchargeAmount(e.target.value)}
                placeholder="0"
                className="h-10 text-base"
              />
            </div>
            <div className="flex flex-col gap-1.5">
              <Label className="text-sm">Tax Rate Override (%)</Label>
              <Input
                type="number"
                value={taxRateOverride}
                onChange={(e) => setTaxRateOverride(e.target.value)}
                placeholder="System default"
                className="h-10 text-base"
              />
            </div>
            {(allowableDeductions ||
              otherTaxableIncome ||
              qualifyingPaymentsReliefs ||
              surchargeAmount ||
              taxRateOverride) && (
              <div className="flex items-end">
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => {
                    setAllowableDeductions("")
                    setOtherTaxableIncome("")
                    setQualifyingPaymentsReliefs("")
                    setSurchargeAmount("")
                    setTaxRateOverride("")
                  }}
                >
                  Clear adjustments
                </Button>
              </div>
            )}
          </div>
        )}
      </div>

      {error && (
        <div className="rounded-lg border border-destructive/30 bg-destructive/5 p-5 text-base text-destructive">{error}</div>
      )}

      {!error && report === null && (
        <div className="flex flex-col gap-3">
          {Array.from({ length: 6 }).map((_, i) => (
            <Skeleton key={i} className="h-12 w-full" />
          ))}
        </div>
      )}

      {!error && report !== null && (
        <div className="rounded-2xl bg-white p-6 shadow-sm ring-1 ring-black/5">
          {/* Own header, not the shared ReportHeader — GL's own PDF gives this report a fuller
              identity block (company name/address/TIN/BRN) that today lives only in GL's own
              appsettings.json, with no endpoint exposing it. Deliberately not fabricated here —
              see docs/21-GENERAL-LEDGER-FRONTEND.md §3's open question. */}
          <div className="flex flex-col items-center gap-1 border-b-2 border-foreground/70 px-4 pb-5 text-center">
            <p className="text-xs font-semibold tracking-[0.2em] text-muted-foreground uppercase">
              General Ledger
            </p>
            <h2 className="text-xl font-bold tracking-tight text-foreground uppercase">Income Tax Computation</h2>
            <p className="text-base text-muted-foreground">
              For the period {formatReportDate(periodStart)} to {formatReportDate(periodEnd)}
            </p>
            <p className="text-sm text-muted-foreground">
              Company identity (name/address/TIN/BRN) isn&apos;t shown here — GL exposes no endpoint for it yet.
            </p>
          </div>

          <div className="flex items-center gap-2 py-3 text-muted-foreground">
            <Receipt className="size-4" />
            <p className="flex-1 text-sm">
              All amounts in Sri Lankan Rupees (LKR) unless stated otherwise.
            </p>
          </div>

          <Table className="text-base">
            <TableBody>
              {ROWS.map((row) => (
                <TableRow key={row.key} className={row.bold ? "bg-muted/40 hover:bg-muted/40" : undefined}>
                  <TableCell className={cn("px-3 py-2.5", row.bold && "font-semibold")}>{row.label}</TableCell>
                  <TableCell className={cn("px-3 py-2.5 text-right tabular-nums", row.bold && "font-semibold")}>
                    {formatAmount(report[row.key] as number)}
                  </TableCell>
                </TableRow>
              ))}
              <TableRow className="border-t-2 border-foreground/70 bg-muted/60 hover:bg-muted/60">
                <TableCell className="px-3 py-3 text-base font-bold">{finalLabel}</TableCell>
                <TableCell className="px-3 py-3 text-right text-base font-bold tabular-nums">
                  {formatAmount(finalAmount)}
                </TableCell>
              </TableRow>
            </TableBody>
          </Table>

          <p className="mt-3 text-sm text-muted-foreground">
            Tax rate applied: {report.taxRatePercent}%
          </p>
        </div>
      )}
    </div>
  )
}
