"use client";

import * as React from "react";
import Link from "next/link";

import { zodResolver } from "@hookform/resolvers/zod";
import { ArrowLeft, Save, Upload, UserPlus } from "lucide-react";
import { Controller, useForm } from "react-hook-form";
import { z } from "zod";

import { useDashboardFormSubmit } from "@/app/dashboard/_components/use-dashboard-form-submit";
import {
  CUSTOMER_STATUSES,
  PHONE_COUNTRIES,
  TIMEZONES,
} from "@/app/dashboard/customers/_components/customer-form/constants";
import { FormField } from "@/components/form/form-field";
import { Button } from "@/components/ui/button";
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from "@/components/ui/input-group";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { MIN_PASSWORD_LENGTH } from "@/config/password-policy";
import { adminPaths } from "@/app/customer/_lib/admin/admin-paths";

type GroupOption = {
  group_id: number;
  name: string;
};

type UserCreateFormProps = {
  tenant: string;
  groups: GroupOption[];
  canAssignRoles?: boolean;
};

type FormValues = {
  first_name: string;
  last_name: string;
  email: string;
  confirm_email: string;
  password: string;
  confirm_password: string;
  group_id: string;
  status: string;
  phone_country: string;
  phone: string;
  timezone: string;
};

function buildSchema(canAssignRoles: boolean) {
  return z
    .object({
      first_name: z.string().trim().min(1, "First name is required"),
      last_name: z.string(),
      email: z.string().trim().email("Enter a valid email address"),
      confirm_email: z.string().trim().email("Confirm the email address"),
      password: z
        .string()
        .min(MIN_PASSWORD_LENGTH, `Password must be at least ${MIN_PASSWORD_LENGTH} characters`),
      confirm_password: z.string().min(1, "Confirm the password"),
      group_id: canAssignRoles
        ? z.string().min(1, "User group is required")
        : z.string(),
      status: z.string().min(1, "Status is required"),
      phone_country: z.string(),
      phone: z.string().trim().min(1, "Phone is required"),
      timezone: z.string().min(1, "Timezone is required"),
    })
    .refine((values) => values.email === values.confirm_email, {
      path: ["confirm_email"],
      message: "Email confirmation does not match",
    })
    .refine((values) => values.password === values.confirm_password, {
      path: ["confirm_password"],
      message: "Password confirmation does not match",
    });
}

const defaults: FormValues = {
  first_name: "",
  last_name: "",
  email: "",
  confirm_email: "",
  password: "",
  confirm_password: "",
  group_id: "",
  status: "active",
  phone_country: "AE",
  phone: "",
  timezone: "UTC",
};

function sanitizePhone(value: string) {
  return value.replace(/\D/g, "");
}

export function UserCreateForm({
  tenant,
  groups,
  canAssignRoles = false,
}: UserCreateFormProps) {
  const paths = adminPaths(tenant);
  const listHref = paths.users();
  const [avatarName, setAvatarName] = React.useState("");
  const avatarInput = React.useRef<HTMLInputElement>(null);

  const schema = React.useMemo(
    () => buildSchema(canAssignRoles),
    [canAssignRoles],
  );

  const form = useForm<FormValues>({
    resolver: zodResolver(schema),
    defaultValues: defaults,
  });

  const { isSaving, submit: submitForm } = useDashboardFormSubmit<FormValues>({
    mode: "create",
    createUrl: paths.usersCreateSubmit(),
    updateUrl: "",
    listHref,
    saveFailMessage: "User could not be created.",
    messages: {
      createFail: "User could not be created.",
      updateFail: "User could not be updated.",
      createSuccess: "User created successfully.",
      updateSuccess: "User updated.",
    },
  });

  const submit = React.useCallback(
    async (values: FormValues) => {
      const payload = canAssignRoles
        ? values
        : {
            first_name: values.first_name,
            last_name: values.last_name,
            email: values.email,
            confirm_email: values.confirm_email,
            password: values.password,
            confirm_password: values.confirm_password,
            status: values.status,
            phone_country: values.phone_country,
            phone: values.phone,
            timezone: values.timezone,
          };
      await submitForm(payload as FormValues);
    },
    [canAssignRoles, submitForm],
  );

  const errors = form.formState.errors;

  return (
    <form onSubmit={form.handleSubmit(submit)} className="flex min-h-full flex-col">
      <header className="mb-5 flex flex-wrap items-center justify-between gap-3 border-b pb-4">
        <div>
          <div className="flex items-center gap-2">
            <UserPlus className="size-5 text-primary" />
            <h1 className="text-xl font-semibold tracking-tight">Create User</h1>
          </div>
          <p className="mt-1 text-sm text-muted-foreground">
            {canAssignRoles
              ? "Add a sub-user and assign a permission group, status, and contact details."
              : "Add a sub-user with status and contact details."}
          </p>
        </div>
        <Button asChild type="button" variant="destructive" size="sm">
          <Link href={listHref}>
            <ArrowLeft />
            Cancel
          </Link>
        </Button>
      </header>

      <div className="space-y-5 pb-24">
        <section className="grid gap-4 rounded-lg border bg-card p-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" error={errors.last_name}>
            <Input id="last_name" className="h-9" {...form.register("last_name")} />
          </FormField>

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

          <FormField label="Password" htmlFor="password" required error={errors.password}>
            <Input
              id="password"
              type="password"
              className="h-9"
              placeholder="Password"
              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"
              placeholder="Confirm password"
              autoComplete="new-password"
              {...form.register("confirm_password")}
            />
          </FormField>

          <div className="grid gap-4 md:col-span-2 md:grid-cols-3">
            {canAssignRoles ? (
              <FormField label="User Group" htmlFor="group_id" required error={errors.group_id}>
                <Controller
                  name="group_id"
                  control={form.control}
                  render={({ field }) => (
                    <Select value={field.value} onValueChange={field.onChange}>
                      <SelectTrigger id="group_id" className="h-9 w-full">
                        <SelectValue placeholder="Select group" />
                      </SelectTrigger>
                      <SelectContent>
                        {groups.map((group) => (
                          <SelectItem key={group.group_id} value={String(group.group_id)}>
                            {group.name}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  )}
                />
              </FormField>
            ) : null}

            <FormField label="Status" htmlFor="status" required error={errors.status}>
              <Controller
                name="status"
                control={form.control}
                render={({ field }) => (
                  <Select value={field.value} onValueChange={field.onChange}>
                    <SelectTrigger id="status" className="h-9 w-full">
                      <SelectValue placeholder="Select status" />
                    </SelectTrigger>
                    <SelectContent>
                      {CUSTOMER_STATUSES.map((status) => (
                        <SelectItem key={status.value} value={status.value}>
                          {status.label}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                )}
              />
            </FormField>

            <FormField label="Phone" htmlFor="phone" required error={errors.phone}>
              <Controller
                name="phone"
                control={form.control}
                render={({ field: phoneField }) => (
                  <InputGroup>
                    <InputGroupAddon align="inline-start" className="border-r">
                      <Controller
                        name="phone_country"
                        control={form.control}
                        render={({ field }) => (
                          <Select value={field.value} onValueChange={field.onChange}>
                            <SelectTrigger className="h-7 w-28 border-0 bg-transparent shadow-none">
                              <SelectValue />
                            </SelectTrigger>
                            <SelectContent>
                              {PHONE_COUNTRIES.map((country) => (
                                <SelectItem key={country.code} value={country.code}>
                                  {country.flag} {country.dial}
                                </SelectItem>
                              ))}
                            </SelectContent>
                          </Select>
                        )}
                      />
                    </InputGroupAddon>
                    <InputGroupInput
                      id="phone"
                      placeholder="50 123 4567"
                      value={phoneField.value}
                      onChange={(event) => phoneField.onChange(sanitizePhone(event.target.value))}
                    />
                  </InputGroup>
                )}
              />
            </FormField>
          </div>

          <FormField
            label="Timezone"
            htmlFor="timezone"
            required
            error={errors.timezone}
            className="md:col-span-2"
          >
            <Controller
              name="timezone"
              control={form.control}
              render={({ field }) => (
                <Select value={field.value} onValueChange={field.onChange}>
                  <SelectTrigger id="timezone" className="h-9 w-full">
                    <SelectValue placeholder="Select timezone" />
                  </SelectTrigger>
                  <SelectContent>
                    {TIMEZONES.map((timezone) => (
                      <SelectItem key={timezone.value} value={timezone.value}>
                        {timezone.label === "UTC" ? "(GMT-00:00) UTC" : timezone.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              )}
            />
          </FormField>

          <FormField label="Avatar" htmlFor="avatar" className="md:col-span-2">
            <input
              ref={avatarInput}
              id="avatar"
              type="file"
              accept=".png,.jpg,.jpeg"
              className="sr-only"
              onChange={(event) => setAvatarName(event.target.files?.[0]?.name ?? "")}
            />
            <div className="flex min-h-16 items-center rounded-md border border-dashed px-3 py-2">
              <Button
                type="button"
                variant="outline"
                size="sm"
                onClick={() => avatarInput.current?.click()}
              >
                <Upload />
                {avatarName || "Browse"}
              </Button>
            </div>
          </FormField>
        </section>
      </div>

      <footer className="sticky bottom-0 z-20 mt-auto flex justify-end border-t bg-background/95 px-4 py-3 shadow-[0_-4px_20px_-10px_rgba(0,0,0,0.3)] backdrop-blur">
        <Button type="submit" disabled={isSaving}>
          <Save />
          {isSaving ? "Saving…" : "Save changes"}
        </Button>
      </footer>
    </form>
  );
}
