import * as React from "react";
import { useCallback, useMemo, useState } from "react";
import { cn } from "@/lib/utils";
import { formatCurrency } from "@/lib/format-currency";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { ExpenseBarChart } from "@/components/ui/expense-bar-chart";
import type { ExpenseBarChartData } from "@/components/ui/expense-bar-chart";
import {
  ExpenseDetailItem,
  SharedEqualToggle,
} from "@/components/ui/expense-detail-item";
import type { ExpenseType } from "@/components/ui/expense-detail-item";
import { RotateCcw } from "lucide-react";
import {
  Tooltip,
  TooltipContent,
  TooltipTrigger,
} from "@/components/ui/tooltip";

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

export type { ExpenseType };

export type ExpenseItem = {
  id: string;
  /** Expense category type — drives the icon in ExpenseDetailItem */
  type: ExpenseType | string;
  /** Display label */
  label: string;
  /** Optional tooltip description */
  description?: string;
  /** Current monthly expense amount */
  amount: number;
  /** Whether this expense is shared between applicants */
  isShared?: boolean;
  /** Percentage attributed to the main applicant (0–100) */
  sharedPercent?: number;
};

export type ExpenseItemUpdates = Pick<
  ExpenseItem,
  "type" | "label" | "amount" | "isShared" | "sharedPercent"
>;

export type ExpenseWorkDetailsProps = {
  /** Rendered as "{applicantName}'s Expenses" in the heading */
  applicantName: string;
  /** Total from Open Banking — shown in the summary card above the chart */
  totalExpenses?: number;
  /** Monthly expense data for the ExpenseBarChart */
  expenseData?: ExpenseBarChartData | null;
  /** Expense items shown in the Expenses Details section */
  items: ExpenseItem[];
  /** When true, shows "Expense shared equally" toggle on each item and in the section header */
  hasCoApplicant?: boolean;
  onItemChange?: (id: string, updates: Partial<ExpenseItemUpdates>) => void;
  /** Called when the global "shared equally" toggle is changed — receives the new value */
  onAllSharedChange?: (shared: boolean) => void;
  /** "Add More +" — appends an empty row; the applicant picks the category in the row. */
  onAddItem?: () => void;
  /** Re-seed the expenses from the connected bank data. */
  onResyncFromBank?: () => void;
  /** "Add More Account +" button in the summary card */
  onConnectMore?: () => void;
  className?: string;
};

// ─── Constants ────────────────────────────────────────────────────────────────

export const EXPENSE_CATEGORIES: Array<{ type: ExpenseType; label: string }> = [
  { type: "housing", label: "Housing" },
  { type: "transport", label: "Transport" },
  { type: "groceries", label: "Groceries" },
  { type: "childcare", label: "Childcare" },
  { type: "insurance", label: "Insurance" },
  { type: "entertainment", label: "Recreation & Entertainment" },
  { type: "utilities", label: "Utilities" },
  { type: "other", label: "Other" },
];

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

/**
 * ExpenseWorkDetails — Expenses section of the loan application wizard.
 *
 * Shows:
 * 1. "{applicantName}'s Expenses" heading
 * 2. Open Banking summary card — total + "Add More Account +" + bare bar chart
 * 3. Expenses Details — list of ExpenseDetailItems with icon, progress bar,
 *    per-item shared toggle (when hasCoApplicant), and currency+slider input
 * 4. "Add More +" dropdown to select a new expense category
 *
 * Shared controls are only shown when hasCoApplicant=true (joint application).
 *
 * Figma: WealthX-Backoffice---Mobile-App — node 19308:53437
 */
export function ExpenseWorkDetails({
  applicantName,
  totalExpenses,
  expenseData,
  items,
  hasCoApplicant = false,
  onItemChange,
  onAllSharedChange,
  onAddItem,
  onResyncFromBank,
  onConnectMore,
  className,
}: ExpenseWorkDetailsProps) {
  const [globalShared, setGlobalShared] = useState(false);
  const itemsTotal = useMemo(
    () => items.reduce((sum, i) => sum + i.amount, 0),
    [items],
  );

  // A category can only be used once, so a new row only offers what is left.
  const remainingCategories = useMemo(() => {
    const used = new Set(items.map((i) => i.type).filter(Boolean));
    return EXPENSE_CATEGORIES.filter((c) => !used.has(c.type));
  }, [items]);

  const handleGlobalSharedChange = useCallback(
    (next: boolean) => {
      setGlobalShared(next);
      items.forEach((item) => onItemChange?.(item.id, { isShared: next }));
      onAllSharedChange?.(next);
    },
    [items, onItemChange, onAllSharedChange],
  );

  return (
    <div className={cn("flex flex-col gap-6 font-sans", className)}>
      <h2 className="text-h3 text-foreground">
        {applicantName}&apos;s Expenses
      </h2>

      {totalExpenses !== undefined && (
        <div className="flex flex-col gap-4 sm:flex-row sm:items-stretch">
          <Card className="w-full shrink-0 sm:w-[195px]">
            <CardContent className="flex flex-col gap-3 p-4">
              <div className="flex flex-1 flex-col gap-1">
                <span className="text-h2 text-foreground">
                  {formatCurrency(totalExpenses)}
                </span>
                <span className="text-body-small text-muted-foreground">
                  Total latest 12 months
                </span>
              </div>
              <Button
                variant="secondary"
                size="sm"
                className="w-fit"
                onClick={onConnectMore}
              >
                Add More Account +
              </Button>
            </CardContent>
          </Card>

          {expenseData && (
            <ExpenseBarChart
              expenseData={expenseData}
              showLegend={false}
              showYAxis
              showXAxis
              defaultPeriod={12}
              height={160}
              className="flex-1"
            />
          )}
        </div>
      )}

      <div className="flex flex-col gap-3">
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-2">
            <h3 className="text-h5 text-foreground">Expenses Details</h3>
            {onResyncFromBank && (
              <Tooltip>
                <TooltipTrigger
                  render={
                    <Button
                      variant="ghost"
                      size="icon-sm"
                      aria-label="Re-sync from bank details"
                      onClick={onResyncFromBank}
                    />
                  }
                >
                  <RotateCcw className="size-4" />
                </TooltipTrigger>
                <TooltipContent>Re-sync from bank details</TooltipContent>
              </Tooltip>
            )}
          </div>
          {hasCoApplicant && (
            <SharedEqualToggle
              checked={globalShared}
              onCheckedChange={handleGlobalSharedChange}
              ariaLabel="Apply shared equally to all expenses"
            />
          )}
        </div>

        <div className="flex flex-col gap-6">
          {items.map((item) => (
            <ExpenseDetailItem
              key={item.id}
              type={item.type}
              label={item.label}
              description={item.description}
              amount={item.amount}
              totalExpenses={itemsTotal}
              hasCoApplicant={hasCoApplicant}
              isShared={item.isShared}
              sharedPercent={item.sharedPercent}
              categoryOptions={remainingCategories}
              onTypeSelect={(type) =>
                onItemChange?.(item.id, {
                  type,
                  label:
                    EXPENSE_CATEGORIES.find((c) => c.type === type)?.label ??
                    "Other",
                })
              }
              onAmountChange={(amount) => onItemChange?.(item.id, { amount })}
              onSharedChange={(isShared) =>
                onItemChange?.(item.id, { isShared })
              }
              onSharedPercentChange={(sharedPercent) =>
                onItemChange?.(item.id, { sharedPercent })
              }
            />
          ))}
        </div>

        <Button
          variant="outline"
          size="sm"
          className="w-fit self-start"
          disabled={remainingCategories.length === 0}
          onClick={onAddItem}
        >
          Add More +
        </Button>
      </div>
    </div>
  );
}
