"use client";

import Button from "@/components/ui/button/Button";
import Input from "@/components/form/input/InputField";
import { DateTimePicker } from "@/components/form/input/DateTimeInput";
import PhoneInput from "@/components/form/group-input/PhoneInput";
import Label from "@/components/form/Label";
import { clearSignupSetupPasswordToken } from "@/lib/auth/signup-setup-token";
import { AlertCircle, Eye, EyeOff, KeyRound, Loader2 } from "lucide-react";
import { useRouter } from "next/navigation";
import React from "react";
import toast from "react-hot-toast";
import {
  buildSignupSetPasswordRequest,
  formatDateOfBirthDisplay,
  formatDateOfBirthInput,
  formatSignupDate,
  isExpiredSignupTokenError,
  parseDateOfBirthInput,
  validateSignupSetPasswordForm,
} from "../formLogic";

interface SignupSetPasswordFormProps {
  setupPasswordToken: string;
}

export default function SignupSetPasswordForm({ setupPasswordToken }: SignupSetPasswordFormProps) {
  const router = useRouter();
  const [firstName, setFirstName] = React.useState("");
  const [lastName, setLastName] = React.useState("");
  const [phone, setPhone] = React.useState("+62");
  const [dateOfBirth, setDateOfBirth] = React.useState("");
  const [dateOfBirthInput, setDateOfBirthInput] = React.useState("");
  const [newPassword, setNewPassword] = React.useState("");
  const [confirmPassword, setConfirmPassword] = React.useState("");
  const [submitting, setSubmitting] = React.useState(false);
  const [tokenExpired, setTokenExpired] = React.useState(false);
  const [showNewPassword, setShowNewPassword] = React.useState(false);
  const [showConfirmPassword, setShowConfirmPassword] = React.useState(false);
  const minDate = React.useMemo(() => new Date(1950, 0, 1), []);
  const maxDate = React.useMemo(() => {
    const date = new Date();
    date.setHours(23, 59, 59, 999);
    return date;
  }, []);

  const handleDateOfBirthInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const formatted = formatDateOfBirthInput(event.target.value);
    setDateOfBirthInput(formatted);
    setDateOfBirth(parseDateOfBirthInput(formatted));
  };

  const handleDateOfBirthPickerChange = (date: Date) => {
    const apiDate = formatSignupDate(date);
    setDateOfBirth(apiDate);
    setDateOfBirthInput(formatDateOfBirthDisplay(apiDate));
  };

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();

    if (!setupPasswordToken) {
      toast.error("Your signup link is missing. Please reopen the verification email.");
      return;
    }

    const formValues = {
      firstName,
      lastName,
      phone,
      dateOfBirth,
      dateOfBirthInput,
      newPassword,
      confirmPassword,
    };
    const validationError = validateSignupSetPasswordForm(formValues);
    if (validationError) {
      toast.error(validationError);
      return;
    }

    setSubmitting(true);
    try {
      const response = await fetch("/api/auth/signup/set-password", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(buildSignupSetPasswordRequest(setupPasswordToken, formValues)),
      });

      const data = await response.json().catch(() => ({}));
      if (!response.ok || data?.ok === false) {
        throw new Error(data?.error || data?.message || "Failed to set password");
      }

      clearSignupSetupPasswordToken();
      toast.success(data?.message || "Password saved successfully. Please sign in.");
      router.replace("/signin");
    } catch (error) {
      const message = error instanceof Error ? error.message : "Failed to set password";
      if (isExpiredSignupTokenError(message)) {
        clearSignupSetupPasswordToken();
        setTokenExpired(true);
        return;
      }
      toast.error(message);
    } finally {
      setSubmitting(false);
    }
  };

  if (tokenExpired) {
    return (
      <div className="rounded-2xl border border-gray-200 bg-white p-6 shadow-theme-sm dark:border-gray-800 dark:bg-gray-900 sm:p-8">
        <div className="mb-6 flex h-12 w-12 items-center justify-center rounded-full bg-error-50 text-error-600 dark:bg-error-500/10 dark:text-error-400">
          <AlertCircle className="h-6 w-6" />
        </div>
        <h1 className="text-2xl font-semibold text-gray-900 dark:text-white">
          Verification link expired
        </h1>
        <p className="mt-3 text-sm leading-6 text-gray-500 dark:text-gray-400">
          This signup link is no longer valid. Return to sign up to restart the process, or go to
          sign in if your account was already created.
        </p>
        <div className="mt-6 space-y-3">
          <Button className="w-full" size="sm" onClick={() => router.replace("/signup")}>
            Back to Sign Up
          </Button>
          <Button
            className="w-full"
            size="sm"
            variant="outline"
            onClick={() => router.replace("/signin")}
          >
            Go to Sign In
          </Button>
        </div>
      </div>
    );
  }

  return (
    <div className="rounded-2xl border border-gray-200 bg-white p-6 shadow-theme-sm dark:border-gray-800 dark:bg-gray-900 sm:p-8">
      <div className="mb-6">
        <div className="mb-3 inline-flex items-center gap-2 rounded-full border border-brand-200 bg-brand-50 px-3 py-1 text-xs font-semibold uppercase text-brand-700 dark:border-brand-500/20 dark:bg-brand-500/10 dark:text-brand-300">
          <KeyRound className="h-3.5 w-3.5" />
          Finish Signup
        </div>
        <h1 className="text-2xl font-semibold text-gray-900 dark:text-white">
          Complete your account
        </h1>
        <p className="mt-3 text-sm leading-6 text-gray-500 dark:text-gray-400">
          Add your required profile details and create a password to finish signing up.
        </p>
      </div>

      <form onSubmit={handleSubmit} className="space-y-5">
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
          <div>
            <Label>First Name</Label>
            <Input
              value={firstName}
              onChange={(event) => setFirstName(event.target.value)}
              placeholder="First name"
            />
          </div>
          <div>
            <Label>Last Name</Label>
            <Input
              value={lastName}
              onChange={(event) => setLastName(event.target.value)}
              placeholder="Last name"
            />
          </div>
        </div>

        <div>
          <Label>Phone Number</Label>
          <PhoneInput
            defaultValue={phone}
            onChange={setPhone}
            placeholder="8123456789"
            fixedDialCode
          />
        </div>

        <div>
          <Label>Date of Birth</Label>
          <div className="flex items-center gap-2">
            <div className="min-w-0 flex-1">
              <Input
                value={dateOfBirthInput}
                onChange={handleDateOfBirthInputChange}
                placeholder="DD/MM/YYYY"
                inputMode="numeric"
                maxLength={10}
                aria-label="Date of Birth"
              />
            </div>
            <div className="w-14 shrink-0">
              <DateTimePicker
                mode="date"
                value={dateOfBirth ? new Date(`${dateOfBirth}T12:00:00`) : null}
                placeholder="Select date"
                minDate={minDate}
                maxDate={maxDate}
                size="sm"
                iconOnly
                onChange={handleDateOfBirthPickerChange}
              />
            </div>
          </div>
          <p className="mt-1 text-xs text-gray-500 dark:text-gray-400">Format: DD/MM/YYYY</p>
        </div>

        <div>
          <Label>New Password</Label>
          <div className="relative">
            <Input
              type={showNewPassword ? "text" : "password"}
              value={newPassword}
              onChange={(e) => setNewPassword(e.target.value)}
              placeholder="Create a strong password"
              className="pr-12"
            />
            <button
              type="button"
              onClick={() => setShowNewPassword((prev) => !prev)}
              className="absolute inset-y-0 right-3 flex items-center text-gray-500 transition hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
              aria-label={showNewPassword ? "Hide password" : "Show password"}
            >
              {showNewPassword ? <EyeOff className="h-5 w-5" /> : <Eye className="h-5 w-5" />}
            </button>
          </div>
        </div>

        <div>
          <Label>Confirm Password</Label>
          <div className="relative">
            <Input
              type={showConfirmPassword ? "text" : "password"}
              value={confirmPassword}
              onChange={(e) => setConfirmPassword(e.target.value)}
              placeholder="Repeat your password"
              className="pr-12"
            />
            <button
              type="button"
              onClick={() => setShowConfirmPassword((prev) => !prev)}
              className="absolute inset-y-0 right-3 flex items-center text-gray-500 transition hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
              aria-label={showConfirmPassword ? "Hide confirm password" : "Show confirm password"}
            >
              {showConfirmPassword ? <EyeOff className="h-5 w-5" /> : <Eye className="h-5 w-5" />}
            </button>
          </div>
        </div>

        <Button className="w-full" size="sm" type="submit" disabled={submitting}>
          {submitting && <Loader2 className="mr-2 inline h-4 w-4 animate-spin" />}
          {submitting ? "Saving..." : "Save Password"}
        </Button>
      </form>
    </div>
  );
}
