import { useEffect, useState } from "react";
import type { ContactInfo } from "../types";
import { getContactInfo } from "../helpers/getContactInfo.helper";
import { createContact, updateHubspotInfo } from "../apis";
import { getARCAInformation } from "../services/getARCAInformation.service";
import { getHubspotContact } from "../services/getHubSpotInformation.service";
import {
  formatPhoneNumber,
  isValidPhoneNumber,
} from "../helpers/formatPhoneNumber";
import { isValidEmail } from "../helpers/getBestEmail.helper";

export const enum Step {
  ARCA_VALIDATED,
  EXISTS,
  CREATE,
  TICKET,
}

const predefContactInfo = {
  hs_id: "",
  cuit: "",
  name: "",
  last_name: "",
  landline: "",
  mobile: "",
  email: "",
  email_type: "",
};

export const usePanelController = () => {
  const [formStep, setFormStep] = useState(Step.ARCA_VALIDATED);
  const [currentCUIT, setCurrentCUIT] = useState("");

  // estados del botón submit
  const [isLoading, setIsLoading] = useState(false);
  const [disableButton, setDisableButton] = useState(false);

  const [formSubmitted, setFormSubmitted] = useState(false);

  const [showCUITError, setShowCUITError] = useState<string | null>(null);
  const [needToUpdate, setNeedToUpdate] = useState(false);
  const [showCreationError, setShowCreationError] = useState<
    "Creation" | "Duplicate" | "Update" | null
  >(null);
  const [ticketText, setTicketText] = useState("");

  const [contactInfo, setContactInfo] =
    useState<ContactInfo>(predefContactInfo);

  useEffect(() => {
    if (formStep === Step.ARCA_VALIDATED || formStep === Step.TICKET) {
      return setDisableButton(false);
    }
    setDisableButton(
      contactInfo.email.length < 1 ||
        !isValidEmail(contactInfo.email) ||
        contactInfo.mobile.length < 1 ||
        !isValidPhoneNumber(contactInfo.mobile) ||
        contactInfo.landline.length < 1 ||
        !isValidPhoneNumber(contactInfo.landline),
    );
  }, [formStep, contactInfo]);

  const handleCUIT = (value: string) => {
    setCurrentCUIT(value);
  };

  // Esto es un reset de estado
  const handleClosePanel = () => {
    setContactInfo(predefContactInfo);
    setShowCUITError(null);
    setFormSubmitted(false);
    setCurrentCUIT("");
    setFormStep(Step.ARCA_VALIDATED);

    setIsLoading(false);

    setTicketText("");

    setShowCreationError(null);
    setNeedToUpdate(false);
  };

  const handleSubmit = (e: any) => {
    switch (formStep) {
      case Step.ARCA_VALIDATED:
        handleCUITSubmit();
        break;
      case Step.CREATE:
        handleNewContact();
        break;
      case Step.EXISTS:
        handleExistingContact();
        break;
    }
  };

  const showTicketSection = () => {
    const standarizedTicketName = `${contactInfo.name} - ${contactInfo.last_name} - ${contactInfo.cuit}`;
    setTicketText(standarizedTicketName);
    setFormStep(Step.TICKET);
    setFormSubmitted(true);
  };

  const handleError = (
    status: "ErrorDuplicate" | "ok" | "ErrorCreation" | "ErrorUpdate",
  ) => {
    switch (status) {
      case "ErrorDuplicate":
        setShowCreationError("Duplicate");
        break;
      case "ErrorCreation":
        setShowCreationError("Creation");
        break;
      case "ErrorUpdate":
        setShowCreationError("Update");
        break;

      default:
        break;
    }
  };

  const isValidCUIT = (cuit: string) => {
    if (!/^\d+$/.test(cuit)) return false;
    if (cuit.length < 8) return false;
    return true;
  };

  /**
   * Esta función gestiona el primer paso, donde validCUIT si el CUIT ingresado
   * existe utilizando una API de ARCA.
   * De existir, se buscará en HubSpot el contacto:
   * - Si el contacto existe, se manda al paso de revisión.
   * - Si el contacto no existe, uso la información de ARCA para llenar el formulario
   * y permitirle al usuario validar y crear al contacto.
   *
   */
  const handleCUITSubmit = async () => {
    setShowCUITError(null);
    setIsLoading(true);

    // limpio el CUIT de posibles caracteres o espacios de sobra
    const validCUIT = currentCUIT.toString().replace(/[-\s]/g, "").trim();
    if (!isValidCUIT(validCUIT)) {
      setIsLoading(false);
      return setShowCUITError("Este CUIT no es válido.");
    }

    const responseARCA = await getARCAInformation(validCUIT);
    if (!responseARCA.ok) {
      setShowCUITError("Este Cuit no se encontró en los registros de ARCA.");
      setIsLoading(false);
      return;
    }
    const info = responseARCA.response.result;

    const hsResponse = await getHubspotContact(validCUIT);
    console.log("Testing desde el hook: ", hsResponse);
    if (hsResponse.found) {
      const hsData = hsResponse.contact;
      const temp = getContactInfo(info, validCUIT, hsData);
      if (temp.email !== hsData.properties.email) setNeedToUpdate(true);
      setContactInfo(temp);
      setFormStep(Step.EXISTS);
    } else {
      setContactInfo(getContactInfo(info, validCUIT, null));
      setFormStep(Step.CREATE);
    }

    setIsLoading(false);
  };

  const handleNewContact = async () => {
    const body = {
      firstname: contactInfo.name,
      lastname: contactInfo.last_name,
      cuil: contactInfo.cuit,
      phone: contactInfo.landline,
      phoneType: "FIJO",
      email: contactInfo.email,
      emailType: contactInfo.email_type,
      emailStatusArca: "Confirmado",
      mobilePhone: contactInfo.mobile,
      whatsapp: formatPhoneNumber(contactInfo.mobile),
    };

    setIsLoading(true);
    const response = await createContact(body);
    setIsLoading(false);
    if (response.status === "ok") {
      const standarizedTicketName = `${contactInfo.name} - ${contactInfo.last_name} - ${contactInfo.cuit}`;
      setTicketText(standarizedTicketName);
      setContactInfo({ ...contactInfo, hs_id: response.idLink });
      showTicketSection();
    } else {
      handleError(response.status);
    }
  };

  const handleExistingContact = async () => {
    if (needToUpdate) {
      setIsLoading(true);
      console.log("Updating contact with info: ", contactInfo);
      const response = await updateHubspotInfo({
        email: contactInfo.email,
        phone: contactInfo.landline,
        mobilePhone: contactInfo.mobile,
        whatsapp: formatPhoneNumber(contactInfo.mobile),
        hubspot_id: contactInfo.hs_id,
        firstName: contactInfo.name,
        lastName: contactInfo.last_name,
      });
      console.log("Updating contact with info: ");

      setIsLoading(false);
      if (response.status === "ok") {
        const standarizedTicketName = `${contactInfo.name} - ${contactInfo.last_name} - ${contactInfo.cuit}`;
        setTicketText(standarizedTicketName);
        showTicketSection();
        return;
      } else {
        handleError(response.status);
        return;
      }
    }

    showTicketSection();
  };

  const handleUpdateChanges = () => {
    if (formStep !== Step.EXISTS) return;
    setNeedToUpdate(true);
  };

  return {
    formStep,
    formSubmitted,
    currentCUIT,
    showCUITError,
    isLoading,
    contactInfo,
    showCreationError,
    ticketText,
    disableButton,
    handleClosePanel,
    handleSubmit,
    handleCUIT,
    handleCUITSubmit,
    setContactInfo,
    handleUpdateChanges,
  };
};
