"use client";

import { useState } from "react";
import { useQuery, useMutation } from "@tanstack/react-query";
import { toast } from "sonner";
import { Plus, Trash2, Eye } from "lucide-react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/Card";
import { Button } from "@/components/ui/Button";
import { Input } from "@/components/ui/Input";
import { Table, TableHead, TableBody, TableRow, Th, Td, EmptyState } from "@/components/ui/Table";
import { Modal } from "@/components/ui/Modal";
import { AccountingNav } from "@/components/accounting/AccountingNav";
import { formatCurrency } from "@/lib/utils";
import api from "@/lib/api";
import type { Account, JournalEntry, JournalEntryLine } from "@/types/index";

function formatDate(iso: string) {
  return new Date(iso).toLocaleDateString("en-PH", { year: "numeric", month: "short", day: "numeric" });
}

interface LineFormItem {
  accountId: string;
  debit: string;
  credit: string;
  memo: string;
}

const emptyLine = (): LineFormItem => ({ accountId: "", debit: "", credit: "", memo: "" });

export default function JournalEntriesPage() {
  const [showNew, setShowNew] = useState(false);
  const [viewEntry, setViewEntry] = useState<JournalEntry | null>(null);
  const [form, setForm] = useState({ date: "", description: "", reference: "" });
  const [lines, setLines] = useState<LineFormItem[]>([emptyLine(), emptyLine()]);

  const { data: entries = [], isLoading, refetch } = useQuery<JournalEntry[]>({
    queryKey: ["journal-entries"],
    queryFn: async () => {
      const res = await api.get<JournalEntry[] | { data: JournalEntry[] }>("/api/v1/journal-entries");
      const d = res.data;
      return Array.isArray(d) ? d : (d as { data: JournalEntry[] }).data ?? [];
    },
  });

  const { data: accounts = [] } = useQuery<Account[]>({
    queryKey: ["accounts"],
    queryFn: async () => {
      const res = await api.get<Account[] | { data: Account[] }>("/api/v1/accounts");
      const d = res.data;
      return (Array.isArray(d) ? d : (d as { data: Account[] }).data ?? []).filter((a) => a.isActive);
    },
  });

  const totalDebit = lines.reduce((s, l) => s + (parseFloat(l.debit) || 0), 0);
  const totalCredit = lines.reduce((s, l) => s + (parseFloat(l.credit) || 0), 0);
  const isBalanced = Math.abs(totalDebit - totalCredit) < 0.01 && totalDebit > 0;

  const createMutation = useMutation({
    mutationFn: async () => {
      const payload = {
        date: form.date,
        description: form.description,
        reference: form.reference || undefined,
        lines: lines
          .filter((l) => l.accountId)
          .map((l) => ({
            accountId: l.accountId,
            debit: parseFloat(l.debit) || 0,
            credit: parseFloat(l.credit) || 0,
            memo: l.memo || undefined,
          })),
      };
      await api.post("/api/v1/journal-entries", payload);
    },
    onSuccess: () => {
      toast.success("Journal entry created");
      setShowNew(false);
      setForm({ date: "", description: "", reference: "" });
      setLines([emptyLine(), emptyLine()]);
      refetch();
    },
    onError: () => toast.error("Failed to create journal entry"),
  });

  function setLine(i: number, field: keyof LineFormItem, value: string) {
    setLines((prev) => prev.map((l, idx) => idx === i ? { ...l, [field]: value } : l));
  }

  function addLine() {
    setLines((prev) => [...prev, emptyLine()]);
  }

  function removeLine(i: number) {
    if (lines.length <= 2) return;
    setLines((prev) => prev.filter((_, idx) => idx !== i));
  }

  const entryTotalDebit = (e: JournalEntry) =>
    e.lines?.reduce((s, l) => s + Number(l.debit), 0) ?? e.totalDebit ?? 0;

  return (
    <div className="space-y-4">
      <div className="flex items-start justify-between">
        <div>
          <h1 className="text-2xl font-bold text-gray-900">Accounting</h1>
          <p className="text-sm text-gray-500">Journal entries and double-entry bookkeeping</p>
        </div>
        <Button size="sm" onClick={() => setShowNew(true)}>+ New Entry</Button>
      </div>

      <AccountingNav />

      <Card>
        <CardHeader>
          <CardTitle>Journal Entries ({entries.length})</CardTitle>
        </CardHeader>
        <CardContent className="p-0">
          <Table>
            <TableHead>
              <TableRow>
                <Th>Date</Th>
                <Th>Reference</Th>
                <Th>Description</Th>
                <Th>Source</Th>
                <Th>Lines</Th>
                <Th>Total Debit</Th>
                <Th></Th>
              </TableRow>
            </TableHead>
            <TableBody>
              {isLoading ? (
                Array.from({ length: 4 }).map((_, i) => (
                  <TableRow key={i}>
                    {[1,2,3,4,5,6,7].map((j) => (
                      <Td key={j}><div className="h-4 w-20 animate-pulse bg-gray-100 rounded" /></Td>
                    ))}
                  </TableRow>
                ))
              ) : entries.length === 0 ? (
                <EmptyState message="No journal entries yet" />
              ) : (
                entries.map((e) => (
                  <TableRow key={e.id}>
                    <Td className="text-sm">{formatDate(e.date)}</Td>
                    <Td className="font-mono text-xs text-gray-500">{e.reference ?? "—"}</Td>
                    <Td className="font-medium max-w-xs truncate">{e.description}</Td>
                    <Td className="text-xs text-gray-500">{e.sourceType ?? "MANUAL"}</Td>
                    <Td className="text-sm">{e.lines?.length ?? 0}</Td>
                    <Td className="font-semibold text-sm">{formatCurrency(entryTotalDebit(e))}</Td>
                    <Td>
                      <Button size="sm" variant="ghost" onClick={() => setViewEntry(e)}>
                        <Eye className="h-4 w-4" />
                      </Button>
                    </Td>
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        </CardContent>
      </Card>

      {/* New Entry Modal */}
      <Modal isOpen={showNew} onClose={() => setShowNew(false)} title="New Journal Entry" className="max-w-3xl">
        <form onSubmit={(e) => { e.preventDefault(); createMutation.mutate(); }} className="space-y-4">
          <div className="grid grid-cols-3 gap-3">
            <Input
              label="Date *"
              type="date"
              value={form.date}
              onChange={(e) => setForm((f) => ({ ...f, date: e.target.value }))}
            />
            <Input
              label="Reference"
              value={form.reference}
              onChange={(e) => setForm((f) => ({ ...f, reference: e.target.value }))}
              placeholder="e.g. JE-001"
            />
            <div className="col-span-1" />
          </div>
          <Input
            label="Description *"
            value={form.description}
            onChange={(e) => setForm((f) => ({ ...f, description: e.target.value }))}
            placeholder="Describe this journal entry"
          />

          {/* Lines */}
          <div>
            <div className="flex items-center justify-between mb-2">
              <p className="text-sm font-medium text-gray-700">Line Items</p>
              <Button type="button" size="sm" variant="outline" onClick={addLine}>
                <Plus className="h-3 w-3 mr-1" /> Add Line
              </Button>
            </div>
            <div className="border rounded-lg overflow-hidden">
              <table className="w-full text-sm">
                <thead className="bg-gray-50 border-b">
                  <tr>
                    <th className="text-left px-3 py-2 text-xs font-medium text-gray-500 w-1/3">Account</th>
                    <th className="text-left px-3 py-2 text-xs font-medium text-gray-500 w-24">Debit</th>
                    <th className="text-left px-3 py-2 text-xs font-medium text-gray-500 w-24">Credit</th>
                    <th className="text-left px-3 py-2 text-xs font-medium text-gray-500">Memo</th>
                    <th className="w-8" />
                  </tr>
                </thead>
                <tbody>
                  {lines.map((line, i) => (
                    <tr key={i} className="border-b last:border-0">
                      <td className="px-3 py-1.5">
                        <select
                          className="w-full rounded border-0 bg-transparent text-sm focus:outline-none focus:ring-1 focus:ring-blue-500 rounded"
                          value={line.accountId}
                          onChange={(e) => setLine(i, "accountId", e.target.value)}
                        >
                          <option value="">Select account</option>
                          {accounts.map((a) => (
                            <option key={a.id} value={a.id}>{a.code} — {a.name}</option>
                          ))}
                        </select>
                      </td>
                      <td className="px-3 py-1.5">
                        <input
                          type="number"
                          min="0"
                          step="0.01"
                          className="w-full rounded border-0 bg-transparent text-sm focus:outline-none focus:ring-1 focus:ring-blue-500 rounded"
                          value={line.debit}
                          onChange={(e) => setLine(i, "debit", e.target.value)}
                          placeholder="0.00"
                        />
                      </td>
                      <td className="px-3 py-1.5">
                        <input
                          type="number"
                          min="0"
                          step="0.01"
                          className="w-full rounded border-0 bg-transparent text-sm focus:outline-none focus:ring-1 focus:ring-blue-500 rounded"
                          value={line.credit}
                          onChange={(e) => setLine(i, "credit", e.target.value)}
                          placeholder="0.00"
                        />
                      </td>
                      <td className="px-3 py-1.5">
                        <input
                          type="text"
                          className="w-full rounded border-0 bg-transparent text-sm focus:outline-none"
                          value={line.memo}
                          onChange={(e) => setLine(i, "memo", e.target.value)}
                          placeholder="Optional"
                        />
                      </td>
                      <td className="px-2 py-1.5">
                        <button
                          type="button"
                          onClick={() => removeLine(i)}
                          disabled={lines.length <= 2}
                          className="text-gray-300 hover:text-red-400 disabled:opacity-20"
                        >
                          <Trash2 className="h-4 w-4" />
                        </button>
                      </td>
                    </tr>
                  ))}
                </tbody>
                <tfoot className="bg-gray-50 border-t">
                  <tr>
                    <td className="px-3 py-2 text-xs font-medium text-gray-500">Totals</td>
                    <td className="px-3 py-2 text-sm font-bold text-gray-800">{formatCurrency(totalDebit)}</td>
                    <td className="px-3 py-2 text-sm font-bold text-gray-800">{formatCurrency(totalCredit)}</td>
                    <td colSpan={2} className="px-3 py-2">
                      {totalDebit > 0 && (
                        <span className={`text-xs font-medium ${isBalanced ? "text-green-600" : "text-red-500"}`}>
                          {isBalanced ? "✓ Balanced" : `Off by ${formatCurrency(Math.abs(totalDebit - totalCredit))}`}
                        </span>
                      )}
                    </td>
                  </tr>
                </tfoot>
              </table>
            </div>
          </div>

          <div className="flex justify-end gap-2 pt-1">
            <Button type="button" variant="outline" size="sm" onClick={() => setShowNew(false)}>Cancel</Button>
            <Button
              type="submit"
              size="sm"
              isLoading={createMutation.isPending}
              disabled={!form.date || !form.description || !isBalanced}
            >
              Create Entry
            </Button>
          </div>
        </form>
      </Modal>

      {/* View Entry Modal */}
      {viewEntry && (
        <Modal isOpen={!!viewEntry} onClose={() => setViewEntry(null)} title="Journal Entry" className="max-w-2xl">
          <div className="space-y-4">
            <div className="grid grid-cols-3 gap-4 text-sm">
              <div>
                <p className="text-gray-500">Date</p>
                <p className="font-medium">{formatDate(viewEntry.date)}</p>
              </div>
              <div>
                <p className="text-gray-500">Reference</p>
                <p className="font-medium font-mono">{viewEntry.reference ?? "—"}</p>
              </div>
              <div>
                <p className="text-gray-500">Source</p>
                <p className="font-medium">{viewEntry.sourceType ?? "MANUAL"}</p>
              </div>
            </div>
            <div>
              <p className="text-gray-500 text-sm">Description</p>
              <p className="font-medium">{viewEntry.description}</p>
            </div>
            <table className="w-full text-sm border rounded-lg overflow-hidden">
              <thead className="bg-gray-50">
                <tr>
                  <th className="text-left px-3 py-2 text-xs font-medium text-gray-500">Account</th>
                  <th className="text-right px-3 py-2 text-xs font-medium text-gray-500">Debit</th>
                  <th className="text-right px-3 py-2 text-xs font-medium text-gray-500">Credit</th>
                  <th className="text-left px-3 py-2 text-xs font-medium text-gray-500">Memo</th>
                </tr>
              </thead>
              <tbody>
                {viewEntry.lines?.map((l, i) => (
                  <tr key={i} className="border-t">
                    <td className="px-3 py-2">{l.account ? `${l.account.code} — ${l.account.name}` : l.accountId}</td>
                    <td className="px-3 py-2 text-right font-mono">{Number(l.debit) > 0 ? formatCurrency(Number(l.debit)) : "—"}</td>
                    <td className="px-3 py-2 text-right font-mono">{Number(l.credit) > 0 ? formatCurrency(Number(l.credit)) : "—"}</td>
                    <td className="px-3 py-2 text-gray-500">{l.memo ?? ""}</td>
                  </tr>
                ))}
              </tbody>
              <tfoot className="bg-gray-50 border-t">
                <tr>
                  <td className="px-3 py-2 text-xs font-medium text-gray-500">Total</td>
                  <td className="px-3 py-2 text-right font-bold text-sm">{formatCurrency(entryTotalDebit(viewEntry))}</td>
                  <td className="px-3 py-2 text-right font-bold text-sm">{formatCurrency(entryTotalDebit(viewEntry))}</td>
                  <td />
                </tr>
              </tfoot>
            </table>
            <div className="flex justify-end">
              <Button variant="outline" size="sm" onClick={() => setViewEntry(null)}>Close</Button>
            </div>
          </div>
        </Modal>
      )}
    </div>
  );
}
