import { useState, useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import parsePhoneNumberFromString from 'libphonenumber-js';
import { PageWrapper } from '../PageWrapper';
import { CardContainer } from '@/components/CardContainer';
import PhoneDisplay from './phoneNumber/PhoneDisplay';
import PhoneEditForm from './phoneNumber/PhoneEditForm';
import PhoneActionButtons from './phoneNumber/PhoneActionButtons';
import { CircularProgress, Box } from '@mui/material';
import { toLocaleDigits } from '@/utils/persianDigit';
import { useApi } from '@/hooks/useApi';
import {
  sendVerificationCode,
  confirmPhoneNumberCode,
  changePhoneNumber,
} from '../../api/settingsApi';
import { type Phone } from '../../types/settingsType';
import { useToast } from '@rkheftan/harmony-ui';
import { useProfile } from '../../hooks/useProfile';
import type { CountryCode } from '@/types/commonTypes';

export function PhoneNumber() {
  const { t, i18n } = useTranslation('setting');
  const toast = useToast();
  const [isEditing, setIsEditing] = useState(false);
  const [phoneNumber, setPhoneNumber] = useState('');
  const [verificationCode, setVerificationCode] = useState('');
  const [buttonState, setButtonState] = useState<'default' | 'counting'>(
    'default',
  );
  const [isVerified, setIsVerified] = useState(false);
  const [isCodeSent, setIsCodeSent] = useState(false);
  const [phones, setPhones] = useState<Phone[]>([]);
  const [countryCode, setCountryCode] = useState<CountryCode>('+98');
  const [phoneNumberError, setPhoneNumberError] = useState<string>();
  const [verificationCodeError, setVerificationCodeError] = useState<string>();
  const [phoneNumberTouched, setPhoneNumberTouched] = useState<boolean>(false);
  const [verificationCodeTouched, setVerificationCodeTouched] =
    useState<boolean>(false);

  const { isLoadingProfile, refetchProfile } = useProfile();

  const { loading: isSendingCode, execute: executeSendCode } =
    useApi(sendVerificationCode);
  const { loading: isVerifying, execute: executeConfirmCode } = useApi(
    confirmPhoneNumberCode,
  );
  const { loading: isChangingPhone, execute: executeChangePhone } =
    useApi(changePhoneNumber);

  const isBusy = useMemo(
    () => isVerifying || isSendingCode || isChangingPhone,
    [isVerifying, isSendingCode, isChangingPhone],
  );

  useEffect(() => {
    const loadProfile = async () => {
      const profileData = await refetchProfile();
      if (!profileData) return;
      if (profileData?.success) {
        setPhones([
          {
            phone: profileData.phoneNumber,
            time: '',
            withCode: profileData.phoneNumber,
          },
        ]);
      } else {
        toast({
          message: profileData.message,
          severity: 'error',
        });
      }
    };
    void loadProfile();
  }, [refetchProfile, toast]);

  useEffect(() => {
    if (!phoneNumberTouched) return;
    if (!phoneNumber) {
      setPhoneNumberError(t('settingForm.thisFieldIsRequired'));
      return;
    }
    const parsed = parsePhoneNumberFromString(countryCode + phoneNumber);
    const valid = Boolean(parsed?.isValid());
    if (!valid) {
      setPhoneNumberError(t('settingForm.phoneNumberIsInvalid'));
    } else {
      setPhoneNumberError(undefined);
    }
  }, [countryCode, phoneNumber, phoneNumberTouched, t]);

  useEffect(() => {
    if (!verificationCodeTouched) return;
    if (!verificationCode) {
      setVerificationCodeError(t('settingForm.verificationCodeRequired'));
      return;
    }
    setVerificationCodeError(undefined);
  }, [verificationCode, verificationCodeTouched, t]);

  const handleBlur = (key: string) => {
    if (key === 'phoneNumber') {
      setPhoneNumberTouched(true);
    } else {
      setVerificationCodeTouched(true);
    }
  };

  const toggleEdit = () => {
    setIsEditing((prev) => {
      if (!prev) {
        setPhoneNumber('');
        setVerificationCode('');
        setIsVerified(false);
        setButtonState('default');
        setPhoneNumberError(undefined);
        setPhoneNumberTouched(false);
        setVerificationCodeError(undefined);
        setVerificationCodeTouched(false);
      }
      return !prev;
    });
  };

  const handleSendCode = async () => {
    setPhoneNumberTouched(true);
    if (!phoneNumber || phoneNumberError) return;
    const result = await executeSendCode({
      phoneNumber: countryCode + phoneNumber.replace(/^0/, ''),
    });
    if (!result) return;
    if (result?.success) {
      setButtonState('counting');
      setIsVerified(false);
      setIsCodeSent(true);
      toast({
        message: result.message || t('settingForm.codeSentSuccessfully'),
        severity: 'success',
      });
    } else {
      toast({
        message: result.message || t('message.serverError'),
        severity: 'error',
      });
    }
  };

  const handleVerifyCode = async () => {
    setVerificationCodeTouched(true);
    if (!verificationCode || verificationCodeError) return;
    const fullPhoneNumber = countryCode + phoneNumber.replace(/^0/, '');
    const confirmResult = await executeConfirmCode({
      phoneNumber: fullPhoneNumber,
      verifyCode: verificationCode,
    });
    if (!confirmResult) return;
    if (!confirmResult.success || !confirmResult.confirm) {
      toast({
        message: confirmResult?.message || t('message.serverError'),
        severity: 'error',
      });
      return;
    }
    setIsVerified(true);
    toast({
      message: t('settingForm.phoneVerified'),
      severity: 'success',
    });
    const changeResult = await executeChangePhone({
      phoneNumber: fullPhoneNumber,
    });
    if (!changeResult) return;
    if (changeResult?.success) {
      setPhones([
        {
          phone: phoneNumber,
          time: t('settingForm.justNow'),
          withCode: fullPhoneNumber,
        },
      ]);
      setIsEditing(false);
      refetchProfile({ force: true });
    } else {
      toast({
        message: changeResult?.message || t('message.serverError'),
        severity: 'error',
      });
    }
  };

  return (
    <PageWrapper>
      <CardContainer
        title={t('settingForm.titlePhoneNumber')}
        subtitle={t('settingForm.descriptionPhoneNumber')}
        highlighted={isEditing}
        action={
          <PhoneActionButtons
            isEditing={isEditing}
            toggleEdit={toggleEdit}
            t={t}
            formId="phoneForm"
            isSubmitting={isBusy}
          />
        }
      >
        {isLoadingProfile ? (
          <Box
            sx={{
              display: 'flex',
              justifyContent: 'center',
              alignItems: 'center',
              p: 4,
              minHeight: '150px',
            }}
          >
            <CircularProgress />
          </Box>
        ) : isEditing ? (
          <Box
            component="form"
            id="phoneForm"
            noValidate
            onSubmit={(e) => {
              e.preventDefault();
              e.stopPropagation();
              if (!isBusy) void handleVerifyCode();
            }}
          >
            <PhoneEditForm
              phoneNumber={phoneNumber}
              setPhoneNumber={setPhoneNumber}
              countryCode={countryCode}
              setCountryCode={setCountryCode}
              verificationCode={verificationCode}
              setVerificationCode={setVerificationCode}
              isVerified={isVerified}
              isVerifying={isBusy}
              isSendingCode={isSendingCode}
              isCodeSent={isCodeSent}
              setIsCodeSent={setIsCodeSent}
              buttonState={buttonState}
              setButtonState={setButtonState}
              handleSendCode={handleSendCode}
              handleVerifyClick={handleVerifyCode}
              phoneNumberError={
                phoneNumberTouched ? phoneNumberError : undefined
              }
              verificationCodeError={
                verificationCodeTouched ? verificationCodeError : undefined
              }
              handleBlur={handleBlur}
              phones={phones}
            />
          </Box>
        ) : (
          <PhoneDisplay
            phones={phones.map((p) => {
              let localPhone = p.withCode;
              if (localPhone.startsWith('+98')) {
                localPhone = '0' + localPhone.slice(3);
              }
              return {
                ...p,
                phone: toLocaleDigits(localPhone, i18n.language),
              };
            })}
          />
        )}
      </CardContainer>
    </PageWrapper>
  );
}
