"use client";

import { zodResolver } from "@hookform/resolvers/zod";
import { CircleUser } from "lucide-react";
import { useRouter } from "next/navigation";
import * as React from "react";
import { Controller, useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";

import {
  FormPageHeader,
  FormSaveBar,
  FormSelect,
  type FormSelectOption,
} from "@/app/dashboard/_components/form";
import { FormField } from "@/components/form/form-field";
import { FormSection } from "@/app/dashboard/customers/_components/customer-form/form-section";
import { TIMEZONES } from "@/app/dashboard/customers/_components/customer-form/constants";
import { LANGUAGES } from "@/app/dashboard/admins/users/_components/user-form/constants";
import { Input } from "@/components/ui/input";
import { MIN_PASSWORD_LENGTH } from "@/config/password-policy";
import { dashboardCsrfHeader } from "@/lib/csrf.client";

import type { AccountProfile } from "../_lib/account-server-api";

const DEFAULT_LANGUAGE_SENTINEL = "__default__";

const languageSelectOptions: FormSelectOption[] = LANGUAGES.map((opt) => ({
  value: opt.value || DEFAULT_LANGUAGE_SENTINEL,
  label: opt.label,
}));

const accountSchema = z
  .object({
    first_name: z.string().min(1, "First name is required"),
    last_name: z.string().min(1, "Last name is required"),
    email: z.string().email("Please enter a valid email"),
    confirm_email: z.string().min(1, "Please confirm email"),
    timezone: z.string().min(1, "Timezone is required"),
    language_id: z.string().optional(),
    password: z.string().optional(),
    confirm_password: z.string().optional(),
  })
  .refine((data) => data.email === data.confirm_email, {
    message: "Email confirmation does not match",
    path: ["confirm_email"],
  })
  .refine(
    (data) => {
      const password = data.password ?? "";
      const confirm = data.confirm_password ?? "";
      if (!password && !confirm) return true;
      return password.length >= MIN_PASSWORD_LENGTH;
    },
    {
      message: `Password must be at least ${MIN_PASSWORD_LENGTH} characters`,
      path: ["password"],
    },
  )
  .refine(
    (data) => {
      const password = data.password ?? "";
      const confirm = data.confirm_password ?? "";
      if (!password && !confirm) return true;
      return password === confirm;
    },
    {
      message: "Password confirmation does not match",
      path: ["confirm_password"],
    },
  );

type AccountFormValues = z.infer<typeof accountSchema>;

export function AccountInfoForm({ user }: { readonly user: AccountProfile }) {
  const router = useRouter();
  const [saving, setSaving] = React.useState(false);

  const form = useForm<AccountFormValues>({
    resolver: zodResolver(accountSchema),
    defaultValues: {
      first_name: user.firstName,
      last_name: user.lastName,
      email: user.email,
      confirm_email: user.email,
      timezone: user.timezone,
      language_id: user.languageId ?? "",
      password: "",
      confirm_password: "",
    },
  });

  const errors = form.formState.errors;

  const onSubmit = async (values: AccountFormValues) => {
    const cleaned = {
      ...values,
      language_id: values.language_id === DEFAULT_LANGUAGE_SENTINEL ? "" : values.language_id,
      password: values.password?.trim() || undefined,
      confirm_password: values.confirm_password?.trim() || undefined,
    };

    setSaving(true);
    try {
      const response = await fetch("/dashboard/account/profile", {
        method: "POST",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json",
          ...dashboardCsrfHeader(),
        },
        body: JSON.stringify(cleaned),
      });
      const data = (await response.json().catch(() => null)) as {
        status?: string;
        message?: string;
      } | null;

      if (!response.ok || data?.status !== "success") {
        throw new Error(data?.message ?? "Could not update account.");
      }

      toast.success(data.message ?? "Account updated.");
      form.reset({
        ...cleaned,
        password: "",
        confirm_password: "",
      });
      router.refresh();
    } catch (error) {
      const message = error instanceof Error ? error.message : "Could not update account.";
      toast.error(message);
    } finally {
      setSaving(false);
    }
  };

  return (
    <form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col">
      <FormPageHeader
        backHref="/dashboard"
        parentLabel="Dashboard"
        titleIcon={<CircleUser className="size-4 text-primary" />}
        title="Account information"
        description="Update your name, email, timezone, and password for this admin account."
      />

      <div className="space-y-6">
        <FormSection title="Personal details">
          <div className="grid gap-4 md:grid-cols-2">
            <FormField label="First name" htmlFor="first_name" required error={errors.first_name}>
              <Input id="first_name" className="h-9" {...form.register("first_name")} />
            </FormField>
            <FormField label="Last name" htmlFor="last_name" required error={errors.last_name}>
              <Input id="last_name" className="h-9" {...form.register("last_name")} />
            </FormField>
          </div>
        </FormSection>

        <FormSection title="Login email">
          <div className="grid gap-4 md:grid-cols-2">
            <FormField label="Email" htmlFor="email" required error={errors.email}>
              <Input
                id="email"
                type="email"
                className="h-9"
                autoComplete="email"
                {...form.register("email")}
              />
            </FormField>
            <FormField
              label="Confirm email"
              htmlFor="confirm_email"
              required
              error={errors.confirm_email}
            >
              <Input
                id="confirm_email"
                type="email"
                className="h-9"
                autoComplete="email"
                {...form.register("confirm_email")}
              />
            </FormField>
          </div>
        </FormSection>

        <FormSection title="Preferences">
          <div className="grid gap-4 md:grid-cols-2">
            <FormField label="Timezone" htmlFor="timezone" required error={errors.timezone}>
              <Controller
                name="timezone"
                control={form.control}
                render={({ field }) => (
                  <FormSelect
                    id="timezone"
                    value={field.value ?? ""}
                    onChange={field.onChange}
                    placeholder="Please select"
                    options={TIMEZONES}
                  />
                )}
              />
            </FormField>
            <FormField label="Language" htmlFor="language_id" error={errors.language_id}>
              <Controller
                name="language_id"
                control={form.control}
                render={({ field }) => (
                  <FormSelect
                    id="language_id"
                    value={field.value || DEFAULT_LANGUAGE_SENTINEL}
                    onChange={field.onChange}
                    placeholder="Application default"
                    options={languageSelectOptions}
                  />
                )}
              />
            </FormField>
          </div>
        </FormSection>

        <FormSection title="Change password">
          <p className="text-muted-foreground mb-4 text-sm">
            Leave blank to keep your current password.
          </p>
          <div className="grid gap-4 md:grid-cols-2">
            <FormField label="New password" htmlFor="password" error={errors.password}>
              <Input
                id="password"
                type="password"
                className="h-9"
                autoComplete="new-password"
                {...form.register("password")}
              />
            </FormField>
            <FormField
              label="Confirm password"
              htmlFor="confirm_password"
              error={errors.confirm_password}
            >
              <Input
                id="confirm_password"
                type="password"
                className="h-9"
                autoComplete="new-password"
                {...form.register("confirm_password")}
              />
            </FormField>
          </div>
        </FormSection>
      </div>

      <FormSaveBar cancelHref="/dashboard" saveLabel="Save account" isSaving={saving} />
    </form>
  );
}
