import { PasswordIcon } from "@/assets/icons";
import {
  createPhoneFieldRules,
  PhoneNumberInput,
} from "@/components/FormElements/PhoneNumberInput";
import type { DynamicFormSection } from "@/components/forms/DynamicFormBuilder";
import FileImageUploadCard from "@/components/ui/FileImageUploadCard";
import { FormErrorMessages } from "@/constants/Texts";
import type { Dispatch, SetStateAction } from "react";
import { Controller, type UseFormRegisterReturn } from "react-hook-form";
import { v4 as uuidv4 } from "uuid";
import type { CreateAdminFormValues } from "./createAdminForm.types";

const adminSectionId = uuidv4();

interface CreateAdminFormSectionsOptions {
  editMode?: boolean;
  passwordFieldInputType: "password" | "text";
  setPasswordFieldInputType: Dispatch<SetStateAction<"password" | "text">>;
  profileImageRegister: UseFormRegisterReturn;
  isUploadingImage: boolean;
  uploadProgress: number;
  previewUrl: string | null;
  selectedFileName: string;
  selectedFileSize: number | null;
  clearSelectedProfileImage: () => void;
}

export const createAdminFormSections = ({
  editMode,
  passwordFieldInputType,
  setPasswordFieldInputType,
  profileImageRegister,
  isUploadingImage,
  uploadProgress,
  previewUrl,
  selectedFileName,
  selectedFileSize,
  clearSelectedProfileImage,
}: CreateAdminFormSectionsOptions): DynamicFormSection<CreateAdminFormValues>[] => [
  {
    id: adminSectionId,
    title: "Input Fields",
    fields: [
      {
        kind: "input",
        name: "full_name",
        label: "Full name",
        type: "text",
        placeholder: "Enter full name (5-100 characters)",
        required: true,
        dataCy: "admin-form-full-name-input",
        rules: {
          required: { message: FormErrorMessages.required, value: true },
          minLength: { value: 5, message: FormErrorMessages.minLength(5) },
          maxLength: { value: 100, message: FormErrorMessages.maxLength(100) },
        },
      },
      {
        kind: "input",
        name: "username",
        label: "Username",
        type: "text",
        placeholder: "Letters and numbers only (3-30)",
        autoComplete: "off",
        required: true,
        dataCy: "admin-form-username-input",
        rules: {
          required: { value: true, message: FormErrorMessages.required },
          pattern: {
            value: /^[a-zA-Z0-9]+$/,
            message: FormErrorMessages.alphaNumeric,
          },
          minLength: { value: 3, message: FormErrorMessages.minLength(3) },
          maxLength: { value: 30, message: FormErrorMessages.maxLength(30) },
        },
      },
      {
        kind: "input",
        name: "email",
        label: "Email",
        type: "email",
        placeholder: "you@example.com",
        autoComplete: "off",
        required: true,
        dataCy: "admin-form-email-input",
        rules: {
          required: { value: true, message: FormErrorMessages.required },
          pattern: {
            value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
            message: FormErrorMessages.invalidEmail,
          },
        },
      },
      {
        kind: "input",
        name: "password",
        label: "Password",
        type: passwordFieldInputType,
        placeholder: "At least 8 characters",
        autoComplete: "new-password",
        required: true,
        hidden: editMode,
        dataCy: "admin-form-password-input",
        icon: (
          <button
            type="button"
            onClick={() =>
              setPasswordFieldInputType(
                passwordFieldInputType === "password" ? "text" : "password",
              )
            }
            className="absolute right-4.5 top-1/2 z-10 flex h-6 w-6 -translate-y-1/2 items-center justify-center rounded text-dark-5 transition hover:text-primary dark:text-white/75 [&>svg]:!static [&>svg]:!size-5 [&>svg]:!translate-y-0"
            aria-label={
              passwordFieldInputType === "password"
                ? "Show password"
                : "Hide password"
            }
          >
            <PasswordIcon className="pointer-events-none" />
          </button>
        ),
        rules: {
          required: { value: true, message: FormErrorMessages.required },
          minLength: { value: 8, message: FormErrorMessages.minLength(8) },
          maxLength: { value: 128, message: FormErrorMessages.maxLength(128) },
        },
      },
      {
        kind: "custom",
        name: "phone",
        render: ({ control, errors }) => (
          <Controller
            name="phone"
            control={control}
            rules={createPhoneFieldRules({ required: false })}
            render={({ field }) => (
              <PhoneNumberInput
                label="Phone"
                value={field.value ?? ""}
                onChange={field.onChange}
                onBlur={field.onBlur}
                error={errors.phone?.message as string | undefined}
                dataCy="admin-form-phone-input"
              />
            )}
          />
        ),
      },
      {
        kind: "input",
        name: "department",
        label: "Department",
        type: "text",
        dataCy: "admin-form-department-input",
        rules: {
          minLength: { value: 2, message: FormErrorMessages.minLength(2) },
          maxLength: { value: 100, message: FormErrorMessages.maxLength(100) },
        },
      },
      {
        kind: "input",
        name: "position",
        label: "Position",
        type: "text",
        dataCy: "admin-form-position-input",
        rules: {
          minLength: { value: 2, message: FormErrorMessages.minLength(2) },
          maxLength: { value: 100, message: FormErrorMessages.maxLength(100) },
        },
      },
      {
        kind: "custom",
        name: "profile_image",
        render: ({ error }) => (
          <FileImageUploadCard
            label="Profile image"
            inputId="profile-image-upload"
            fileRegister={profileImageRegister}
            isLoading={isUploadingImage}
            uploadProgress={uploadProgress}
            previewUrl={previewUrl}
            selectedFileName={selectedFileName}
            selectedFileSize={selectedFileSize}
            onClear={clearSelectedProfileImage}
            errorMessage={error}
          />
        ),
      },
    ],
  },
];
