import * as React from "react";
import { useState } from "react";
import { Pencil, Plus, Trash2 } from "lucide-react";
import { cn } from "@/lib/utils";
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion";
import { Button } from "@/components/ui/button";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { LoanOptionGroup } from "@/components/ui/loan-option-group";
import {
  CurrencyInputWithSlider,
  OwnershipSplit,
  type OwnershipOwner,
} from "@/components/ui/form-primitives";
import { FREQUENCY_OPTIONS } from "@/lib/loan-constants";
import { formatCurrency } from "@/lib/format-currency";

// ─── Types ──────────────────────────────────────────────────────────────────

export type DebtOwner = OwnershipOwner;

export type DebtItem = {
  id: string;
  /** Summary label shown in the collapsed row. */
  description: string;
  currentOwing: number;
  monthlyRepayment?: number;
  interestRate?: number;
  subLabel?: string;
  // ── Debt detail fields (edited via the inline form) ──
  originalLoanAmount?: number;
  loanRepaymentAmount?: number;
  repaymentFrequency?: "monthly" | "weekly";
  detail?: string;
  lenderName?: string;
  accountName?: string;
  bsb?: string;
  accountNumber?: string;
  owners?: DebtOwner[];
};

export type DebtGroup = {
  debtType: string;
  label: string;
  items: DebtItem[];
};

export type DebtAccordionProps = {
  groups: DebtGroup[];
  openGroups?: string[];
  onToggleGroup?: (debtType: string) => void;
  /** Create/update an item. `item.id === ""` means a newly-added item. */
  onSaveItem?: (debtType: string, item: DebtItem) => void;
  onDeleteItem?: (debtType: string, itemId: string) => void;
  /** Applicants used to seed the liability-ownership split on a new item. */
  owners?: DebtOwner[];
  /** Accessible label for the accordion landmark region. */
  "aria-label"?: string;
  className?: string;
};

const NEW_ITEM_ID = "__new__";

function blankDebtItem(owners: DebtOwner[]): DebtItem {
  return {
    id: "",
    description: "",
    currentOwing: 0,
    originalLoanAmount: 0,
    loanRepaymentAmount: 0,
    repaymentFrequency: "monthly",
    detail: "",
    lenderName: "",
    accountName: "",
    bsb: "",
    accountNumber: "",
    owners,
  };
}

// ─── Component ──────────────────────────────────────────────────────────────

export function DebtAccordion({
  groups,
  openGroups,
  onToggleGroup,
  onSaveItem,
  onDeleteItem,
  owners = [{ id: "main", name: "Main Applicant", share: 100 }],
  "aria-label": ariaLabel = "Debt list",
  className,
}: DebtAccordionProps) {
  const [editing, setEditing] = useState<{
    debtType: string;
    itemId: string;
  } | null>(null);
  const [draft, setDraft] = useState<DebtItem | null>(null);

  const totalOwing = groups
    .flatMap((g) => g.items)
    .reduce((sum, item) => sum + item.currentOwing, 0);

  const startAdd = (debtType: string) => {
    setDraft(blankDebtItem(owners));
    setEditing({ debtType, itemId: NEW_ITEM_ID });
  };
  const startEdit = (debtType: string, item: DebtItem) => {
    setDraft({ ...item, owners: item.owners ?? owners });
    setEditing({ debtType, itemId: item.id });
  };
  const cancel = () => {
    setEditing(null);
    setDraft(null);
  };
  const save = (debtType: string, item: DebtItem) => {
    onSaveItem?.(debtType, item);
    cancel();
  };

  return (
    <div className={cn("flex flex-col gap-4 font-sans", className)}>
      <div className="flex items-center justify-between pb-2">
        <h3 className="text-h3 text-foreground">Debts</h3>
        <span className="text-label-medium text-foreground">
          Total owing: {formatCurrency(totalOwing)}
        </span>
      </div>

      <Accordion
        multiple
        aria-label={ariaLabel}
        value={openGroups}
        onValueChange={(vals) => {
          const prev = new Set(openGroups ?? []);
          const next = new Set(vals as string[]);
          for (const v of next) {
            if (!prev.has(v)) onToggleGroup?.(v);
          }
          for (const v of prev) {
            if (!next.has(v)) onToggleGroup?.(v);
          }
        }}
      >
        {groups.map((group) => {
          const isAdding =
            editing?.debtType === group.debtType &&
            editing.itemId === NEW_ITEM_ID;
          // One form element per group — at most one is shown at a time
          // (editing an existing item, or the new draft).
          const form =
            editing?.debtType === group.debtType && draft ? (
              <DebtItemForm
                debtType={group.debtType}
                initial={draft}
                onSave={(updated) => save(group.debtType, updated)}
                onCancel={cancel}
              />
            ) : null;
          return (
            <AccordionItem key={group.debtType} value={group.debtType}>
              <AccordionTrigger>
                <div className="flex w-full items-center justify-between pr-2">
                  <span>{group.label}</span>
                  <span className="text-caption text-muted-foreground">
                    {group.items.length}{" "}
                    {group.items.length === 1 ? "item" : "items"} ·{" "}
                    {formatCurrency(
                      group.items.reduce((s, i) => s + i.currentOwing, 0),
                    )}{" "}
                    owing
                  </span>
                </div>
              </AccordionTrigger>
              <AccordionContent>
                <div className="flex flex-col gap-2 pb-2">
                  {group.items.length === 0 && !isAdding ? (
                    <p className="text-caption text-muted-foreground">
                      No {group.label.toLowerCase()} added yet.
                    </p>
                  ) : (
                    group.items.map((item) =>
                      editing?.debtType === group.debtType &&
                      editing.itemId === item.id &&
                      form ? (
                        React.cloneElement(form, { key: item.id })
                      ) : (
                        <DebtItemRow
                          key={item.id}
                          item={item}
                          onEdit={() => startEdit(group.debtType, item)}
                          onDelete={() =>
                            onDeleteItem?.(group.debtType, item.id)
                          }
                        />
                      ),
                    )
                  )}

                  {isAdding && form}

                  {!isAdding && (
                    <Button
                      variant="secondary"
                      size="sm"
                      className="mt-1 self-start text-body-small"
                      onClick={() => startAdd(group.debtType)}
                    >
                      <Plus className="size-4" />
                      Add {group.label}
                    </Button>
                  )}
                </div>
              </AccordionContent>
            </AccordionItem>
          );
        })}
      </Accordion>
    </div>
  );
}

// ─── Collapsed summary row ──────────────────────────────────────────────────

function DebtItemRow({
  item,
  onEdit,
  onDelete,
}: {
  item: DebtItem;
  onEdit?: () => void;
  onDelete?: () => void;
}) {
  const repayment = item.loanRepaymentAmount ?? item.monthlyRepayment;
  return (
    <div className="flex items-start justify-between border border-border p-3">
      <div className="flex flex-col gap-0.5">
        <span className="text-label-medium text-foreground">
          {item.description || "Untitled debt"}
        </span>
        {item.subLabel && (
          <span className="text-caption text-muted-foreground">
            {item.subLabel}
          </span>
        )}
        <div className="flex flex-wrap gap-3">
          <span className="text-body-small text-foreground">
            Owing: {formatCurrency(item.currentOwing)}
          </span>
          {repayment != null && repayment > 0 && (
            <span className="text-caption text-muted-foreground">
              Repayment: {formatCurrency(repayment)}/
              {item.repaymentFrequency === "weekly" ? "wk" : "mo"}
            </span>
          )}
          {item.interestRate != null && (
            <span className="text-caption text-muted-foreground">
              Rate: {item.interestRate}%
            </span>
          )}
        </div>
      </div>
      <div className="flex shrink-0 items-center gap-1">
        <Button
          variant="ghost"
          size="icon-sm"
          aria-label={`Edit ${item.description}`}
          onClick={onEdit}
        >
          <Pencil className="size-4" />
        </Button>
        <Button
          variant="ghost"
          size="icon-sm"
          className="text-destructive hover:text-destructive"
          aria-label={`Delete ${item.description}`}
          onClick={onDelete}
        >
          <Trash2 className="size-4" />
        </Button>
      </div>
    </div>
  );
}

// ─── Inline add / edit form ─────────────────────────────────────────────────

function DebtItemForm({
  debtType,
  initial,
  onSave,
  onCancel,
}: {
  debtType: string;
  initial: DebtItem;
  onSave: (item: DebtItem) => void;
  onCancel: () => void;
}) {
  const [item, setItem] = useState<DebtItem>(initial);
  const set = (patch: Partial<DebtItem>) =>
    setItem((prev) => ({ ...prev, ...patch }));

  const isCreditCard = debtType === "credit-card";

  const canSave =
    item.currentOwing > 0 &&
    (item.originalLoanAmount ?? 0) > 0 &&
    (item.loanRepaymentAmount ?? 0) > 0;

  const handleSave = () => {
    const description = isCreditCard
      ? item.lenderName || item.description
      : item.detail || item.description;
    onSave({
      ...item,
      description: description || "Untitled debt",
      monthlyRepayment: item.loanRepaymentAmount,
    });
  };

  return (
    <div className="flex flex-col gap-5 border border-border p-4">
      <Field>
        <FieldLabel>How much is owing?</FieldLabel>
        <CurrencyInputWithSlider
          value={item.currentOwing}
          min={0}
          max={3_000_000}
          step={10_000}
          onValueChange={(n) => set({ currentOwing: n })}
        />
      </Field>

      <Field>
        <FieldLabel>Original loan amount</FieldLabel>
        <CurrencyInputWithSlider
          value={item.originalLoanAmount ?? 0}
          min={0}
          max={3_000_000}
          step={10_000}
          onValueChange={(n) => set({ originalLoanAmount: n })}
        />
      </Field>

      <Field>
        <FieldLabel>How much are your loan repayments?</FieldLabel>
        <div className="flex flex-col gap-2">
          <CurrencyInputWithSlider
            value={item.loanRepaymentAmount ?? 0}
            min={0}
            max={20_000}
            step={100}
            onValueChange={(n) => set({ loanRepaymentAmount: n })}
          />
          <LoanOptionGroup
            options={FREQUENCY_OPTIONS}
            value={item.repaymentFrequency ?? "monthly"}
            onChange={(v) =>
              set({ repaymentFrequency: v as DebtItem["repaymentFrequency"] })
            }
          />
        </div>
      </Field>

      {isCreditCard ? (
        <>
          <Field>
            <FieldLabel>Name of lender</FieldLabel>
            <Input
              value={item.lenderName ?? ""}
              placeholder="e.g. ANZ"
              onChange={(e) => set({ lenderName: e.target.value })}
            />
          </Field>
          <Field>
            <FieldLabel>Account Name</FieldLabel>
            <Input
              value={item.accountName ?? ""}
              onChange={(e) => set({ accountName: e.target.value })}
            />
          </Field>
          <div className="grid grid-cols-2 gap-4">
            <Field>
              <FieldLabel>BSB</FieldLabel>
              <Input
                value={item.bsb ?? ""}
                inputMode="numeric"
                placeholder="000-000"
                onChange={(e) => set({ bsb: e.target.value })}
              />
            </Field>
            <Field>
              <FieldLabel>Account Number</FieldLabel>
              <Input
                value={item.accountNumber ?? ""}
                inputMode="numeric"
                onChange={(e) => set({ accountNumber: e.target.value })}
              />
            </Field>
          </div>
        </>
      ) : (
        <Field>
          <FieldLabel>Details</FieldLabel>
          <Input
            value={item.detail ?? ""}
            placeholder="e.g. lender or account name"
            onChange={(e) => set({ detail: e.target.value })}
          />
        </Field>
      )}

      {item.owners && item.owners.length > 1 && (
        <Field>
          <FieldLabel>Who owns the liability?</FieldLabel>
          <OwnershipSplit
            owners={item.owners}
            onOwnersChange={(ow) => set({ owners: ow })}
          />
        </Field>
      )}

      <div className="flex items-center gap-2">
        <Button size="sm" disabled={!canSave} onClick={handleSave}>
          Save &amp; Collapse
        </Button>
        <Button size="sm" variant="ghost" onClick={onCancel}>
          Cancel
        </Button>
      </div>
    </div>
  );
}
