import React, { useEffect, useState } from "react";
import { Pencil, X } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "./button";
import { Input } from "./input";
import { MoneyInputWithSlider } from "./money-input-with-slider";
import { Toggle } from "./toggle";
import { Sheet, SheetContent, SheetTitle } from "./sheet";

/**
 * Mobile bottom-sheet organism for creating or editing a borrowing scenario.
 *
 * Sections (top-to-bottom):
 *  - Header: editable scenario name + close button
 *  - Content (scrollable):
 *    - Objective selector (Buy a Home / Buy an Investment / Refinance)
 *    - Applicants selector (1 / 2)
 *    - Dependants selector (0 – 3)
 *    - MoneyInputWithSlider fields (income, expenses, debt, desired loan)
 *  - Footer: Cancel + Create/Update Scenario buttons
 *
 * On mobile the sheet fills the viewport width. On larger screens it is
 * capped at max-w-2xl and the slider fields flow in a 2-column grid so
 * the drawer does not stretch the page layout.
 */

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

export type ScenarioObjective = "buy-home" | "buy-investment" | "refinance";

export interface ScenarioDrawerValues {
  name: string;
  objective: ScenarioObjective;
  /** 1 = sole applicant, 2 = two applicants */
  applicants: 1 | 2;
  /** Number of dependants (0–3) */
  dependants: number;
  /** Main applicant after-tax monthly income in dollars */
  mainApplicantMonthlyIncome: number;
  /** Main applicant monthly rental income in dollars */
  mainApplicantMonthlyRentalIncome: number;
  /** Co-applicant after-tax monthly income in dollars (applicants = 2 only) */
  coApplicantMonthlyIncome: number;
  /** Co-applicant monthly rental income in dollars (applicants = 2 only) */
  coApplicantMonthlyRentalIncome: number;
  /** Combined essential expenses per month in dollars */
  monthlyExpense: number;
  /** Combined debt repayments per month in dollars */
  monthlyDebtRepayment: number;
  /** Estimated rental income (buy-investment objective only) */
  estimatedRentalIncome: number;
  /** Target loan amount in dollars */
  desiredLoanAmount: number;
}

export interface ScenarioDrawerProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  /** Initial field values — re-applied whenever the drawer opens */
  defaultValues?: Partial<ScenarioDrawerValues>;
  /** true = show "Update Scenario" footer button, false = "Create Scenario" */
  isEditMode?: boolean;
  /** Called with the final values when the user clicks Save */
  onSave: (values: ScenarioDrawerValues) => void;
  /** Called when the user clicks Cancel or the close button */
  onCancel?: () => void;
  className?: string;
}

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

const DEFAULT_VALUES: ScenarioDrawerValues = {
  name: "New Scenario",
  objective: "buy-home",
  applicants: 1,
  dependants: 0,
  mainApplicantMonthlyIncome: 0,
  mainApplicantMonthlyRentalIncome: 0,
  coApplicantMonthlyIncome: 0,
  coApplicantMonthlyRentalIncome: 0,
  monthlyExpense: 0,
  monthlyDebtRepayment: 0,
  estimatedRentalIncome: 0,
  desiredLoanAmount: 750_000,
};

const OBJECTIVE_OPTIONS: { value: ScenarioObjective; label: string }[] = [
  { value: "buy-home", label: "Buy a Home or Move" },
  { value: "buy-investment", label: "Buy an Investment" },
  { value: "refinance", label: "Refinance My Loan" },
];

const APPLICANT_OPTIONS: { value: 1 | 2; label: string }[] = [
  { value: 1, label: "Just Me" },
  { value: 2, label: "Me + One" },
];

const DEPENDANT_OPTIONS: { value: number; label: string }[] = [
  { value: 0, label: "None" },
  { value: 1, label: "1" },
  { value: 2, label: "2" },
  { value: 3, label: "3" },
];

// ─── Internal sub-components ──────────────────────────────────────────────────

/**
 * Horizontally connected row of Toggle buttons acting as a single-select group.
 * Uses the WealthX `Toggle` variant="outline" so the pressed state renders
 * with `bg-primary/10 + inset-ring-primary` per the DS token.
 */
function OptionGroup<T extends string | number>({
  label,
  options,
  value,
  onChange,
}: {
  label: string;
  options: { value: T; label: string }[];
  value: T;
  onChange: (v: T) => void;
}) {
  return (
    <div className="flex flex-col gap-2">
      <span className="text-sm font-medium text-foreground">{label}</span>
      <div className="flex">
        {options.map((opt, idx) => (
          <Toggle
            key={String(opt.value)}
            variant="outline"
            pressed={opt.value === value}
            onPressedChange={(on) => {
              if (on) onChange(opt.value);
            }}
            className={cn(
              "h-auto flex-1 whitespace-normal px-3 py-2 text-center text-sm leading-tight",
              // Connect buttons: collapse shared borders
              idx > 0 && "border-l-0",
            )}
          >
            {opt.label}
          </Toggle>
        ))}
      </div>
    </div>
  );
}

// ─── Main component ───────────────────────────────────────────────────────────

export function ScenarioDrawer({
  open,
  onOpenChange,
  defaultValues,
  isEditMode = false,
  onSave,
  onCancel,
  className,
}: ScenarioDrawerProps) {
  const [values, setValues] = useState<ScenarioDrawerValues>({
    ...DEFAULT_VALUES,
    ...defaultValues,
  });
  const [editingName, setEditingName] = useState(false);

  // Re-seed internal state whenever the drawer opens with new defaultValues
  useEffect(() => {
    if (open) {
      setValues({ ...DEFAULT_VALUES, ...defaultValues });
    }
  }, [open]); // intentional: only react to open changing, not defaultValues

  const set = <K extends keyof ScenarioDrawerValues>(
    key: K,
    value: ScenarioDrawerValues[K],
  ) => setValues((prev) => ({ ...prev, [key]: value }));

  const handleCancel = () => {
    onCancel?.();
    onOpenChange(false);
  };

  const handleSave = () => {
    onSave(values);
    onOpenChange(false);
  };

  const isTwoApplicants = values.applicants === 2;
  const isInvestment = values.objective === "buy-investment";
  const expenseLabel = isTwoApplicants ? "Combined" : "Estimated";

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      {/*
       * showCloseButton={false}: disable the Sheet's built-in absolute close
       * button — the drawer renders its own X in the header row.
       */}
      <SheetContent
        side="bottom"
        showCloseButton={false}
        className={cn("flex max-h-[90dvh] flex-col gap-0 p-0", className)}
      >
        {/* ── Header ─────────────────────────────────────────────────────── */}
        <div className="flex items-center justify-between border-b border-border px-4 py-3">
          <SheetTitle className="sr-only">
            {isEditMode ? "Edit Scenario" : "Create Scenario"}
          </SheetTitle>

          {editingName ? (
            <Input
              autoFocus
              value={values.name}
              onChange={(e) => set("name", e.target.value)}
              onBlur={() => setEditingName(false)}
              onKeyDown={(e) => e.key === "Enter" && setEditingName(false)}
              className="h-8 text-base font-semibold"
            />
          ) : (
            <button
              type="button"
              onClick={() => setEditingName(true)}
              className="flex items-center gap-2 text-base font-semibold text-foreground hover:opacity-70"
            >
              {values.name}
              <Pencil size={14} className="shrink-0 text-muted-foreground" />
            </button>
          )}

          <button
            type="button"
            onClick={handleCancel}
            aria-label="Close"
            className="ml-3 shrink-0 p-1 text-muted-foreground transition-colors hover:text-foreground"
          >
            <X size={18} />
          </button>
        </div>

        {/* ── Scrollable content ──────────────────────────────────────────── */}
        <div className="flex-1 overflow-y-auto px-4 py-4">
          <div className="flex flex-col gap-6">
            {/* Selectors */}
            <OptionGroup
              label="Objective"
              options={OBJECTIVE_OPTIONS}
              value={values.objective}
              onChange={(v) => set("objective", v)}
            />
            <OptionGroup
              label="Applicants"
              options={APPLICANT_OPTIONS}
              value={values.applicants}
              onChange={(v) => set("applicants", v)}
            />
            <OptionGroup
              label="Dependants"
              options={DEPENDANT_OPTIONS}
              value={values.dependants}
              onChange={(v) => set("dependants", v)}
            />

            {/* Income sliders — 2-col grid on md+ */}
            <div className="grid grid-cols-1 gap-5 md:grid-cols-2">
              <MoneyInputWithSlider
                label="Main Applicant Monthly Income"
                value={values.mainApplicantMonthlyIncome}
                min={0}
                max={30_000}
                step={100}
                onChange={(v) => set("mainApplicantMonthlyIncome", v)}
              />
              <MoneyInputWithSlider
                label="Main Applicant Rental Income"
                value={values.mainApplicantMonthlyRentalIncome}
                min={0}
                max={30_000}
                step={100}
                onChange={(v) => set("mainApplicantMonthlyRentalIncome", v)}
              />
              {isTwoApplicants && (
                <>
                  <MoneyInputWithSlider
                    label="Co-Applicant Monthly Income"
                    value={values.coApplicantMonthlyIncome}
                    min={0}
                    max={30_000}
                    step={100}
                    onChange={(v) => set("coApplicantMonthlyIncome", v)}
                  />
                  <MoneyInputWithSlider
                    label="Co-Applicant Rental Income"
                    value={values.coApplicantMonthlyRentalIncome}
                    min={0}
                    max={30_000}
                    step={100}
                    onChange={(v) => set("coApplicantMonthlyRentalIncome", v)}
                  />
                </>
              )}
            </div>

            {/* Expense sliders — 2-col grid on md+ */}
            <div className="grid grid-cols-1 gap-5 md:grid-cols-2">
              <MoneyInputWithSlider
                label={`${expenseLabel} Essential Expenses PM`}
                value={values.monthlyExpense}
                min={0}
                max={15_000}
                step={100}
                onChange={(v) => set("monthlyExpense", v)}
              />
              <MoneyInputWithSlider
                label={`${expenseLabel} Debt Repayment PM`}
                value={values.monthlyDebtRepayment}
                min={0}
                max={15_000}
                step={100}
                onChange={(v) => set("monthlyDebtRepayment", v)}
              />
              {isInvestment && (
                <MoneyInputWithSlider
                  label="Estimated Rental Income PM"
                  value={values.estimatedRentalIncome}
                  min={0}
                  max={30_000}
                  step={100}
                  onChange={(v) => set("estimatedRentalIncome", v)}
                />
              )}
            </div>

            {/* Desired Loan Amount */}
            <div className="border-t border-border pt-4">
              <MoneyInputWithSlider
                label="Desired Loan Amount"
                value={values.desiredLoanAmount}
                min={50_000}
                max={2_000_000}
                step={5_000}
                onChange={(v) => set("desiredLoanAmount", v)}
              />
            </div>
          </div>
        </div>

        {/* ── Footer ──────────────────────────────────────────────────────── */}
        <div className="flex gap-3 border-t border-border px-4 py-3">
          <Button variant="outline" className="flex-1" onClick={handleCancel}>
            Cancel
          </Button>
          <Button className="flex-1" onClick={handleSave}>
            {isEditMode ? "Update Scenario" : "Create Scenario"}
          </Button>
        </div>
      </SheetContent>
    </Sheet>
  );
}
