"use client"

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

import { reportsApi } from "@/lib/api/general-ledger"
import { errorMessage } from "@/lib/error-map"
import { formatReportDate, todayIso } from "@/lib/format"
import { cn } from "@/lib/utils"
import { BalanceSheetResponse, BalanceSheetSection, 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 { DownloadCsvButton } from "@/components/reports/DownloadCsvButton"
import { DownloadPdfButton } from "@/components/reports/DownloadPdfButton"
import { ReportHeader } from "@/components/reports/ReportHeader"
import { ReportSection, ReportSectionLine } from "@/components/reports/ReportSection"
import { ReportSubtotal } from "@/components/reports/ReportSubtotal"

// GL's leaf rows carry `accountCode` too, but a classified Statement of Financial Position
// (matching the reference template this screen follows) shows plain line-item names only, no
// codes — same convention as the Balance Sheet's account-code-free presentation elsewhere.
function sectionLines(section?: BalanceSheetSection): ReportSectionLine[] {
  return (section?.lines ?? []).map((l) => ({ label: l.accountName, amount: l.balance }))
}

export default function BalanceSheetPage() {
  const [asOfDate, setAsOfDate] = useState(todayIso())
  const [report, setReport] = useState<BalanceSheetResponse | null>(null)
  const [error, setError] = useState<string | null>(null)

  // Clears stale results the instant asOfDate 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 !== asOfDate) {
    setLoadedFor(asOfDate)
    setReport(null)
    setError(null)
  }

  useEffect(() => {
    if (!asOfDate) return
    let cancelled = false
    reportsApi
      .balanceSheet(asOfDate)
      .then((res) => {
        if (!cancelled) setReport(res)
      })
      .catch((err) => {
        if (!cancelled) setError(errorMessage(err))
      })
    return () => {
      cancelled = true
    }
  }, [asOfDate])

  const isEmpty =
    report !== null &&
    (report.nonCurrentAssets?.lines?.length ?? 0) === 0 &&
    (report.currentAssets?.lines?.length ?? 0) === 0 &&
    (report.unclassifiedAssets?.lines?.length ?? 0) === 0 &&
    (report.equity?.lines?.length ?? 0) === 0 &&
    (report.nonCurrentLiabilities?.lines?.length ?? 0) === 0 &&
    (report.currentLiabilities?.lines?.length ?? 0) === 0 &&
    (report.unclassifiedLiabilities?.lines?.length ?? 0) === 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">Balance Sheet</h1>
          <p className="text-base text-muted-foreground">Statement of Financial Position — Assets, Liabilities, Equity.</p>
        </div>
      </div>

      <div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
        <div className="flex flex-col gap-1.5">
          <Label className="text-base">As at</Label>
          <Input type="date" value={asOfDate} onChange={(e) => setAsOfDate(e.target.value)} className="h-11 w-full text-base sm:w-60" />
        </div>
        <div className="flex gap-2">
          <DownloadPdfButton reportType={ReportType.BalanceSheet} params={{ asOfDate }} disabled={!report} />
          <DownloadCsvButton reportType={ReportType.BalanceSheet} params={{ asOfDate }} disabled={!report} />
        </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 && isEmpty && (
        <div className="flex flex-col items-center gap-4 rounded-xl border border-dashed py-20 text-center">
          <Landmark className="size-12 text-muted-foreground" />
          <p className="text-base text-muted-foreground">No Asset/Liability/Equity accounts as at this date.</p>
        </div>
      )}

      {!error && report !== null && !isEmpty && (
        <div className="rounded-2xl bg-white p-6 shadow-sm ring-1 ring-black/5">
          <ReportHeader title="Statement of Financial Position" subtitle={`As at ${formatReportDate(asOfDate)}`} />

          <div className="mt-4">
            <p className="mb-2 text-sm font-bold tracking-wide text-foreground uppercase">Assets</p>
            <ReportSection
              title="Non-Current Assets"
              lines={sectionLines(report.nonCurrentAssets)}
              total={report.nonCurrentAssets?.total}
            />
            <ReportSection title="Current Assets" lines={sectionLines(report.currentAssets)} total={report.currentAssets?.total} />
            <ReportSection
              title="Unclassified Assets"
              lines={sectionLines(report.unclassifiedAssets)}
              total={report.unclassifiedAssets?.total}
            />
            <ReportSubtotal label="Total Assets" amount={report.totalAssets} large />

            <p className="mt-6 mb-2 text-sm font-bold tracking-wide text-foreground uppercase">Equity and Liabilities</p>
            <ReportSection title="Equity" lines={sectionLines(report.equity)} total={report.equity?.total} />
            <ReportSection
              title="Non-Current Liabilities"
              lines={sectionLines(report.nonCurrentLiabilities)}
              total={report.nonCurrentLiabilities?.total}
            />
            <ReportSection
              title="Current Liabilities"
              lines={sectionLines(report.currentLiabilities)}
              total={report.currentLiabilities?.total}
            />
            <ReportSection
              title="Unclassified Liabilities"
              lines={sectionLines(report.unclassifiedLiabilities)}
              total={report.unclassifiedLiabilities?.total}
            />
            <ReportSubtotal label="Total Equity and Liabilities" amount={report.totalEquityAndLiabilities} large />
          </div>
        </div>
      )}
    </div>
  )
}
