import { EyeIcon, GlobeIcon } from "@/assets/icons";
import MultiSelect from "@/components/FormElements/MultiSelect";
import {
  createPhoneFieldRules,
  PhoneNumberInput,
} from "@/components/FormElements/PhoneNumberInput";
import { Select } from "@/components/FormElements/select";
import type { DynamicFormSection } from "@/components/forms/DynamicFormBuilder";
import { AdminRoles } from "@/constants/enums";
import { REGEX } from "@/constants/regex";
import { FormErrorMessages } from "@/constants/Texts";
import type { CreateCustomerCredentials } from "@/lib/api";
import type { ILabelValue } from "@/types/shared";
import { getEnumAsArray } from "@/utils/shared";
import type { Dispatch, SetStateAction } from "react";
import { Controller, type UseFormWatch } from "react-hook-form";
import { v4 as uuidv4 } from "uuid";

const customerSectionId = uuidv4();

interface CustomerFormSectionsOptions {
  editMode?: boolean;
  companyItems: ILabelValue[];
  watch: UseFormWatch<CreateCustomerCredentials>;
  showPassword: boolean;
  setShowPassword: Dispatch<SetStateAction<boolean>>;
}

export const createCustomerFormSections = ({
  editMode,
  companyItems,
  watch,
  showPassword,
  setShowPassword,
}: CustomerFormSectionsOptions): DynamicFormSection<CreateCustomerCredentials>[] => [
  {
    id: customerSectionId,
    title: "Create Customer",
    className: "gap-5",
    fields: [
      {
        kind: "input",
        name: "username",
        label: "Username",
        type: "text",
        placeholder: "Unique login, letters and numbers only",
        required: true,
        rules: {
          required: { value: true, message: FormErrorMessages.required },
          minLength: { value: 3, message: FormErrorMessages.minLength(3) },
          maxLength: { value: 30, message: FormErrorMessages.maxLength(30) },
          pattern: {
            value: REGEX.USERNAME,
            message: FormErrorMessages.invalidPattern,
          },
        },
      },
      {
        kind: "custom",
        name: "companies",
        render: ({ register, errors }) => (
          <MultiSelect<CreateCustomerCredentials>
            label="Select companies"
            value={watch("companies")}
            items={companyItems}
            {...register("companies")}
            errors={errors}
            placeholder=""
          />
        ),
      },
      {
        kind: "input",
        name: "email",
        label: "Email",
        type: "email",
        placeholder: "name@company.com",
        required: true,
        rules: {
          required: { value: true, message: FormErrorMessages.required },
          pattern: {
            value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
            message: FormErrorMessages.invalidEmail,
          },
        },
      },
      {
        kind: "custom",
        name: "role",
        render: ({ register, errors }) => (
          <Select<CreateCustomerCredentials>
            label="Role"
            {...register("role", {
              required: { message: FormErrorMessages.required, value: true },
            })}
            errors={errors}
            name="role"
            value={watch("role")}
            items={getEnumAsArray(AdminRoles)}
            placeholder="Choose a role"
            required
          />
        ),
      },
      {
        kind: "input",
        name: "password",
        label: "Password",
        type: showPassword ? "text" : "password",
        placeholder: "At least 8 characters",
        required: !editMode,
        disabled: editMode,
        hidden: editMode,
        iconPosition: "right",
        icon: (
          <button
            type="button"
            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"
            onClick={() => setShowPassword((visible) => !visible)}
            aria-label={showPassword ? "Hide password" : "Show password"}
          >
            <EyeIcon />
          </button>
        ),
        rules: {
          required: { value: true, message: FormErrorMessages.required },
          minLength: { value: 8, message: FormErrorMessages.minLength(8) },
          maxLength: { value: 128, message: FormErrorMessages.maxLength(128) },
        },
      },
      {
        kind: "input",
        name: "full_name",
        label: "Full name",
        type: "text",
        rules: {
          minLength: { value: 2, message: FormErrorMessages.minLength(2) },
          maxLength: { value: 100, message: FormErrorMessages.maxLength(100) },
        },
      },
      {
        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}
              />
            )}
          />
        ),
      },
      {
        kind: "custom",
        name: "type",
        render: ({ register, errors }) => (
          <Select<CreateCustomerCredentials>
            {...register("type", {
              required: {
                message: FormErrorMessages.required,
                value: true,
              },
            })}
            errors={errors}
            name="type"
            label="Type"
            required
            value={watch("type")}
            placeholder="Choose customer type"
            prefixIcon={<GlobeIcon />}
            items={[
              { label: "Individual", value: "individual" },
              { label: "Company", value: "company" },
              { label: "Government", value: "government" },
            ]}
          />
        ),
      },
    ],
  },
];
