import React, { createContext, useState } from 'react';
import { apiConfig } from '@/config/api.config';
import { useCallApi } from '@/hooks';
import { toast } from 'sonner';
import { getAuth,useAuthContext } from '@/auth';

interface Password {
  password: string;
  retype_password: string;
  username: string;
  current_password: string;
}

interface Profile {
  name: string;
  email: string;
  username: string;
}

interface PinCodePayload {
  currentpincode: string;
  newpincode: string;
  retypepincode: string;
}

interface ContextProps {
  password: Password | null;
  profile: Profile | null;
  pincode: PinCodePayload | null;
  setPincode: (pincode: PinCodePayload) => Promise<void>;
  setPassword: (password: Password) => Promise<void>;
  setProfile: (profile: Profile) => Promise<void>;
}

const initialProps: ContextProps = {
  profile: null,
  password: null,
  pincode: null,
  setPassword: async () => {},
  setProfile: async () => {},
  setPincode: async () => {},
};

const AccountUserProfileContext = createContext<ContextProps>(initialProps);

const API_URL = apiConfig.service_dashboard;
const API_URL2 = apiConfig.service_customer;

const AccountUserProfileContextProvider = ({ children }: { children: React.ReactNode }) => {
  const { login } = useAuthContext();
  const [profile, setProfileState] = useState<Profile | null>(null);
  const [password, setPasswordState] = useState<Password | null>(null);
  const [pinCode, setPincodeState] = useState<PinCodePayload | null>(null);
  const [alert, setAlert] = useState({ show: false, message: '' });

  const { PutData, PostData } = useCallApi();

  const handleError = (error: any, defaultMessage: string) => {
    const errorMessage = error?.response?.data?.message || error?.message || defaultMessage;
    setAlert({ show: true, message: errorMessage });
    toast.error(errorMessage);
  };

  const handleSetPassword = async (newPassword: Password) => {
    setPasswordState(newPassword);

    try {
      const validate = await PostData(`${API_URL}/login`, {
        password: newPassword.current_password,
        username: newPassword.username,
      });

      if (!validate || !validate.status) {
        toast.error('Current password validation failed.');
        return;
      }

      const response = await PutData(`${API_URL}/user/update_password`, {
        password: newPassword.password,
        retype_password: newPassword.retype_password,
      });

      if (response && response.status) {
        toast.success('Password updated successfully!');
      } else {
        toast.error(response?.message || 'Failed to update password.');
      }
    } catch (error: any) {
      handleError(error, 'Failed to update password. Please try again.');
    }
  };

  const handleSetProfile = async (newProfile: Profile) => {
    try {
      setProfileState(newProfile);

      await PutData(`${API_URL}/user/update_profile/`, {
        name: newProfile.name,
        email: newProfile.email,
        username: newProfile.username,
      });

      toast.success('Profile updated successfully.');
    } catch (error: any) {
      handleError(error, 'Failed to update profile. Please try again.');
    }
  };

  const handleSetPinCode = async (newPinCode: PinCodePayload) => {
    try {
      setPincodeState(newPinCode);
      const customerid = getAuth()?.user?.customer?.id;
      const response = await PutData(`${API_URL2}/customer/pin/${customerid}`, {
        old_pin: newPinCode.currentpincode,
        new_pin: newPinCode.newpincode,
        retype_new_pin: newPinCode.retypepincode,
      });

      if (response && response.status) {
        toast.success('Pin code updated successfully.');
      } else {
        toast.error(response?.message || 'Failed to update pin code.');
      }
    } catch (error: any) {
      handleError(error, 'Failed to update Pin Code. Please try again.');
    }
  };

  return (
    <AccountUserProfileContext.Provider
      value={{
        password,
        profile,
        pincode: pinCode,
        setPassword: handleSetPassword,
        setProfile: handleSetProfile,
        setPincode: handleSetPinCode,
      }}
    >
      {children}
    </AccountUserProfileContext.Provider>
  );
};

export { AccountUserProfileContextProvider, AccountUserProfileContext };
