import axios from 'axios';
import { Alert } from 'react-native';
import * as SecureStore from 'expo-secure-store';
import { EXPO_PUBLIC_API_URL } from '@env';
import { forgetPasswordFormData } from '../types/signup';
import { CustomerData } from '../types/signUpFormData';

class AuthenticationService {
    private apiUrl: string;

    constructor() {
        this.apiUrl = EXPO_PUBLIC_API_URL;
        if (!this.apiUrl) {
            throw new Error('API URL is not defined in environment variables');
        }
    }

    async login(username: string, password: string) {
        try {
            const response = await axios.post(
                `${this.apiUrl}/public/client/customer/sign-in`,
                {
                    email: username,
                    password: password
                },
                {
                    headers: {
                        'Content-Type': 'application/json',
                        Accept: 'application/json'
                    }
                }
            );
            if (response.status === 201) {
                const token = response.data.accessToken;
                await SecureStore.setItemAsync('accessToken', token);
                console.log('Login successful!');
                return true;
            } else {
                console.error('Login failed:', response.status);

                return false;
            }
        } catch (error) {
            if (axios.isAxiosError(error)) {
                console.error(
                    'Login error:',
                    error.response?.data?.message || error.message
                );
            } else {
                console.error('An unexpected error occurred:', error);
            }

            return false;
        }
    }

    async logout() {
        await SecureStore.deleteItemAsync('accessToken');
        console.log('log out successfully, accessToken deleted');
    }

    //BELOW CODES RELATE TO "SIGN UP"
    //BELOW CODES RELATE TO "SIGN UP"
    async sendOtpToSignUpEmail(email: string) {
        try {
            const response = await axios.post(
                `${this.apiUrl}/public/client/customer/otp`,
                { email: email },
                {
                    headers: {
                        'Content-Type': 'application/json',
                        Accept: 'application/json'
                    }
                }
            );
            if (response.status === 200 || response.status === 201) {
                console.log('OTP sent successfully');
                return true;
            } else {
                console.error('Failed to send OTP:', response.status);
                return false;
            }
        } catch (error) {
            if (axios.isAxiosError(error)) {
                console.error(
                    'Error sending OTP:',
                    error.response?.data?.message || error.message
                );
            } else {
                console.error(
                    'An unexpected error occurred while sending OTP:',
                    error
                );
            }
            return false;
        }
    }

    async verifySignUpOtp(
        email: string,
        code: string,
        setScreen: React.Dispatch<React.SetStateAction<number>>,
        setError: React.Dispatch<React.SetStateAction<string>>
    ) {
        try {
            const response = await axios.put(
                `${this.apiUrl}/public/client/customer/otp`,
                { email, code },
                {
                    headers: {
                        'Content-Type': 'application/json',
                        Accept: 'application/json'
                    }
                }
            );

            if (response.status === 200) {
                console.log('OTP verified successfully');
                setScreen(
                    (currentScreenNumber: number) => currentScreenNumber + 1
                );
                return true;
            } else {
                console.error('OTP verification failed:', response.status);
                setError('OTP驗證碼錯誤');
                return false;
            }
        } catch (error) {
            if (axios.isAxiosError(error)) {
                console.error(
                    'Error verifying OTP:',
                    error.response?.data?.message || error.message
                );
                setError(
                    '發生意外錯誤，請確保您輸入的電子郵件正確，並再次確認您的OTP驗證碼是否正確。'
                );
            } else {
                console.error(
                    'An unexpected error occurred while verifying OTP:',
                    error
                );
                setError('發生意外錯誤，請稍後再試');
            }
            return false;
        }
    }

    async signUp(data: CustomerData) {
        try {
            const response = await axios.post(
                `${this.apiUrl}/public/client/customer`,
                data,
                {
                    headers: {
                        'Content-Type': 'application/json',
                        Accept: 'application/json'
                    }
                }
            );

            if (response.status === 200 || response.status === 201) {
                console.log('Signup successful');
                return true;
            } else {
                console.error('Signup failed:', response.status);
                return false;
            }
        } catch (error) {
            if (axios.isAxiosError(error)) {
                console.error(
                    'Error signing up:',
                    error.response?.data?.message || error.message
                );
            } else {
                console.error(
                    'An unexpected error occurred while signing up:',
                    error
                );
            }
            return false;
        }
    }

    //BELOW CODES RELATE TO "FORGET PASSWORD"
    //BELOW CODES RELATE TO "FORGET PASSWORD"
    async sendForgetPasswordOtp(email: string) {
        try {
            const response = await axios.post(
                `${this.apiUrl}/public/client/customer/pw/otp`,
                { email },
                {
                    headers: {
                        'Content-Type': 'application/json',
                        Accept: 'application/json'
                    }
                }
            );

            if (response.status === 200 || response.status === 201) {
                console.log('Forget password OTP sent successfully');
                return true;
            } else {
                console.error(
                    'Failed to send forget password OTP:',
                    response.status
                );
                return false;
            }
        } catch (error) {
            if (axios.isAxiosError(error)) {
                console.error(
                    'Error sending forget password OTP:',
                    error.response?.data?.message || error.message
                );
            } else {
                console.error(
                    'An unexpected error occurred while sending forget password OTP:',
                    error
                );
            }
            return false;
        }
    }

    async verifyingOtpForgetPassword(
        email: string,
        otp: string,
        setForgetPasswordFormData: React.Dispatch<
            React.SetStateAction<forgetPasswordFormData>
        >,
        setData: React.Dispatch<React.SetStateAction<string>>
    ) {
        try {
            const res = await axios.put(
                `${this.apiUrl}/public/client/customer/pw/otp`,
                {
                    email: email,
                    code: otp
                }
            );
            const data = res.data;
            setData(data.msg);
            console.log(data.msg);
            setForgetPasswordFormData((prevFormData) => ({
                ...prevFormData,
                otpAuthCompleted: true
            }));
            return true;
        } catch (error) {
            console.error('Error', error);
            return false;
        }
    }

    async changePassword(confirmedNewPassword: string, data: string) {
        try {
            const res = await axios.put(
                `${this.apiUrl}/clients/customer/pw/forget`,
                { newPassword: confirmedNewPassword },
                {
                    headers: {
                        Authorization: `Bearer ${data}`
                    }
                }
            );
            return true;
        } catch (error) {
            if (axios.isAxiosError(error)) {
                console.error(
                    'Error changing password:',
                    error.response?.data?.message || error.message
                );
            } else {
                console.error('An unexpected error occurred:', error);
            }
        }
    }

    //BELOW CODES RELATE TO "changing account info (such as gender, name)"
    //BELOW CODES RELATE TO "changing account info (such as gender, name)"
    async changeName(
        name: string | null,
        token: string | null
    ): Promise<boolean> {
        try {
            const res = await axios.put(
                `${this.apiUrl}/clients/customer`,
                { nickname: name },
                {
                    headers: {
                        Authorization: `Bearer ${token}`
                    }
                }
            );
            console.log('Change Name Successfully!');
            return true;
        } catch (error) {
            if (axios.isAxiosError(error)) {
                console.error(
                    'Error changing name:',
                    error.response?.data?.message
                );
            } else {
                console.error('An unexpected error occurred:', error);
            }
            return false;
        }
    }

    async changePhone(
        phone: string | null,
        token: string | null
    ): Promise<boolean> {
        try {
            const convertPhoneStringToNumber = Number(phone);
            const res = await axios.put(
                `${this.apiUrl}/clients/customer`,
                { phone: convertPhoneStringToNumber },
                {
                    headers: {
                        Authorization: `Bearer ${token}`
                    }
                }
            );
            console.log('Change Phone Successfully!');
            return true;
        } catch (error) {
            if (axios.isAxiosError(error)) {
                console.error(
                    'Error changing phone:',
                    error.response?.data?.message
                );
            } else {
                console.error('An unexpected error occurred:', error);
            }
            return false;
        }
    }

    async changeGender(
        gender: string | null,
        token: string | null
    ): Promise<boolean> {
        try {
            const res = await axios.put(
                `${this.apiUrl}/clients/customer`,
                { gender: gender },
                {
                    headers: {
                        Authorization: `Bearer ${token}`
                    }
                }
            );
            console.log('Change gender Successfully!');
            return true;
        } catch (error) {
            if (axios.isAxiosError(error)) {
                console.error(
                    'Error changing gender:',
                    error.response?.data?.message
                );
            } else {
                console.error('An unexpected error occurred:', error);
            }
            return false;
        }
    }
    async getUserInfo() {
        try {
            const response = await axios.get(
                `${this.apiUrl}/clients/customer`,
                {
                    headers: {
                        Authorization: `Bearer ${await SecureStore.getItemAsync(
                            'accessToken'
                        )}`
                    }
                }
            );
            if (response.status === 200 || response.status === 201) {
                // console.log(response);
                return response;
            } else {
                console.log('invalid response');
            }
        } catch (error) {
            console.log(error);
        }
    }
}
export const authenticationService = new AuthenticationService();
