"use client";

import React, { useEffect, useMemo, useRef, useState } from "react";
import { Formik, Form, Field, ErrorMessage, FormikHelpers } from "formik";
import PhoneInput from "@/components/ui/PhoneInputField";
import GlobalLoadingOverlay from "@/components/ui/GlobalLoadingOverlay";
import apiClient from "@/lib/apiClient";
import { logger } from "@/lib/logger";
import {
  CreatorFormValues,
  creatorInitialValues,
  creatorValidationSchema,
  SOCIAL_ITEMS,
} from "./types";
import {
  PrivacyConsentField,
  ApplyFormStatus,
  ApplySubmitButton,
} from "./CommonApplyFields";

interface CreatorApplyFormProps {
  apiError: string;
  successMessage: string;
  onSubmit: (
    values: CreatorFormValues,
    helpers: FormikHelpers<CreatorFormValues>,
  ) => Promise<void>;
}

type ApplyBrandOption = {
  name: string;
  logo?: string;
};

function parseAdvertisersPayload(payload: unknown): ApplyBrandOption[] {
  const body = (payload ?? {}) as Record<string, unknown>;
  const nested = (body.data ?? {}) as Record<string, unknown>;
  const rawList = Array.isArray(nested.advertisers)
    ? nested.advertisers
    : Array.isArray(body.advertisers)
      ? body.advertisers
      : [];

  return rawList
    .map((item): ApplyBrandOption | null => {
      const advertiser = item as { name?: string; logo?: string };
      const name = String(advertiser?.name || "").trim();
      if (!name) return null;

      const logo = String(advertiser?.logo || "").trim();
      return logo ? { name, logo } : { name };
    })
    .filter((item): item is ApplyBrandOption => item !== null);
}

let cachedBrandOptions: ApplyBrandOption[] | null = null;
let brandOptionsRequest: Promise<ApplyBrandOption[]> | null = null;

function loadApplyBrandOptions(): Promise<ApplyBrandOption[]> {
  if (cachedBrandOptions) {
    return Promise.resolve(cachedBrandOptions);
  }

  if (!brandOptionsRequest) {
    brandOptionsRequest = apiClient
      .get("/contact/advertisers")
      .then((response) => {
        const advertisers = parseAdvertisersPayload(response?.data);
        cachedBrandOptions =
          advertisers.length > 0 ? advertisers : [];
        return cachedBrandOptions;
      })
      .catch((error) => {
        logger.error("Failed to load apply-form brands:", error);
        brandOptionsRequest = null;
        return Promise.resolve([]);
      });
  }

  return brandOptionsRequest;
}

export default function CreatorApplyForm({
  apiError,
  successMessage,
  onSubmit,
}: CreatorApplyFormProps) {
  const [brandDropdownOpen, setBrandDropdownOpen] = useState(false);
  const [brandSearch, setBrandSearch] = useState("");
  const [brandOptions, setBrandOptions] = useState<ApplyBrandOption[]>(
    () => cachedBrandOptions ?? [],
  );
  const [brandsLoading, setBrandsLoading] = useState(() => !cachedBrandOptions);
  const brandDropdownRef = useRef<HTMLDivElement | null>(null);
  const brandSearchRef = useRef<HTMLInputElement | null>(null);

  useEffect(() => {
    let cancelled = false;

    void loadApplyBrandOptions().then((options) => {
      if (!cancelled) {
        setBrandOptions(options);
        setBrandsLoading(false);
      }
    });

    return () => {
      cancelled = true;
    };
  }, []);

  useEffect(() => {
    if (!brandDropdownOpen) return;

    const handleOutsideClick = (event: MouseEvent) => {
      if (
        brandDropdownRef.current &&
        !brandDropdownRef.current.contains(event.target as Node)
      ) {
        setBrandDropdownOpen(false);
      }
    };

    const handleEscape = (event: KeyboardEvent) => {
      if (event.key === "Escape") {
        setBrandDropdownOpen(false);
      }
    };

    document.addEventListener("mousedown", handleOutsideClick);
    document.addEventListener("keydown", handleEscape);
    brandSearchRef.current?.focus();

    return () => {
      document.removeEventListener("mousedown", handleOutsideClick);
      document.removeEventListener("keydown", handleEscape);
    };
  }, [brandDropdownOpen]);

  const filteredBrandOptions = useMemo(() => {
    const search = brandSearch.trim().toLowerCase();

    if (!search) {
      return brandOptions;
    }

    return brandOptions.filter((brand) =>
      brand.name.toLowerCase().includes(search),
    );
  }, [brandOptions, brandSearch]);

  const toggleBrand = (
    brandName: string,
    currentBrands: string[],
    setFieldValue: (field: string, value: string[]) => void,
  ) => {
    if (currentBrands.includes(brandName)) {
      setFieldValue(
        "brands",
        currentBrands.filter((selectedBrand) => selectedBrand !== brandName),
      );
      return;
    }

    setFieldValue("brands", [...currentBrands, brandName]);
  };

  return (
    <Formik<CreatorFormValues>
      initialValues={creatorInitialValues}
      validationSchema={creatorValidationSchema}
      onSubmit={onSubmit}
      validateOnBlur
      validateOnChange
    >
      {({ isSubmitting, setFieldValue, values }) => (
        <Form className="">
          <GlobalLoadingOverlay show={isSubmitting} />

          <div className="row g-3">
            <div className="col-md-6">
              <label htmlFor="firstName" className="form-check-label">
                First Name <span className="color-second">*</span>
              </label>

              <Field
                placeholder="First Name"
                className="form-control"
                type="text"
                name="firstName"
              />

              <ErrorMessage
                name="firstName"
                component="div"
                className="invalid-feedback d-block"
              />
            </div>

            <div className="col-md-6">
              <label htmlFor="lastName" className="form-check-label">
                Last Name <span className="color-second">*</span>
              </label>

              <Field
                placeholder="Last Name"
                className="form-control"
                type="text"
                name="lastName"
              />

              <ErrorMessage
                name="lastName"
                component="div"
                className="invalid-feedback d-block"
              />
            </div>

            <div className="col-md-6">
              <label htmlFor="email" className="form-check-label">
                Email ID <span className="color-second">*</span>
              </label>

              <Field
                placeholder="Email ID"
                className="form-control"
                type="email"
                name="email"
              />

              <ErrorMessage
                name="email"
                component="div"
                className="invalid-feedback d-block"
              />
            </div>

            <div className="col-md-6">
              <label className="form-check-label">
                Phone Number <span className="color-second">*</span>
              </label>

              <div className="position-relative request-code-input">
                <PhoneInput />
              </div>
            </div>

            <div className="col-md-6">
              <label htmlFor="country" className="form-check-label">
                Country <span className="color-second">*</span>
              </label>

              <Field
                as="select"
                name="country"
                className="form-select custom-select-box"
              >
                <option value="" disabled>
                  Select Country
                </option>

                <option value="US">US</option>
                <option value="UK">UK</option>
              </Field>

              <ErrorMessage
                name="country"
                component="div"
                className="invalid-feedback d-block"
              />
            </div>

            <div className="col-md-6">
              <label htmlFor="state" className="form-check-label">
                State <span className="color-second">*</span>
              </label>

              <Field
                placeholder="State"
                className="form-control"
                type="text"
                name="state"
              />

              <ErrorMessage
                name="state"
                component="div"
                className="invalid-feedback d-block"
              />
            </div>

            <div className="col-md-6">
              <label htmlFor="city" className="form-check-label">
                City <span className="color-second">*</span>
              </label>

              <Field
                placeholder="City"
                className="form-control"
                type="text"
                name="city"
              />

              <ErrorMessage
                name="city"
                component="div"
                className="invalid-feedback d-block"
              />
            </div>

            <div className="col-md-6">
              <label htmlFor="zipCode" className="form-check-label">
                Zip Code <span className="color-second">*</span>
              </label>

              <Field
                placeholder="Zip Code"
                className="form-control"
                type="text"
                name="zipCode"
              />

              <ErrorMessage
                name="zipCode"
                component="div"
                className="invalid-feedback d-block"
              />
            </div>

            <div className="col-12">
              <label htmlFor="addressLine1" className="form-check-label">
                Address Line 1 <span className="color-second">*</span>
              </label>

              <Field
                placeholder="Address Line 1"
                className="form-control"
                type="text"
                name="addressLine1"
              />

              <ErrorMessage
                name="addressLine1"
                component="div"
                className="invalid-feedback d-block"
              />
            </div>

            <div className="col-12">
              <label htmlFor="addressLine2" className="form-check-label">
                Address Line 2
              </label>

              <Field
                placeholder="Address Line 2"
                className="form-control"
                type="text"
                name="addressLine2"
              />
            </div>

            <div className="col-12 creator-brand-field-col">
              <div className="creator-brand-field">
                <label htmlFor="brandSelectBox" className="form-check-label">
                  Select the brand(s) you’d like to promote on Influential
                </label>

                <div
                  className="brand-multiselect"
                  id="brandDropdown"
                  ref={brandDropdownRef}
                >
                  <button
                    type="button"
                    className="brand-select-box"
                    id="brandSelectBox"
                    aria-haspopup="listbox"
                    aria-expanded={brandDropdownOpen}
                    onClick={() => setBrandDropdownOpen((prev) => !prev)}
                  >
                    <div className="selected-brands" id="selectedBrands">
                      {values.brands.length > 0 ? (
                        values.brands.map((brand) => (
                          <span className="selected-brand" key={brand}>
                            <span>{brand}</span>

                            <span
                              role="button"
                              tabIndex={0}
                              className="remove-brand"
                              onClick={(event) => {
                                event.stopPropagation();
                                setFieldValue(
                                  "brands",
                                  values.brands.filter(
                                    (selectedBrand) => selectedBrand !== brand,
                                  ),
                                );
                              }}
                              onKeyDown={(event) => {
                                if (event.key === "Enter" || event.key === " ") {
                                  event.preventDefault();
                                  event.stopPropagation();
                                  setFieldValue(
                                    "brands",
                                    values.brands.filter(
                                      (selectedBrand) =>
                                        selectedBrand !== brand,
                                    ),
                                  );
                                }
                              }}
                              aria-label={`Remove ${brand}`}
                            >
                              ×
                            </span>
                          </span>
                        ))
                      ) : (
                        <span className="brand-placeholder">
                          Select brand(s)
                        </span>
                      )}
                    </div>

                    <svg
                      className="brand-arrow"
                      width="18"
                      height="18"
                      viewBox="0 0 24 24"
                      fill="none"
                      stroke="currentColor"
                      strokeWidth="2"
                      aria-hidden="true"
                    >
                      <path d="m6 9 6 6 6-6" />
                    </svg>
                  </button>

                  {brandDropdownOpen && (
                    <div
                      className="brand-dropdown-menu"
                      id="brandDropdownMenu"
                      role="listbox"
                      aria-multiselectable="true"
                      aria-label="Select brands"
                    >
                      <div className="brand-search">
                        <svg
                          width="18"
                          height="18"
                          viewBox="0 0 24 24"
                          fill="none"
                          stroke="currentColor"
                          strokeWidth="2"
                          aria-hidden="true"
                        >
                          <circle cx="11" cy="11" r="7" />
                          <path d="m20 20-4-4" />
                        </svg>

                        <input
                          type="text"
                          id="brandSearch"
                          placeholder="Search brands..."
                          autoComplete="off"
                          value={brandSearch}
                          ref={brandSearchRef}
                          onChange={(event) =>
                            setBrandSearch(event.target.value)
                          }
                          onClick={(event) => event.stopPropagation()}
                        />
                      </div>

                      <div className="brand-options" id="brandOptions">
                        {brandsLoading && (
                          <div className="brand-no-results">
                            Loading brands...
                          </div>
                        )}

                        {!brandsLoading &&
                          filteredBrandOptions.map((brand) => {
                            const isSelected = values.brands.includes(
                              brand.name,
                            );

                            return (
                              <button
                                type="button"
                                className={`brand-option ${isSelected ? "selected" : ""
                                  }`}
                                data-brand={brand.name}
                                key={brand.name}
                                role="option"
                                aria-selected={isSelected}
                                onClick={() =>
                                  toggleBrand(
                                    brand.name,
                                    values.brands,
                                    setFieldValue,
                                  )
                                }
                              >
                                {brand.logo ? (
                                  // eslint-disable-next-line @next/next/no-img-element
                                  <img src={brand.logo} alt="" />
                                ) : (
                                  <span className="brand-logo-fallback">
                                    {brand.name.charAt(0)}
                                  </span>
                                )}

                                <span>{brand.name}</span>

                                <span
                                  className="brand-check"
                                  aria-hidden="true"
                                >
                                  {isSelected ? "✓" : ""}
                                </span>
                              </button>
                            );
                          })}

                        {!brandsLoading &&
                          filteredBrandOptions.length === 0 && (
                            <div
                              className="brand-no-results"
                              id="brandNoResults"
                            >
                              No brands found
                            </div>
                          )}
                      </div>
                    </div>
                  )}
                </div>
              </div>
            </div>

            <p className="color-second fw-600 mt-3 mb-0">
              Social Media Platform
            </p>

            <div className="col-md-8 col-12">
              <label htmlFor="contentNiche" className="form-check-label">
                Content Niche <span className="color-second">*</span>
              </label>

              <Field
                placeholder=""
                className="form-control"
                type="text"
                name="contentNiche"
              />

              <ErrorMessage
                name="contentNiche"
                component="div"
                className="invalid-feedback d-block"
              />
            </div>

            <div className="col-md-4 col-12">
              <label htmlFor="audienceSizeRange" className="form-check-label">
                Audience Size Range <span className="color-second">*</span>
              </label>

              <Field
                as="select"
                name="audienceSizeRange"
                className="form-select custom-select-box"
              >
                <option value="" disabled>
                  Select Audience Size Range
                </option>

                <option value="size1">10,000 – 50,000</option>
                <option value="size2">50,000 – 100,000</option>
                <option value="size3">100,000 – 250,000</option>
                <option value="size4">250,000 – 500,000</option>
                <option value="size5">500,000 – 1M</option>
                <option value="size6">1M+</option>
              </Field>

              <ErrorMessage
                name="audienceSizeRange"
                component="div"
                className="invalid-feedback d-block"
              />
            </div>

            <div id="social-media-section">
              <p className="color-second fw-600 mb-3">
                Select the social media platforms* :
              </p>

              <div className="row g-3">
                {SOCIAL_ITEMS.map((item) => {
                  const isChecked = values[item.checkName];

                  return (
                    <div className="col-md-6" key={item.id}>
                      <div className="social-item d-flex align-items-center">
                        <div
                          className="d-flex align-items-center"
                          style={{ minWidth: "100px" }}
                        >
                          <input
                            className="form-check-input social-link-check me-2"
                            id={item.id}
                            type="checkbox"
                            checked={isChecked || false}
                            onChange={(e) => {
                              const checked = e.target.checked;

                              setFieldValue(item.checkName, checked);

                              if (!checked) {
                                setFieldValue(item.name, "");
                              }
                            }}
                          />

                          <label
                            htmlFor={item.id}
                            className="form-check-label mb-0"
                          >
                            {item.label}
                          </label>
                        </div>

                        {isChecked && (
                          <div className="flex-grow-1 ms-3">
                            <Field
                              placeholder={item.placeholder}
                              className="form-control social-link-input"
                              type="text"
                              name={item.name}
                            />
                          </div>
                        )}
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>

            <PrivacyConsentField />

            <ApplyFormStatus
              apiError={apiError}
              successMessage={successMessage}
            />

            <ApplySubmitButton isSubmitting={isSubmitting} />
          </div>
        </Form>
      )}
    </Formik>
  );
}
