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 {
  editingContractFormSelector,
  contractFormEditedSelector,
  contractFormNameErrorSelector,
  contractFormTemplateErrorSelector,
  companyIdSelector,
} from '../selectors';
import { editContractForm, setContractFormEdited, setContractFormErrors, listCompanyContractForms } from '../actions';
import { FormTemplate } from '../Models/FormsModel/FormModel';

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

const EditContractForms = ({ isOpen, onClose, initData }: Props) => {
  const dispatch = useDispatch();
  const isEditing = useSelector(editingContractFormSelector, areEqual);
  const isEdited = useSelector(contractFormEditedSelector, areEqual);
  const companyId = useSelector(companyIdSelector, areEqual);
  const nameErrors = useSelector(contractFormNameErrorSelector, areEqual);
  const templateErrors = useSelector(contractFormTemplateErrorSelector, areEqual);

  const [formData, setFormData] = useState({
    name: initData?.name ?? '',
    template: initData?.template ?? '',
    requireSignature: initData?.has_signature ?? false,
  });
  const [toastMessage, setToastMessage] = useState('');
  const [showToast, setShowToast] = useState(false);
  const [toastType, setToastType] = useState<'success' | 'error'>('success');
  const [wasEditing, setWasEditing] = useState(false);
  const textAreaRef = useRef<HTMLTextAreaElement>(null);

  useEffect(() => {
    if (initData) {
      setFormData({
        name: initData.name,
        template: initData.template,
        requireSignature: initData.has_signature,
      });
    }
  }, [initData]);

  useEffect(() => {
    if (isEdited) {
      setToastType('success');
      setToastMessage('Contract Form Updated');
      setShowToast(true);
      if (companyId) {
        dispatch(listCompanyContractForms(companyId));
      }
      dispatch(setContractFormErrors({}));
      setTimeout(() => {
        setShowToast(false);
        onClose();
        dispatch(setContractFormEdited(false));
      }, 1500);
    }
  }, [isEdited, companyId, dispatch, onClose]);

  useEffect(() => {
    if (isEditing) {
      setWasEditing(true);
    } else if (wasEditing && !isEdited) {
      // API call finished but form wasn't edited (error occurred)
      setToastType('error');
      setToastMessage('Failed to update contract form. Please try again.');
      setShowToast(true);
      setWasEditing(false);
      setTimeout(() => {
        setShowToast(false);
      }, 3000);
    }
  }, [isEditing, isEdited, wasEditing]);

  useEffect(() => {
    if (!isOpen) {
      setFormData({
        name: '',
        template: '',
        requireSignature: false,
      });
      dispatch(setContractFormErrors({}));
    }
  }, [isOpen, dispatch, initData]);

  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();
      // Client-side validation
      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) {
        // Prepare API payload
        const payload = {
          name: formData.name,
          company_id: companyId,
          replacement_tags: Array.from(new Set(formData.template.match(/~~~.*?~~~/g) || [])).join(', '),
          status: 'active',
          template: formData.template,
          has_signature: formData.requireSignature,
        };
        dispatch(editContractForm(payload));
      }
    },
    [formData, companyId, dispatch]
  );

  return (
    <ContractFormsModal
      isOpen={isOpen}
      title="Edit Contract Form"
      submitText="Edit 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={isEditing}
    />
  );
};

const EditContractFormsMemo = memo(EditContractForms, areEqual);
export { EditContractFormsMemo as EditContractForms };
