import React, { useEffect, useState, useRef, useCallback, memo } from 'react';
import { areEqual } from 'Utils/equalityChecks';
import { useDispatch, useSelector } from 'react-redux';
import { ContractFormsModal } from 'Components/Forms/ContractFormsModal';
import {
  addingContractFormSelector,
  companyIdSelector,
  contractFormAddedSelector,
  contractFormNameErrorSelector,
  contractFormTemplateErrorSelector,
} from '../selectors';
import { addContractForm, listCompanyContractForms, setContractFormAdded, setContractFormErrors } from '../actions';

const initData = {
  name: '',
  template: '',
  requireSignature: false,
};

interface Props {
  isOpen: boolean;
  onClose: () => void;
}

const AddContractForms = ({ isOpen, onClose }: Props) => {
  const dispatch = useDispatch();
  const isAdding = useSelector(addingContractFormSelector, areEqual);
  const isAdded = useSelector(contractFormAddedSelector, areEqual);
  const companyId = useSelector(companyIdSelector, areEqual);
  const nameErrors = useSelector(contractFormNameErrorSelector, areEqual);
  const templateErrors = useSelector(contractFormTemplateErrorSelector, areEqual);

  const [formData, setFormData] = useState({ ...initData });
  const [toastMessage, setToastMessage] = useState('');
  const [showToast, setShowToast] = useState(false);
  const [toastType, setToastType] = useState<'success' | 'error'>('success');
  const [wasAdding, setWasAdding] = useState(false);
  const textAreaRef = useRef<HTMLTextAreaElement>(null);

  const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
    const { name, value, type } = e.target;
    const newValue = type === 'checkbox' ? (e.target as HTMLInputElement).checked : value;
    setFormData((prev) => ({
      ...prev,
      [name]: newValue,
    }));
  }, []);

  const handleTagClick = useCallback(
    (tag: string) => {
      const textarea = textAreaRef.current;
      if (textarea) {
        const start = textarea.selectionStart;
        const end = textarea.selectionEnd;
        const newText = formData.template.substring(0, start) + tag + formData.template.substring(end);
        setFormData((prev) => ({ ...prev, template: newText }));
        setTimeout(() => {
          textarea.selectionStart = start + tag.length;
          textarea.selectionEnd = start + tag.length;
          textarea.focus();
        }, 0);
      }
    },
    [formData.template]
  );

  const onFormSubmit = useCallback(
    (e) => {
      e.preventDefault();
      const errors: any = {};
      if (!formData.name.trim()) errors.name = ['Form name is required'];
      if (!formData.template.trim()) errors.template = ['Template is required'];
      if (Object.keys(errors).length > 0) {
        dispatch(setContractFormErrors(errors));
        return;
      }
      if (companyId) {
        const payload = {
          company_id: companyId,
          name: formData.name,
          replacement_tags: Array.from(new Set(formData.template.match(/~~~.*?~~~/g) || [])).join(', '),
          status: 'active',
          template: formData.template,
          has_signature: formData.requireSignature,
        };
        dispatch(addContractForm(payload));
      }
    },
    [formData, companyId, dispatch]
  );

  useEffect(() => {
    if (isAdded) {
      setToastType('success');
      setToastMessage('Contract Form Added');
      setShowToast(true);
      setFormData({ ...initData });
      if (companyId) {
        dispatch(listCompanyContractForms(companyId));
      }
      dispatch(setContractFormErrors({}));
      setTimeout(() => {
        setShowToast(false);
        onClose();
        dispatch(setContractFormAdded(false));
      }, 1500);
    }
  }, [isAdded, companyId, dispatch, onClose]);

  useEffect(() => {
    if (isAdding) {
      setWasAdding(true);
    } else if (wasAdding && !isAdded) {
      // API call finished but form wasn't added (error occurred)
      setToastType('error');
      setToastMessage('Failed to add contract form. Please try again.');
      setShowToast(true);
      setWasAdding(false);
      setTimeout(() => {
        setShowToast(false);
      }, 3000);
    }
  }, [isAdding, isAdded, wasAdding]);

  useEffect(() => {
    if (!isOpen) {
      setFormData({ ...initData });
      dispatch(setContractFormErrors({}));
    }
  }, [isOpen, dispatch]);

  return (
    <ContractFormsModal
      isOpen={isOpen}
      title="Add Contract Form"
      submitText="Add Contract"
      formData={formData}
      formErrors={{
        name: nameErrors,
        template: templateErrors,
      }}
      showToast={showToast}
      toastMessage={toastMessage}
      toastType={toastType}
      onFormSubmit={onFormSubmit}
      onClickClose={(e) => {
        e.preventDefault();
        onClose();
      }}
      handleChange={handleChange}
      textAreaRef={textAreaRef}
      handleTagClick={handleTagClick}
      submitting={isAdding}
    />
  );
};

const AddContractFormsMemo = memo(AddContractForms, areEqual);
export { AddContractFormsMemo as AddContractForms };
