"use client";

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

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 { Input } from "@/components/ui/input";
import { dashboardCsrfHeader } from "@/lib/csrf.client";

import { LANGUAGES, USER_STATUSES } from "./constants";
import type { UserDetail } from "../../_lib/users-server-api";
import {
  userCreateDefaults,
  userCreateSchema,
  userUpdateSchema,
  type UserCreateFormValues,
  type UserUpdateFormValues,
} from "./schema";

const DEFAULT_LANGUAGE_SENTINEL = "__default__";

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

export function UserCreateForm() {
  const router = useRouter();
  const [saving, setSaving] = React.useState(false);

  const form = useForm<UserCreateFormValues>({
    resolver: zodResolver(userCreateSchema),
    defaultValues: userCreateDefaults,
  });

  const errors = form.formState.errors;

  const onSubmit = async (values: UserCreateFormValues) => {
    const cleaned: UserCreateFormValues = {
      ...values,
      language_id: values.language_id === DEFAULT_LANGUAGE_SENTINEL ? "" : values.language_id,
    };

    setSaving(true);

    try {
      const response = await fetch("/dashboard/admins/users/create-user", {
        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 create user.");
      }

      toast.success(data.message ?? "User created.");
      router.push("/dashboard/admins/users");
    } catch (error) {
      const message = error instanceof Error ? error.message : "Could not create user.";
      toast.error(message);
    } finally {
      setSaving(false);
    }
  };

  return (
    <form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col">
      <FormPageHeader
        backHref="/dashboard/admins/users"
        parentLabel="Users"
        titleIcon={<UserPlus className="size-4 text-primary" />}
        title="Create new user"
        description="Add a backend user and configure their language, status, and access."
      />

      <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 credentials">
          <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>

          <div className="grid gap-4 md:grid-cols-2">
            <FormField label="Password" htmlFor="password" required 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"
              required
              error={errors.confirm_password}
            >
              <Input
                id="confirm_password"
                type="password"
                className="h-9"
                autoComplete="new-password"
                {...form.register("confirm_password")}
              />
            </FormField>
          </div>
        </FormSection>

        <FormSection title="Preferences & access">
          <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
            <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>
            <FormField label="Status" htmlFor="status" required error={errors.status}>
              <Controller
                name="status"
                control={form.control}
                render={({ field }) => (
                  <FormSelect
                    id="status"
                    value={field.value}
                    onChange={field.onChange}
                    placeholder="Select status"
                    options={USER_STATUSES}
                  />
                )}
              />
            </FormField>
          </div>
        </FormSection>
      </div>

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

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

  const form = useForm<UserUpdateFormValues>({
    resolver: zodResolver(userUpdateSchema),
    defaultValues: {
      userId: user.userId,
      first_name: user.firstName,
      last_name: user.lastName,
      email: user.email,
      confirm_email: user.email,
      timezone: user.timezone,
      language_id: user.languageId ?? "",
      status: user.status,
    },
  });

  const errors = form.formState.errors;

  const onSubmit = async (values: UserUpdateFormValues) => {
    const cleaned: UserUpdateFormValues = {
      ...values,
      language_id: values.language_id === DEFAULT_LANGUAGE_SENTINEL ? "" : values.language_id,
    };

    setSaving(true);

    try {
      const response = await fetch("/dashboard/admins/users/update-user", {
        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 user.");
      }

      toast.success(data.message ?? "User updated.");
      router.push(`/dashboard/admins/users/${user.userId}?action=view`);
    } catch (error) {
      const message = error instanceof Error ? error.message : "Could not update user.";
      toast.error(message);
    } finally {
      setSaving(false);
    }
  };

  return (
    <form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col">
      <FormPageHeader
        backHref={`/dashboard/admins/users/${user.userId}?action=view`}
        parentLabel="Users"
        titleIcon={<UserCog className="size-4 text-primary" />}
        title={`Update user: ${user.displayName || user.email}`}
        description="Edit backend user details, preferences, and access."
      />

      <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 & access">
          <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
            <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>
            <FormField label="Status" htmlFor="status" required error={errors.status}>
              <Controller
                name="status"
                control={form.control}
                render={({ field }) => (
                  <FormSelect
                    id="status"
                    value={field.value}
                    onChange={field.onChange}
                    placeholder="Select status"
                    options={USER_STATUSES}
                  />
                )}
              />
            </FormField>
          </div>
        </FormSection>
      </div>

      <FormSaveBar
        cancelHref={`/dashboard/admins/users/${user.userId}?action=view`}
        saveLabel="Update user"
        isSaving={saving}
      />
    </form>
  );
}
