"use client";
import { handleApiError } from "@/lib/apiErrorHandler";
import { sanitizeText } from "@/lib/sanitize";
import { createFieldValidation } from "@/lib/validation";
import api from "@/service/api";
import { CmsContact } from "@/types/TCms";
import HCaptcha from "@hcaptcha/react-hcaptcha";
import { useMemo, useRef, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "react-toastify";
import InputGroup from "../_components/InputGroup";
import Loading from "../_components/Loading";

type TInquiresForm = {
  [key: string]: string;
};

type InquiresFormProps = {
  columnsPerRow?: 1 | 2 | 3 | 4;
  buttonText?: string;
  contactData?: CmsContact;
};

const InquiresForm = ({
  columnsPerRow = 2,
  buttonText,
  contactData,
}: InquiresFormProps) => {
  const [isLoading, setIsLoading] = useState(false);
  const [hcaptchaToken, setHcaptchaToken] = useState<string | null>(null);
  const captchaRef = useRef<HCaptcha>(null);
  const {
    register,
    handleSubmit,
    formState: { errors, isValid },
    reset,
    setError,
    trigger,
  } = useForm<TInquiresForm>({ mode: "onChange" });

  const defaultFields = useMemo(
    () => [
      {
        name: "full_name",
        label: "Full Name",
        placeholder: "",
        required: true,
      },
      {
        name: "company_name",
        label: "Company Name",
        placeholder: "",
        required: true,
      },
      {
        name: "work_email",
        label: "Work Email",
        placeholder: "",
        required: true,
      },
      {
        name: "phone_number",
        label: "Phone Number",
        placeholder: "",
        required: true,
      },
    ],
    [],
  );

  const fields = contactData?.fields || defaultFields;
  const formFieldNames = useMemo(() => fields.map((f) => f.name), [fields]);

  const onCaptchaVerify = (token: string) => {
    setHcaptchaToken(token);
  };

  const onCaptchaExpire = () => {
    setHcaptchaToken(null);
  };
  const onSubmit = async (data: TInquiresForm) => {
    const sanitizedData = Object.fromEntries(
      Object.entries(data).map(([key, value]) => [
        key,
        typeof value === "string" ? value.trim() : value,
      ]),
    ) as TInquiresForm;

    const requiredFields = fields.filter((field) => field.required);
    let hasEmptyRequiredField = false;

    requiredFields.forEach((field) => {
      const value = sanitizedData[field.name];
      if (!value) {
        setError(field.name, {
          type: "required",
          message: `${field.label} is required`,
        });
        hasEmptyRequiredField = true;
      }
    });

    if (hasEmptyRequiredField) {
      toast.error("Please complete all required fields");
      return;
    }

    const isFormValid = await trigger(formFieldNames);
    if (!isFormValid) {
      toast.error("Please correct invalid form fields");
      return;
    }

    if (!hcaptchaToken) {
      toast.error("Please complete the captcha verification");
      return;
    }
    setIsLoading(true);
    try {
      const response = (
        await api.post("inquiries", {
          ...sanitizedData,
          hcaptcha_token: hcaptchaToken,
        })
      ).data;
      toast.success(response.message);
      reset();
      setHcaptchaToken(null);
      captchaRef.current?.resetCaptcha();
    } catch (error) {
      handleApiError(error, setError, toast.error, formFieldNames);
    } finally {
      setIsLoading(false);
    }
  };

  const gridColsClass = {
    1: "lg:grid-cols-1",
    2: "lg:grid-cols-2",
    3: "lg:grid-cols-3",
    4: "lg:grid-cols-4",
  }[columnsPerRow];

  const colSpanClass = {
    1: "lg:col-span-1",
    2: "lg:col-span-2",
    3: "lg:col-span-3",
    4: "lg:col-span-4",
  }[columnsPerRow];

  const submitText =
    sanitizeText(contactData?.submit_button_text) || buttonText || "Submit";

  /**
   * Creates validation rules based on field type with XSS protection
   */
  const getFieldValidation = (field: {
    name: string;
    label: string;
    required?: boolean;
  }) => {
    const isEmailField =
      field.name.includes("email") || field.name === "work_email";
    const isPhoneField =
      field.name.includes("phone") || field.name === "phone_number";
    const isStrictTextField =
      field.name === "full_name" || field.name === "company_name";

    if (isPhoneField) {
      return createFieldValidation(field.label, field.required, {
        pattern: {
          value: /^[+\d\s()-]+$/,
          message:
            "Please enter a valid phone number (digits, +, spaces, parentheses, and dashes only)",
        },
        minLength: field.required
          ? { value: 10, message: "Phone number must be at least 10 digits" }
          : undefined,
        maxLength: {
          value: 20,
          message: "Phone number must not exceed 20 characters",
        },
      });
    }

    if (isEmailField) {
      return createFieldValidation(field.label, field.required, {
        pattern: {
          value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
          message: "Please enter a valid email address",
        },
      });
    }

    if (isStrictTextField) {
      return createFieldValidation(field.label, field.required, {
        minLength: field.required
          ? {
              value: 2,
              message: `${field.label} must be at least 2 characters`,
            }
          : undefined,
        maxLength: {
          value: 200,
          message: `${field.label} must not exceed 200 characters`,
        },
        pattern: {
          value: /^[\p{L}\p{M}\p{N}\s'.,()&/_-]+$/u,
          message: `${field.label} may only include letters, numbers, spaces, and common punctuation (no HTML or code)`,
        },
      });
    }

    return createFieldValidation(field.label, field.required, {
      maxLength: {
        value: 200,
        message: `${field.label} must not exceed 200 characters`,
      },
    });
  };

  return (
    <form
      className={`w-full px-4 lg:px-16 py-10 grid ${gridColsClass} gap-4`}
      onSubmit={handleSubmit(onSubmit)}>
      {fields.map((field) => {
        const inputType =
          field.name.includes("email") || field.name === "work_email"
            ? "email"
            : "text";

        return (
          <InputGroup
            key={field.name}
            id={field.name}
            label={sanitizeText(field.label)}
            placeholder={sanitizeText(field.placeholder)}
            register={register}
            type={inputType}
            error={errors[field.name]?.message}
            validation={getFieldValidation(field)}
          />
        );
      })}
      <div className={`${colSpanClass}`}>
        <HCaptcha
          sitekey={process.env.NEXT_PUBLIC_HCAPTCHA_SITE_KEY || ""}
          onVerify={onCaptchaVerify}
          onExpire={onCaptchaExpire}
          ref={captchaRef}
        />
      </div>
      <div className={`${colSpanClass} flex justify-end`}>
        <button
          type="submit"
          disabled={!isValid || isLoading || !hcaptchaToken}
          className="bg-(--primary) cursor-pointer inline-flex items-center justify-center min-h-14 w-fit text-white rounded-full py-4 px-6 disabled:opacity-60 disabled:cursor-not-allowed">
          {isLoading ? <Loading /> : submitText}
        </button>
      </div>
    </form>
  );
};

export default InquiresForm;
