"use client"

import { Fragment, useEffect, useState } from "react"
import Link from "next/link"
import { ArrowLeft, BookOpen } 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 { GeneralLedgerRow, ReportType } from "@/types/general-ledger"

import { 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, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { DownloadCsvButton } from "@/components/reports/DownloadCsvButton"
import { DownloadPdfButton } from "@/components/reports/DownloadPdfButton"
import { ReportHeader } from "@/components/reports/ReportHeader"

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

  const [rows, setRows] = useState<GeneralLedgerRow[] | null>(null)
  const [error, setError] = useState<string | null>(null)

  // Clears stale results the instant the period 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 periodKey = `${periodStart}|${periodEnd}`
  const [loadedFor, setLoadedFor] = useState<string | null>(null)
  if (loadedFor !== periodKey) {
    setLoadedFor(periodKey)
    setRows(null)
    setError(null)
  }

  useEffect(() => {
    if (!periodStart || !periodEnd) return
    let cancelled = false
    reportsApi
      .generalLedger(periodStart, periodEnd)
      .then((res) => {
        if (!cancelled) setRows(res)
      })
      .catch((err) => {
        if (!cancelled) setError(errorMessage(err))
      })
    return () => {
      cancelled = true
    }
  }, [periodStart, periodEnd])

  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">General Ledger</h1>
          <p className="text-base text-muted-foreground">Every posted movement on every account, with a running balance per account.</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.GeneralLedger} params={{ periodStart, periodEnd }} disabled={!rows} />
          <DownloadCsvButton reportType={ReportType.GeneralLedger} params={{ periodStart, periodEnd }} disabled={!rows} />
        </div>
      </div>

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

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

      {!error && rows !== null && rows.length === 0 && (
        <div className="flex flex-col items-center gap-4 rounded-xl border border-dashed py-20 text-center">
          <BookOpen className="size-12 text-muted-foreground" />
          <p className="text-base text-muted-foreground">No postings on any account in the selected period.</p>
        </div>
      )}

      {!error && rows !== null && rows.length > 0 && (
        <div className="rounded-2xl bg-white p-6 shadow-sm ring-1 ring-black/5">
          <ReportHeader title="General Ledger" subtitle={`${formatReportDate(periodStart)} to ${formatReportDate(periodEnd)}`} />
          <Table className="mt-4 text-base">
            <TableHeader>
              <TableRow>
                <TableHead className="h-11 px-3 text-sm">Date</TableHead>
                <TableHead className="h-11 px-3 text-sm">Journal No.</TableHead>
                <TableHead className="h-11 px-3 text-sm">Narration</TableHead>
                <TableHead className="h-11 px-3 text-right text-sm">Debit</TableHead>
                <TableHead className="h-11 px-3 text-right text-sm">Credit</TableHead>
                <TableHead className="h-11 px-3 text-right text-sm">Running balance</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {rows.map((row, i) => {
                const isNewAccount = i === 0 || row.accountCode !== rows[i - 1].accountCode
                return (
                  <Fragment key={i}>
                    {isNewAccount && (
                      <TableRow className="bg-muted/40 hover:bg-muted/40">
                        <TableCell colSpan={6} className="px-3 py-2 font-semibold">
                          {row.accountCode} — {row.accountName}
                        </TableCell>
                      </TableRow>
                    )}
                    <TableRow>
                      <TableCell className="px-3 py-2.5">{formatReportDate(row.entryDate)}</TableCell>
                      <TableCell className="px-3 py-2.5 font-medium">{row.journalNo}</TableCell>
                      <TableCell className="px-3 py-2.5 text-muted-foreground">{row.narration ?? "—"}</TableCell>
                      <TableCell className="px-3 py-2.5 text-right tabular-nums">{formatAmount(row.debitAmount, true)}</TableCell>
                      <TableCell className="px-3 py-2.5 text-right tabular-nums">{formatAmount(row.creditAmount, true)}</TableCell>
                      <TableCell className="px-3 py-2.5 text-right font-medium tabular-nums">{formatAmount(row.runningBalance)}</TableCell>
                    </TableRow>
                  </Fragment>
                )
              })}
            </TableBody>
          </Table>
        </div>
      )}
    </div>
  )
}
