"use client";

import * as React from "react";
import { zodResolver } from "@hookform/resolvers/zod";
import { ArrowLeft, ArrowRight, CheckCircle2 } from "lucide-react";
import { useSession, signIn } from "next-auth/react";
import { useForm, useWatch } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";

import { saveCalculationAction } from "@/app/actions/calculation-actions";
import { HeirSelectorGrid } from "@/components/calculator/heir-selector-grid";
import { ResultsPanel } from "@/components/calculator/results-panel";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { CURRENCY_OPTIONS } from "@/lib/constants";
import { useCalculatorWizard } from "@/hooks/use-calculator-wizard";
import { runInheritanceCalculation } from "@/services/inheritance.service";
import { HEIR_LABELS, HEIR_TYPES, type HeirType, type InheritanceInput, type InheritanceResult } from "@/types/inheritance";
import { formatCurrency } from "@/utils/formatting";

const heirCountsSchema = z.object({
  husband: z.number().int().min(0).max(1),
  wife: z.number().int().min(0).max(4),
  father: z.number().int().min(0).max(1),
  mother: z.number().int().min(0).max(1),
  son: z.number().int().min(0).max(10),
  daughter: z.number().int().min(0).max(10),
  brother: z.number().int().min(0).max(10),
  sister: z.number().int().min(0).max(10),
  grandfather: z.number().int().min(0).max(1),
  grandmother: z.number().int().min(0).max(1),
});

const estateFormSchema = z.object({
  totalEstate: z.number().positive("Estate amount must be greater than 0"),
  currency: z.string().trim().min(3, "Currency is required"),
  debts: z.number().min(0, "Debts cannot be negative"),
  funeralExpenses: z.number().min(0, "Funeral expenses cannot be negative"),
  wasiyyahAmount: z.number().min(0, "Wasiyyah cannot be negative"),
});

const wizardSchema = z.object({
  estate: estateFormSchema,
  heirs: heirCountsSchema,
});

type WizardValues = z.infer<typeof wizardSchema>;

const stepLabels = ["Estate", "Heirs", "Review", "Results"];

function getInitialHeirCounts(initialInput?: InheritanceInput): Record<HeirType, number> {
  const counts: Record<HeirType, number> = {
    husband: 0,
    wife: 0,
    father: 0,
    mother: 0,
    son: 0,
    daughter: 0,
    brother: 0,
    sister: 0,
    grandfather: 0,
    grandmother: 0,
  };

  if (!initialInput) {
    return counts;
  }

  for (const heir of initialInput.heirs) {
    counts[heir.type] = heir.count;
  }

  return counts;
}

function toInheritancePayload(values: WizardValues): InheritanceInput {
  return {
    madhab: "hanafi",
    estate: values.estate,
    heirs: HEIR_TYPES.map((type) => ({
      type,
      count: values.heirs[type],
    })),
  };
}

interface CalculatorWizardProps {
  initialInput?: InheritanceInput;
}

export function CalculatorWizard({ initialInput }: CalculatorWizardProps) {
  const { step, nextStep, previousStep, setWizardStep, isFirstStep, isLastStep } =
    useCalculatorWizard(4);
  const { data: session } = useSession();
  const [result, setResult] = React.useState<InheritanceResult | null>(null);
  const [savedCalculationId, setSavedCalculationId] = React.useState<string | null>(null);
  const [isSaving, startSavingTransition] = React.useTransition();

  const form = useForm<WizardValues>({
    resolver: zodResolver(wizardSchema),
    mode: "onChange",
    defaultValues: {
      estate: {
        totalEstate: initialInput?.estate.totalEstate ?? 100_000,
        currency: initialInput?.estate.currency ?? "USD",
        debts: initialInput?.estate.debts ?? 0,
        funeralExpenses: initialInput?.estate.funeralExpenses ?? 0,
        wasiyyahAmount: initialInput?.estate.wasiyyahAmount ?? 0,
      },
      heirs: getInitialHeirCounts(initialInput),
    },
  });

  const watchedEstate = useWatch({
    control: form.control,
    name: "estate",
  });
  const watchedHeirs = useWatch({
    control: form.control,
    name: "heirs",
  });
  const values: WizardValues = {
    estate: watchedEstate ?? form.getValues("estate"),
    heirs: watchedHeirs ?? form.getValues("heirs"),
  };
  const errors = form.formState.errors;

  const handleHeirChange = (type: HeirType, count: number) => {
    form.setValue(`heirs.${type}`, count, {
      shouldDirty: true,
      shouldValidate: true,
    });
  };

  const onCalculate = async () => {
    const isValid = await form.trigger();
    if (!isValid) {
      toast.error("Please correct form errors.");
      return;
    }

    try {
      const payload = toInheritancePayload(form.getValues());
      const calculated = runInheritanceCalculation(payload);
      setResult(calculated);
      setSavedCalculationId(null);
      toast.success("Calculation completed.");
      nextStep();
    } catch (error) {
      const message =
        error instanceof Error ? error.message : "Failed to calculate inheritance.";
      toast.error(message);
    }
  };

  const onSave = () => {
    if (!result) {
      return;
    }

    if (!session?.user) {
      signIn("google");
      return;
    }

    const payload = toInheritancePayload(form.getValues());
    const spouseLabel =
      payload.heirs.find((heir) => heir.type === "husband" && heir.count > 0)
        ? "Husband"
        : payload.heirs.find((heir) => heir.type === "wife" && heir.count > 0)
          ? "Wife"
          : "Family";

    startSavingTransition(async () => {
      const response = await saveCalculationAction({
        title: `${spouseLabel} Estate - ${new Date().toLocaleDateString("en-US")}`,
        metadata: {
          source: "calculator-wizard",
        },
        input: payload,
        result,
      });

      if (!response.success || !response.id) {
        toast.error(response.message);
        return;
      }

      setSavedCalculationId(response.id);
      toast.success(response.message);
    });
  };

  const goNext = async () => {
    if (step === 1) {
      const valid = await form.trigger(["estate.totalEstate", "estate.currency", "estate.debts", "estate.funeralExpenses", "estate.wasiyyahAmount"]);
      if (!valid) {
        toast.error("Please complete estate details.");
        return;
      }
    }

    if (step === 3) {
      await onCalculate();
      return;
    }

    nextStep();
  };

  return (
    <div className="mx-auto w-full max-w-4xl space-y-6 px-4 py-8 sm:px-6 lg:px-0">
      <div className="flex items-center justify-between">
        {stepLabels.map((label, index) => {
          const currentStep = index + 1;
          const active = currentStep === step;
          const completed = currentStep < step;

          return (
            <div key={label} className="flex flex-1 items-center">
              <div
                className={`inline-flex size-7 items-center justify-center rounded-full text-xs font-semibold ${
                  completed
                    ? "bg-emerald-700 text-white"
                    : active
                      ? "bg-accent text-accent-foreground"
                      : "bg-muted text-muted-foreground"
                }`}
              >
                {completed ? <CheckCircle2 className="size-4" /> : currentStep}
              </div>
              <span className="ml-2 hidden text-xs font-medium text-emerald-900 sm:inline">
                {label}
              </span>
              {index < stepLabels.length - 1 ? (
                <div className="mx-2 h-px flex-1 bg-border" />
              ) : null}
            </div>
          );
        })}
      </div>

      <Card>
        <CardHeader>
          <CardTitle>
            {step === 1 && "Estate Information"}
            {step === 2 && "Heir Selection"}
            {step === 3 && "Review Information"}
            {step === 4 && "Calculation Results"}
          </CardTitle>
          <CardDescription>
            {step === 1 && "Enter estate value and deductible amounts."}
            {step === 2 && "Select heirs and quantities."}
            {step === 3 && "Confirm all details before calculation."}
            {step === 4 && "Hanafi distribution output for the selected heirs."}
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-5">
          {step === 1 ? (
            <div className="grid gap-4 sm:grid-cols-2">
              <div className="space-y-1.5 sm:col-span-2">
                <Label htmlFor="estate-total">Total Estate</Label>
                <Input
                  id="estate-total"
                  type="number"
                  min="0"
                  step="0.01"
                  {...form.register("estate.totalEstate", { valueAsNumber: true })}
                />
                {errors.estate?.totalEstate ? (
                  <p className="text-xs text-destructive">{errors.estate.totalEstate.message}</p>
                ) : null}
              </div>
              <div className="space-y-1.5">
                <Label>Currency</Label>
                <Select
                  value={values.estate.currency ?? undefined}
                  onValueChange={(value) => {
                    if (!value) {
                      return;
                    }
                    form.setValue("estate.currency", value, {
                      shouldValidate: true,
                      shouldDirty: true,
                    });
                  }}
                >
                  <SelectTrigger>
                    <SelectValue placeholder="Currency" />
                  </SelectTrigger>
                  <SelectContent>
                    {CURRENCY_OPTIONS.map((currency) => (
                      <SelectItem key={currency} value={currency}>
                        {currency}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div className="space-y-1.5">
                <Label htmlFor="estate-debts">Debts</Label>
                <Input
                  id="estate-debts"
                  type="number"
                  min="0"
                  step="0.01"
                  {...form.register("estate.debts", { valueAsNumber: true })}
                />
                {errors.estate?.debts ? (
                  <p className="text-xs text-destructive">{errors.estate.debts.message}</p>
                ) : null}
              </div>
              <div className="space-y-1.5">
                <Label htmlFor="estate-funeral">Funeral Expenses</Label>
                <Input
                  id="estate-funeral"
                  type="number"
                  min="0"
                  step="0.01"
                  {...form.register("estate.funeralExpenses", { valueAsNumber: true })}
                />
                {errors.estate?.funeralExpenses ? (
                  <p className="text-xs text-destructive">
                    {errors.estate.funeralExpenses.message}
                  </p>
                ) : null}
              </div>
              <div className="space-y-1.5">
                <Label htmlFor="estate-wasiyyah">Wasiyyah Amount</Label>
                <Input
                  id="estate-wasiyyah"
                  type="number"
                  min="0"
                  step="0.01"
                  {...form.register("estate.wasiyyahAmount", { valueAsNumber: true })}
                />
                {errors.estate?.wasiyyahAmount ? (
                  <p className="text-xs text-destructive">
                    {errors.estate.wasiyyahAmount.message}
                  </p>
                ) : null}
              </div>
            </div>
          ) : null}

          {step === 2 ? (
            <HeirSelectorGrid values={values.heirs} onChange={handleHeirChange} />
          ) : null}

          {step === 3 ? (
            <div className="space-y-4">
              <div className="rounded-lg border border-border bg-muted/30 p-4">
                <p className="text-sm font-medium text-emerald-900">Estate Summary</p>
                <p className="mt-2 text-sm text-muted-foreground">
                  Total: {formatCurrency(values.estate.totalEstate, values.estate.currency)}
                </p>
                <p className="text-sm text-muted-foreground">
                  Debts: {formatCurrency(values.estate.debts, values.estate.currency)}
                </p>
                <p className="text-sm text-muted-foreground">
                  Funeral: {formatCurrency(values.estate.funeralExpenses, values.estate.currency)}
                </p>
                <p className="text-sm text-muted-foreground">
                  Wasiyyah: {formatCurrency(values.estate.wasiyyahAmount, values.estate.currency)}
                </p>
              </div>
              <div className="rounded-lg border border-border bg-muted/30 p-4">
                <p className="text-sm font-medium text-emerald-900">Selected Heirs</p>
                <div className="mt-2 flex flex-wrap gap-2">
                  {HEIR_TYPES.filter((type) => values.heirs[type] > 0).map((type) => (
                    <span key={type} className="rounded-md bg-emerald-100 px-2 py-1 text-xs text-emerald-900">
                      {HEIR_LABELS[type]} x {values.heirs[type]}
                    </span>
                  ))}
                  {HEIR_TYPES.every((type) => values.heirs[type] === 0) ? (
                    <span className="text-xs text-muted-foreground">No heirs selected yet.</span>
                  ) : null}
                </div>
              </div>
            </div>
          ) : null}

          {step === 4 && result ? (
            <ResultsPanel
              result={result}
              currency={values.estate.currency}
              onSave={onSave}
              canSave={Boolean(session?.user)}
              saving={isSaving}
              savedCalculationId={savedCalculationId}
            />
          ) : null}
        </CardContent>
      </Card>

      <div className="flex items-center justify-between">
        <Button
          type="button"
          variant="outline"
          disabled={isFirstStep}
          onClick={previousStep}
        >
          <ArrowLeft className="size-4" />
          Previous
        </Button>

        {isLastStep ? (
          <Button
            type="button"
            variant="outline"
            onClick={() => {
              form.reset();
              setResult(null);
              setSavedCalculationId(null);
              setWizardStep(1);
            }}
          >
            Start New Calculation
          </Button>
        ) : (
          <Button type="button" onClick={goNext}>
            {step === 3 ? (
              <>
                Calculate
              </>
            ) : (
              <>
                Next
                <ArrowRight className="size-4" />
              </>
            )}
          </Button>
        )}
      </div>
    </div>
  );
}
