"use client"

import { useEffect, useState } from "react"
import Link from "next/link"
import { AlertTriangle, ArrowLeft, CheckCircle2, Lock, ReceiptText } from "lucide-react"

import { salesDayEndApi } from "@/lib/api/sales-day-end"
import { usersApi } from "@/lib/api/users"
import { errorMessage } from "@/lib/error-map"
import { cn } from "@/lib/utils"
import { ManagedUser } from "@/types/users"
import { SalesDayEnd, SalesDayEndPreview } from "@/types/sales"

import { Button, buttonVariants } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Skeleton } from "@/components/ui/skeleton"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { toast } from "@/components/ui/toast"

function todayIso(): string {
  return new Date().toISOString().slice(0, 10)
}

export default function SalesDayEndPage() {
  const [cashiers, setCashiers] = useState<ManagedUser[]>([])
  const [cashierUserId, setCashierUserId] = useState<number | null>(null)
  const [businessDate, setBusinessDate] = useState(todayIso())

  const [preview, setPreview] = useState<SalesDayEndPreview | null>(null)
  const [previewLoading, setPreviewLoading] = useState(false)
  const [previewError, setPreviewError] = useState<string | null>(null)

  const [report, setReport] = useState<SalesDayEnd | null>(null)
  const [closing, setClosing] = useState(false)

  useEffect(() => {
    usersApi
      .list({ pageSize: 200 })
      .then((res) => {
        setCashiers(res.items)
        setCashierUserId((prev) => prev ?? res.items[0]?.userId ?? null)
      })
      .catch(() => {})
  }, [])

  function loadPreview() {
    if (!cashierUserId) return
    setReport(null)
    setPreviewError(null)
    setPreviewLoading(true)
    salesDayEndApi
      .preview(cashierUserId, businessDate)
      .then(setPreview)
      .catch((err) => setPreviewError(errorMessage(err)))
      .finally(() => setPreviewLoading(false))
  }

  useEffect(() => {
    loadPreview()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [cashierUserId, businessDate])

  async function handleClose() {
    if (!cashierUserId) return
    setClosing(true)
    try {
      const result = await salesDayEndApi.close({ cashierUserId, businessDate })
      setReport(result)
      toast.success("Day closed", `${result.docNo} — ${result.slipCount} slip(s), ${result.bundleCount} bundle(s), ${result.grandTotal.toFixed(2)} total.`)
      loadPreview()
    } catch (err) {
      toast.error("Could not close the day", errorMessage(err))
    } finally {
      setClosing(false)
    }
  }

  const cashierName = cashiers.find((c) => c.userId === cashierUserId)?.displayName

  return (
    <div className="flex flex-col gap-6">
      <div className="flex items-center gap-3">
        <Link href="/dashboard/sales" className={cn(buttonVariants({ variant: "outline", size: "icon" }))}>
          <ArrowLeft className="size-4" />
        </Link>
        <div>
          <h1 className="text-2xl font-bold text-foreground">Day End</h1>
          <p className="text-base text-muted-foreground">
            Close a cashier's business day — locks their posted sales slips and bundle sales, and posts one consolidated journal entry to the ledger.
          </p>
        </div>
      </div>

      <div className="grid grid-cols-1 gap-4 rounded-2xl border border-border bg-card p-5 shadow-[var(--shadow-panel)] sm:grid-cols-3">
        <div className="flex flex-col gap-2">
          <Label className="text-base">Cashier</Label>
          <Select<number | null> value={cashierUserId} onValueChange={setCashierUserId}>
            <SelectTrigger className="h-12! w-full text-base">
              <SelectValue placeholder="Select cashier" />
            </SelectTrigger>
            <SelectContent>
              {cashiers.map((c) => (
                <SelectItem key={c.userId} value={c.userId} className="text-base">
                  {c.displayName}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
        <div className="flex flex-col gap-2">
          <Label className="text-base">Business date</Label>
          <Input
            type="date"
            value={businessDate}
            max={todayIso()}
            onChange={(e) => setBusinessDate(e.target.value)}
            className="h-12 text-base"
          />
        </div>
      </div>

      {previewLoading && <Skeleton className="h-40 w-full" />}

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

      {!previewLoading && preview && !report && (
        <div className="flex flex-col gap-4 rounded-2xl border border-border bg-card p-5 shadow-[var(--shadow-panel)]">
          {preview.alreadyClosed ? (
            <div className="flex items-start gap-3 rounded-lg border border-success/30 bg-success/5 p-4 text-base text-success">
              <CheckCircle2 className="size-5 shrink-0" />
              <div>
                <p className="font-semibold">{cashierName ?? `Cashier ${cashierUserId}`} already closed {businessDate}.</p>
                <p className="text-sm text-success/80">{preview.slipCount} slip(s), {preview.bundleCount} bundle(s), {preview.grandTotal.toFixed(2)} total.</p>
              </div>
            </div>
          ) : preview.draftSlipsBlockingClose.length > 0 || preview.draftBundleSalesBlockingClose.length > 0 ? (
            <div className="flex items-start gap-3 rounded-lg border border-warning/30 bg-warning/5 p-4 text-base text-warning">
              <AlertTriangle className="size-5 shrink-0" />
              <div className="flex flex-col gap-2">
                <p className="font-semibold">Still Draft — post or cancel these before closing.</p>
                <ul className="list-inside list-disc text-sm">
                  {preview.draftSlipsBlockingClose.map((s) => (
                    <li key={`slip-${s.salesSlipId}`}>
                      <Link href={`/dashboard/sales/slips/${s.salesSlipId}`} className="underline">{s.slipNo}</Link> — {s.grandTotal.toFixed(2)}
                    </li>
                  ))}
                  {preview.draftBundleSalesBlockingClose.map((b) => (
                    <li key={`bundle-${b.bundleSaleId}`}>
                      <Link href={`/dashboard/sales/bundles/${b.bundleSaleId}`} className="underline">{b.bundleNo}</Link> — {b.grandTotal.toFixed(2)}
                    </li>
                  ))}
                </ul>
              </div>
            </div>
          ) : (
            <p className="text-base text-muted-foreground">
              {preview.slipCount === 0 && preview.bundleCount === 0
                ? "No sales slips or bundle sales for this cashier on this date."
                : `${preview.slipCount} posted slip(s), ${preview.bundleCount} posted bundle sale(s) ready to close.`}
            </p>
          )}

          <div className="grid grid-cols-2 gap-3 sm:grid-cols-4">
            <Stat label="Subtotal" value={preview.subtotal} />
            <Stat label="Discount" value={preview.discountTotal} />
            <Stat label="Tax" value={preview.taxTotal} />
            <Stat label="Grand total" value={preview.grandTotal} emphasize />
          </div>

          {!preview.alreadyClosed && (
            <div className="flex justify-end">
              <Button
                size="lg"
                onClick={handleClose}
                disabled={closing || preview.draftSlipsBlockingClose.length > 0 || preview.draftBundleSalesBlockingClose.length > 0 || !cashierUserId}
              >
                <Lock className="size-5" />
                {closing ? "Closing…" : "Close day"}
              </Button>
            </div>
          )}

          {preview.alreadyClosed && (
            <div className="flex justify-end">
              <Button size="lg" variant="outline" onClick={handleClose} disabled={closing}>
                <ReceiptText className="size-5" />
                {closing ? "Loading…" : "View full report"}
              </Button>
            </div>
          )}
        </div>
      )}

      {report && (
        <div className="flex flex-col gap-4 rounded-2xl border border-border bg-card p-5 shadow-[var(--shadow-panel)]">
          <div className="flex flex-col gap-1 border-b border-border pb-4 sm:flex-row sm:items-center sm:justify-between">
            <div>
              <h2 className="text-lg font-semibold text-foreground">{report.docNo}</h2>
              <p className="text-sm text-muted-foreground">
                {cashierName ?? `Cashier ${report.cashierUserId}`} — {report.businessDate} — closed {new Date(report.closedAt).toLocaleString()}
              </p>
            </div>
            {report.glJournalNo && (
              <div className="text-sm text-muted-foreground">
                GL journal <span className="font-medium text-foreground">{report.glJournalNo}</span> posted {report.glPostedAt ? new Date(report.glPostedAt).toLocaleString() : ""}
              </div>
            )}
          </div>

          <div className="grid grid-cols-2 gap-3 sm:grid-cols-6">
            <Stat label="Slips" value={report.slipCount} isCount />
            <Stat label="Bundles" value={report.bundleCount} isCount />
            <Stat label="Subtotal" value={report.subtotal} />
            <Stat label="Discount" value={report.discountTotal} />
            <Stat label="Tax" value={report.taxTotal} />
            <Stat label="Grand total" value={report.grandTotal} emphasize />
          </div>

          <div className="flex flex-col gap-2">
            <h3 className="text-sm font-semibold text-foreground">Item breakdown</h3>
            <div className="overflow-x-auto">
              <Table className="text-sm">
                <TableHeader>
                  <TableRow>
                    <TableHead className="h-10 px-3 text-sm">Item</TableHead>
                    <TableHead className="h-10 px-3 text-right text-sm">Qty</TableHead>
                    <TableHead className="h-10 px-3 text-right text-sm">Revenue</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {report.itemBreakdown.length === 0 ? (
                    <TableRow>
                      <TableCell colSpan={3} className="px-3 py-6 text-center text-sm text-muted-foreground">No lines.</TableCell>
                    </TableRow>
                  ) : (
                    report.itemBreakdown.map((line) => (
                      <TableRow key={line.itemId}>
                        <TableCell className="px-3 py-2.5">{line.sku} — {line.name}</TableCell>
                        <TableCell className="px-3 py-2.5 text-right font-mono tabular-nums">{line.qty}</TableCell>
                        <TableCell className="px-3 py-2.5 text-right font-mono tabular-nums">{line.revenue.toFixed(2)}</TableCell>
                      </TableRow>
                    ))
                  )}
                </TableBody>
              </Table>
            </div>
          </div>

          {report.slipNumbers.length > 0 && (
            <div className="flex flex-col gap-2">
              <h3 className="text-sm font-semibold text-foreground">Slips included</h3>
              <p className="text-sm text-muted-foreground">{report.slipNumbers.join(", ")}</p>
            </div>
          )}

          {report.bundleNumbers.length > 0 && (
            <div className="flex flex-col gap-2">
              <h3 className="text-sm font-semibold text-foreground">Bundle sales included</h3>
              <p className="text-sm text-muted-foreground">{report.bundleNumbers.join(", ")}</p>
            </div>
          )}
        </div>
      )}
    </div>
  )
}

function Stat({ label, value, emphasize, isCount }: { label: string; value: number; emphasize?: boolean; isCount?: boolean }) {
  return (
    <div className="flex flex-col gap-1 rounded-xl border border-border bg-muted/30 p-3">
      <span className="text-xs text-muted-foreground">{label}</span>
      <span className={cn("font-mono tabular-nums", emphasize ? "text-lg font-bold text-foreground" : "text-base font-semibold text-foreground")}>
        {isCount ? value : value.toFixed(2)}
      </span>
    </div>
  )
}
