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

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

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

interface PinCode {
  newpincode: string;
}

interface ContextProps {
  password: Password | null;
  profile: Profile | null;
  pincode: PinCode | null;
  setPincode: (pincode: PinCode) => 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 AccountUserProfileContextProvider = ({ children }: { children: React.ReactNode }) => {
  /* state */
  const { login } = useAuthContext();
  const [profile, setProfileState] = useState<Profile | null>(null);
  const [password, setPasswordState] = useState<Password | null>(null);
  const [pinCode, setPincodeState] = useState<PinCode | null>(null);
  const [alert, setAlert] = useState({
    show: false,
    message: ''
  });

  const { PutData, PostData } = useCallApi();

  // Helper function to handle API errors
  const handleError = (error: any, defaultMessage: string) => {
    const errorMessage = error?.response?.data?.message || error?.message || defaultMessage;
    setAlert({ show: true, message: errorMessage });
    toast.error(errorMessage);
  };

  // Function to handle password update
  const handleSetPassword = async (newPassword: Password) => {
    setPasswordState(newPassword);

    try {
      // Validate the current password
      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;
      }

      // Update the password
      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.');
    }
  };

  // Function to handle profile update
  const handleSetProfile = async (newProfile: Profile) => {
    try {
      setProfileState(newProfile);

      const response = 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.');
    }
  };

  // Function to handle pin code update
  const handleSetPinCode = async (newPinCode: PinCode) => {
    try {
      setPincodeState(newPinCode);

      // You can make an API call here to update the pin code in the backend if needed
      toast.success('Pin code updated successfully.');
    } 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 };
