import { UserFindAuthMethodParams, UserAuthMethodData, AuthMethodModifyItem } from '@/entities/user/model/types';
import { useUserFindAuthMethodMutation } from '@/entities/user/api/use-user-find-authmethod-mutation';
import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant';
import { useEffect, useState } from 'react';
import { useUserModifyAuthMethodMutation } from '@/entities/user/api/use-user-modify-authmethod-mutation';
import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { snackBar } from '@/shared/lib/toast';

export const UserLoginAuthInfoWrap = ({
  mid,
  usrid,
  idCL,
  status,
}: UserFindAuthMethodParams) => {
  const { navigate } = useNavigate();
  const [pageParam] = useState(DEFAULT_PAGE_PARAM);
  const [authMethodData, setAuthMethodData] = useState<UserAuthMethodData>();
  const [initialData, setInitialData] = useState<UserAuthMethodData>();
  const [newEmails, setNewEmails] = useState<string[]>([]);
  const [newPhones, setNewPhones] = useState<string[]>([]);
  const [editableEmailIndex, setEditableEmailIndex] = useState<number>(-1);
  const [editablePhoneIndex, setEditablePhoneIndex] = useState<number>(-1);
  const [readOnlyEmails, setReadOnlyEmails] = useState<Set<number>>(new Set());
  const [readOnlyPhones, setReadOnlyPhones] = useState<Set<number>>(new Set());
  const { mutateAsync: userFindAuthMethod } = useUserFindAuthMethodMutation();
  const { mutateAsync: userModifyAuthMethod } = useUserModifyAuthMethodMutation({
    onSuccess: () => {
      snackBar('사용자 정보가 성공적으로 저장되었습니다.');
      navigate(PATHS.account.user.manage, {
        state: {
          mid: mid,
        }
      });
    },
    onError: (error) => {
      snackBar(error?.response?.data?.message || '사용자 정보 저장에 실패했습니다.');
    }
  });

  console.log("UserLoginAuthInfoWrap", mid, usrid, idCL, status);

  const handleRemoveExistingEmail = (index: number) => {
    if (authMethodData?.emails) {
      const updatedEmails = authMethodData.emails.filter((_, i) => i !== index);
      setAuthMethodData({ ...authMethodData, emails: updatedEmails });
    }
  };

  const handleRemoveExistingPhone = (index: number) => {
    if (authMethodData?.phones) {
      const updatedPhones = authMethodData.phones.filter((_, i) => i !== index);
      setAuthMethodData({ ...authMethodData, phones: updatedPhones });
    }
  };

  const callUserFindAuthMethod = (mid: string, usrid: string) => {
    let params: UserFindAuthMethodParams = {
      mid: mid,
      usrid: usrid,
      idCL: idCL,
      status: status,
      page: pageParam
    };
    userFindAuthMethod(params).then((rs: any) => {
      console.log("User Find Auth Method: ", rs);
      // API 응답이 직접 데이터를 반환하는 경우
      if (rs.emails || rs.phones) {
        console.log("Setting authMethodData directly from response: ", rs);
        setAuthMethodData(rs);
        setInitialData(rs);
      }
      // API 응답이 data 프로퍼티 안에 있는 경우
      else if (rs.data) {
        console.log("Setting authMethodData from rs.data: ", rs.data);
        setAuthMethodData(rs.data);
        setInitialData(rs.data);
      }
    });
  };

  useEffect(() => {
    if (mid && usrid) {
      callUserFindAuthMethod(mid, usrid);
    }
  }, [mid, usrid]);

  const handleAddEmail = () => {
    // 현재 편집 중인 항목을 읽기전용으로 고정
    if (editableEmailIndex >= 0) {
      setReadOnlyEmails(prev => new Set([...prev, editableEmailIndex]));
    }

    // 새로운 편집 가능한 항목 추가
    setEditableEmailIndex(newEmails.length);
    setNewEmails([...newEmails, '']);
  };

  const handleAddPhone = () => {
    // 현재 편집 중인 항목을 읽기전용으로 고정
    if (editablePhoneIndex >= 0) {
      setReadOnlyPhones(prev => new Set([...prev, editablePhoneIndex]));
    }

    // 새로운 편집 가능한 항목 추가
    setEditablePhoneIndex(newPhones.length);
    setNewPhones([...newPhones, '']);
  };


  const handleRemoveNewEmail = (index: number) => {
    const updatedEmails = newEmails.filter((_, i) => i !== index);
    setNewEmails(updatedEmails);

    // 읽기전용 인덱스들을 업데이트 (삭제된 인덱스보다 큰 인덱스들은 1씩 감소)
    const updatedReadOnlyEmails = new Set<number>();
    readOnlyEmails.forEach(readOnlyIndex => {
      if (readOnlyIndex < index) {
        updatedReadOnlyEmails.add(readOnlyIndex);
      } else if (readOnlyIndex > index) {
        updatedReadOnlyEmails.add(readOnlyIndex - 1);
      }
      // readOnlyIndex === index인 경우 제거됨 (Set에 추가하지 않음)
    });
    setReadOnlyEmails(updatedReadOnlyEmails);

    // 삭제 후 편집 가능한 인덱스 조정
    if (index === editableEmailIndex) {
      // 현재 편집 중인 항목을 삭제한 경우 - 편집 가능한 항목이 없음
      setEditableEmailIndex(-1);
    } else if (index < editableEmailIndex) {
      // 편집 가능한 항목보다 앞의 항목을 삭제한 경우
      setEditableEmailIndex(editableEmailIndex - 1);
    }
  };

  const handleRemoveNewPhone = (index: number) => {
    const updatedPhones = newPhones.filter((_, i) => i !== index);
    setNewPhones(updatedPhones);

    // 읽기전용 인덱스들을 업데이트 (삭제된 인덱스보다 큰 인덱스들은 1씩 감소)
    const updatedReadOnlyPhones = new Set<number>();
    readOnlyPhones.forEach(readOnlyIndex => {
      if (readOnlyIndex < index) {
        updatedReadOnlyPhones.add(readOnlyIndex);
      } else if (readOnlyIndex > index) {
        updatedReadOnlyPhones.add(readOnlyIndex - 1);
      }
      // readOnlyIndex === index인 경우 제거됨 (Set에 추가하지 않음)
    });
    setReadOnlyPhones(updatedReadOnlyPhones);

    // 삭제 후 편집 가능한 인덱스 조정
    if (index === editablePhoneIndex) {
      // 현재 편집 중인 항목을 삭제한 경우 - 편집 가능한 항목이 없음
      setEditablePhoneIndex(-1);
    } else if (index < editablePhoneIndex) {
      // 편집 가능한 항목보다 앞의 항목을 삭제한 경우
      setEditablePhoneIndex(editablePhoneIndex - 1);
    }
  };

  const handleNewEmailChange = (index: number, value: string) => {
    const updated = [...newEmails];
    updated[index] = value;
    setNewEmails(updated);
  };

  const handleNewPhoneChange = (index: number, value: string) => {
    const updated = [...newPhones];
    updated[index] = value;
    setNewPhones(updated);
  };

  // 이메일 형식 검증
  const isValidEmail = (email: string) => {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
  };

  // 전화번호 형식 검증 (010으로 시작하고 총 11자리 숫자)
  const isValidPhone = (phone: string) => {
    const phoneRegex = /^010\d{8}$/;
    return phoneRegex.test(phone);
  };

  // 이메일 추가 버튼 활성화 조건
  const isEmailAddButtonEnabled = () => {
    if (newEmails.length === 0) return true; // 처음은 활성화

    const lastEmailIndex = newEmails.length - 1;
    const lastEmail = newEmails[lastEmailIndex];

    // 마지막 항목이 편집 가능하고, 유효한 형식이며, 중복이 없으면 활성화
    return lastEmailIndex >= editableEmailIndex &&
           lastEmail &&
           lastEmail.trim() &&
           isValidEmail(lastEmail) &&
           !hasDuplicateEmail();
  };

  // 전화번호 추가 버튼 활성화 조건
  const isPhoneAddButtonEnabled = () => {
    if (newPhones.length === 0) return true; // 처음은 활성화

    const lastPhoneIndex = newPhones.length - 1;
    const lastPhone = newPhones[lastPhoneIndex];

    // 마지막 항목이 편집 가능하고, 유효한 형식이며, 중복이 없으면 활성화
    return lastPhoneIndex >= editablePhoneIndex &&
           lastPhone &&
           lastPhone.trim() &&
           isValidPhone(lastPhone) &&
           !hasDuplicatePhone();
  };

  // 삭제 버튼 활성화 조건 (전체 항목이 1개만 남으면 비활성화)
  const isDeleteButtonEnabled = () => {
    const totalEmailCount = (authMethodData?.emails?.length || 0) + newEmails.length;
    const totalPhoneCount = (authMethodData?.phones?.length || 0) + newPhones.length;
    const totalCount = totalEmailCount + totalPhoneCount;

    return totalCount > 1;
  };

  // 중복 이메일 검증
  const hasDuplicateEmail = () => {
    const allEmails = [
      ...(authMethodData?.emails?.map(e => e.content) || []),
      ...newEmails.filter(e => e.trim())
    ];

    const uniqueEmails = new Set(allEmails);
    return allEmails.length !== uniqueEmails.size;
  };

  // 중복 전화번호 검증
  const hasDuplicatePhone = () => {
    const allPhones = [
      ...(authMethodData?.phones?.map(p => p.content) || []),
      ...newPhones.filter(p => p.trim())
    ];

    const uniquePhones = new Set(allPhones);
    return allPhones.length !== uniquePhones.size;
  };

  const isSaveButtonEnabled = () => {
    // 새로 추가된 이메일 중 값이 있는 것들의 형식 검증
    const validNewEmails = newEmails.filter(e => e.trim());
    const hasInvalidEmail = validNewEmails.some(email => !isValidEmail(email));

    // 새로 추가된 전화번호 중 값이 있는 것들의 형식 검증
    const validNewPhones = newPhones.filter(p => p.trim());
    const hasInvalidPhone = validNewPhones.some(phone => !isValidPhone(phone));

    // 형식이 맞지 않는 항목이 있거나 중복이 있으면 비활성화
    if (hasInvalidEmail || hasInvalidPhone || hasDuplicateEmail() || hasDuplicatePhone()) {
      return false;
    }

    // 현재 이메일과 전화번호가 모두 없으면 비활성화
    const currentEmailCount = (authMethodData?.emails?.length || 0) + validNewEmails.length;
    const currentPhoneCount = (authMethodData?.phones?.length || 0) + validNewPhones.length;

    if (currentEmailCount === 0 && currentPhoneCount === 0) {
      return false;
    }

    // 초기 데이터와 비교하여 변경사항이 있는지 확인
    const initialEmailCount = initialData?.emails?.length || 0;
    const initialPhoneCount = initialData?.phones?.length || 0;
    const currentApiEmailCount = authMethodData?.emails?.length || 0;
    const currentApiPhoneCount = authMethodData?.phones?.length || 0;

    // 삭제가 발생했거나 새로운 항목이 추가된 경우 활성화
    const hasChanges = (
      currentApiEmailCount < initialEmailCount ||
      currentApiPhoneCount < initialPhoneCount ||
      validNewEmails.length > 0 ||
      validNewPhones.length > 0
    );

    return hasChanges;
  };

  const handleSave = async () => {
    try {
      const addMethods: AuthMethodModifyItem[] = [];
      const removeMethods: AuthMethodModifyItem[] = [];

      // 삭제된 이메일 항목 수집
      if (initialData?.emails) {
        initialData.emails.forEach((email) => {
          const stillExists = authMethodData?.emails?.some(
            e => e.content === email.content && e.sequence === email.sequence
          );
          if (!stillExists) {
            removeMethods.push({
              usrid: usrid,
              systemAdminClassId: mid,
              idCl:  idCL,
              authMethodType: "EMAIL",
              sequence: email.sequence,
              content: email.content
            });
          }
        });
      }

      // 삭제된 전화번호 항목 수집
      if (initialData?.phones) {
        initialData.phones.forEach((phone) => {
          const stillExists = authMethodData?.phones?.some(
            p => p.content === phone.content && p.sequence === phone.sequence
          );
          if (!stillExists) {
            removeMethods.push({
              usrid: usrid,
              systemAdminClassId: mid,
              idCl: idCL,
              authMethodType: "PHONE",
              sequence: phone.sequence,
              content: phone.content
            });
          }
        });
      }

      // 새로 추가된 이메일 항목 수집
      const validNewEmails = newEmails.filter(e => e.trim());
      validNewEmails.forEach((email, index) => {
        const existingEmailCount = authMethodData?.emails?.length || 0;
        addMethods.push({
          usrid: usrid,
          systemAdminClassId: mid,
          idCl: idCL,
          authMethodType: "EMAIL",
          sequence: existingEmailCount + index + 1,
          content: email
        });
      });

      // 새로 추가된 전화번호 항목 수집
      const validNewPhones = newPhones.filter(p => p.trim());
      validNewPhones.forEach((phone, index) => {
        const existingPhoneCount = authMethodData?.phones?.length || 0;
        addMethods.push({
          usrid: usrid,
          systemAdminClassId: mid,
          idCl: idCL,
          authMethodType: "PHONE",
          sequence: existingPhoneCount + index + 1,
          content: phone
        });
      });

      const requestBody = {
        addMethods: addMethods.length > 0 ? addMethods : undefined,
        removeMethods: removeMethods.length > 0 ? removeMethods : undefined
      };

      // 빈 배열 제거
      const finalRequestBody = Object.fromEntries(
        Object.entries(requestBody).filter(([_, value]) => value !== undefined)
      );

      console.log("Save request body:", finalRequestBody);

      // API 호출
      await userModifyAuthMethod(finalRequestBody);

      // 성공 후 데이터 새로고침
      callUserFindAuthMethod(mid, usrid);

      // 새로 추가한 항목들 초기화
      setNewEmails([]);
      setNewPhones([]);
      setEditableEmailIndex(-1);
      setEditablePhoneIndex(-1);
      setReadOnlyEmails(new Set());
      setReadOnlyPhones(new Set());
    } catch (error) {
      console.error("Failed to save auth methods:", error);
    }
  };

  console.log("Rendering with authMethodData: ", authMethodData);
  console.log("Emails: ", authMethodData?.emails);
  console.log("Phones: ", authMethodData?.phones);

  return (
    <>
      <div className="ing-list pdtop">
        <div className="settings-login-auth pb-86">
          <div className="group">
            <div className="group-header">
              <div className="title">이메일 주소</div>
              <button
                className="ic20 plus"
                type="button"
                aria-label="추가"
                onClick={handleAddEmail}
                disabled={!isEmailAddButtonEnabled()}
              ></button>
            </div>
            {authMethodData?.emails && authMethodData.emails.length > 0 && authMethodData.emails.map((email, index) => (
              <div className="input-row" key={`existing-email-${index}`}>
                <input
                  type="email"
                  value={email.content}
                  placeholder="example@domain.com"
                  readOnly
                />
                <button
                  className="icon-btn minus"
                  type="button"
                  aria-label="삭제"
                  onClick={() => handleRemoveExistingEmail(index)}
                  disabled={!isDeleteButtonEnabled()}
                ></button>
              </div>
            ))}
            {newEmails.map((email, index) => (
              <div className="input-row" key={`new-email-${index}`}>
                <input
                  type="email"
                  value={email}
                  placeholder="example@domain.com"
                  onChange={(e) => handleNewEmailChange(index, e.target.value)}
                  readOnly={readOnlyEmails.has(index) || index !== editableEmailIndex}
                />
                <button
                  className="icon-btn minus"
                  type="button"
                  aria-label="삭제"
                  onClick={() => handleRemoveNewEmail(index)}
                  disabled={!isDeleteButtonEnabled()}
                ></button>
              </div>
            ))}
          </div>

          <div className="group">
            <div className="group-header">
              <div className="title">휴대폰 번호</div>
              <button
                className="ic20 plus"
                type="button"
                aria-label="추가"
                onClick={handleAddPhone}
                disabled={!isPhoneAddButtonEnabled()}
              ></button>
            </div>
            {authMethodData?.phones && authMethodData.phones.length > 0 && authMethodData.phones.map((phone, index) => (
              <div className="input-row" key={`existing-phone-${index}`}>
                <input
                  type="tel"
                  value={phone.content}
                  placeholder="휴대폰 번호 입력"
                  readOnly
                />
                <button
                  className="icon-btn minus"
                  type="button"
                  aria-label="삭제"
                  onClick={() => handleRemoveExistingPhone(index)}
                  disabled={!isDeleteButtonEnabled()}
                ></button>
              </div>
            ))}
            {newPhones.map((phone, index) => (
              <div className="input-row" key={`new-phone-${index}`}>
                <input
                  type="tel"
                  value={phone}
                  placeholder="휴대폰 번호 입력"
                  onChange={(e) => handleNewPhoneChange(index, e.target.value)}
                  readOnly={readOnlyPhones.has(index) || index !== editablePhoneIndex}
                />
                <button
                  className="icon-btn minus"
                  type="button"
                  aria-label="삭제"
                  onClick={() => handleRemoveNewPhone(index)}
                  disabled={!isDeleteButtonEnabled()}
                ></button>
              </div>
            ))}
            <div className="notice-bar">※ 탭을 변경하면 미저장 내용은 초기화됩니다.</div>
          </div>
        </div>
        <div className="apply-row">
          <button
            className="btn-50 btn-blue flex-1"
            disabled={!isSaveButtonEnabled()}
            onClick={handleSave}
          >
            저장
          </button>
        </div>
      </div>
    </>
  );
};