import * as React from "react";
import { useState, useCallback } from "react";
import {
  Baby,
  Car,
  DollarSign,
  Gift,
  Home,
  Info,
  ShoppingCart,
  Shield,
  Smartphone,
  type LucideIcon,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Switch } from "@/components/ui/switch";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { CurrencyInputWithSlider } from "@/components/ui/form-primitives";

// ---------------------------------------------------------------------------
// SharedEqualToggle — "No [Switch] Yes" row + label, used both as the
// per-item toggle here and the global toggle in ExpenseWorkDetails.
// ---------------------------------------------------------------------------

export type SharedEqualToggleProps = {
  checked: boolean;
  onCheckedChange?: (checked: boolean) => void;
  label?: string;
  ariaLabel?: string;
  /** "stacked" = label above the switch row (per-item); "inline" = all on one row (global toggle). */
  layout?: "inline" | "stacked";
};

export function SharedEqualToggle({
  checked,
  onCheckedChange,
  label = "Expense shared equally",
  ariaLabel,
  layout = "inline",
}: SharedEqualToggleProps) {
  const toggleRow = (
    <div className="flex items-center gap-2">
      <span>No</span>
      <Switch
        size="sm"
        checked={checked}
        onCheckedChange={onCheckedChange}
        aria-label={ariaLabel ?? label}
      />
      <span>Yes</span>
    </div>
  );

  if (layout === "stacked") {
    return (
      <div className="flex flex-col gap-1 text-caption text-muted-foreground">
        <span>{label}</span>
        {toggleRow}
      </div>
    );
  }

  return (
    <div className="flex items-center gap-2 text-caption text-muted-foreground">
      <span>{label}</span>
      {toggleRow}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

export type ExpenseType =
  | "housing"
  | "transport"
  | "groceries"
  | "childcare"
  | "insurance"
  | "entertainment"
  | "utilities"
  | "other";

export type ExpenseDetailItemProps = {
  /** Expense category type — drives the icon. Empty means "not chosen yet",
   *  which renders the category picker instead of the icon + label. */
  type: ExpenseType | string;
  /** Display label for the expense */
  label: string;
  /** Categories still available to pick — only used while `type` is unset. */
  categoryOptions?: Array<{ type: ExpenseType | string; label: string }>;
  /** Called when a category is chosen for a not-yet-typed item. */
  onTypeSelect?: (type: string) => void;
  /** Placeholder for the category picker. */
  categoryPlaceholder?: string;
  /** Optional tooltip description (shown via ⓘ icon) */
  description?: string;
  /** Current monthly expense amount */
  amount: number;
  /** Total of all expenses — used to calculate the progress bar ratio */
  totalExpenses?: number;
  /** Whether there is a co-applicant — shows the shared toggle when true */
  hasCoApplicant?: boolean;
  /** Whether this expense is shared between applicants */
  isShared?: boolean;
  /** Percentage attributed to the main applicant (0–100) */
  sharedPercent?: number;
  onAmountChange?: (amount: number) => void;
  onSharedChange?: (shared: boolean) => void;
  onSharedPercentChange?: (percent: number) => void;
  onDelete?: () => void;
  className?: string;
};

// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------

const EXPENSE_ICON_MAP: Record<string, LucideIcon> = {
  housing: Home,
  transport: Car,
  groceries: ShoppingCart,
  childcare: Baby,
  insurance: Shield,
  entertainment: Gift,
  utilities: Smartphone, // phone / internet / subscriptions
  other: DollarSign,
};

// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------

/**
 * ExpenseDetailItem — a single expense row in the loan wizard Expenses Details section.
 *
 * Left side: category icon + label + ⓘ, progress bar, optional shared toggle + percent.
 * Right side: currency input with slider.
 *
 * Figma: WealthX-Backoffice---Mobile-App — node 19308:53715
 */
export function ExpenseDetailItem({
  type,
  label,
  categoryOptions = [],
  onTypeSelect,
  categoryPlaceholder = "Choose Your Expense Item",
  description,
  amount,
  totalExpenses,
  hasCoApplicant = false,
  isShared = false,
  sharedPercent: initialPercent = 50,
  onAmountChange,
  onSharedChange,
  onSharedPercentChange,
  onDelete,
  className,
}: ExpenseDetailItemProps) {
  // A freshly added row has no category yet — it shows a picker until one is chosen.
  const isNewItem = !type;
  const Icon = EXPENSE_ICON_MAP[type] ?? DollarSign;
  const fillPct =
    totalExpenses && totalExpenses > 0
      ? Math.min(100, (amount / totalExpenses) * 100)
      : 0;

  const [percent, setPercent] = useState(String(initialPercent));

  const handlePercentBlur = useCallback(() => {
    const parsed = Math.max(0, Math.min(100, parseInt(percent, 10) || 0));
    setPercent(String(parsed));
    onSharedPercentChange?.(parsed);
  }, [percent, onSharedPercentChange]);

  return (
    <div
      className={cn(
        "flex flex-col gap-4 font-sans sm:flex-row sm:items-start sm:gap-6",
        className,
      )}
    >
      <div className="flex flex-1 flex-col gap-2">
        {isNewItem ? (
          <Select
            value=""
            onValueChange={(v) => onTypeSelect?.(v as string)}
            items={categoryOptions.map((o) => ({
              value: String(o.type),
              label: o.label,
            }))}
          >
            <SelectTrigger className="w-full" aria-label={categoryPlaceholder}>
              <SelectValue placeholder={categoryPlaceholder} />
            </SelectTrigger>
            <SelectContent>
              {categoryOptions.map((o) => (
                <SelectItem key={String(o.type)} value={String(o.type)}>
                  {o.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        ) : (
          <div className="flex items-center gap-2">
            <div className="flex size-9 shrink-0 items-center justify-center bg-muted">
              <Icon
                className="size-5 text-muted-foreground"
                aria-hidden="true"
              />
            </div>
            <span className="text-label-medium text-foreground">{label}</span>
            {description && (
              <span
                title={description}
                className="cursor-help text-muted-foreground"
              >
                <Info className="size-3.5" aria-hidden="true" />
              </span>
            )}
          </div>
        )}

        {/* Full-width on mobile; capped at 274px (Figma left-column width) from sm+ */}
        <div className="h-2 w-full max-w-none bg-muted sm:max-w-[274px]">
          <div
            className="h-full bg-foreground transition-all"
            style={{ width: `${fillPct}%` }}
            role="progressbar"
            aria-label={`${label} proportion of total expenses`}
            aria-valuenow={fillPct}
            aria-valuemin={0}
            aria-valuemax={100}
          />
        </div>

        {hasCoApplicant && (
          <div className="flex items-start gap-4">
            <SharedEqualToggle
              layout="stacked"
              checked={isShared}
              onCheckedChange={onSharedChange}
            />

            {isShared && (
              <div className="flex flex-col gap-1">
                <label
                  className="text-caption text-muted-foreground"
                  htmlFor={`shared-percent-${label}`}
                >
                  Shared percent
                </label>
                <div className="relative w-20">
                  <Input
                    id={`shared-percent-${label}`}
                    type="number"
                    min={0}
                    max={100}
                    value={percent}
                    onChange={(e) => setPercent(e.target.value)}
                    onBlur={handlePercentBlur}
                    className="pr-6 text-body-small"
                    aria-label={`${label} shared percent`}
                  />
                  <span className="pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 text-caption text-muted-foreground">
                    %
                  </span>
                </div>
              </div>
            )}
          </div>
        )}
      </div>

      <div className="flex w-full shrink-0 flex-col gap-1.5 sm:w-64">
        <CurrencyInputWithSlider
          value={amount}
          min={0}
          max={20000}
          step={50}
          onValueChange={onAmountChange}
        />
        {onDelete && (
          <Button
            variant="link"
            size="xs"
            onClick={onDelete}
            aria-label="Delete expense"
            className="mt-1 self-end px-0 text-muted-foreground hover:text-destructive"
          >
            Remove
          </Button>
        )}
      </div>
    </div>
  );
}
