import React, { createContext, useContext, useReducer, useEffect } from 'react';
import { AuthState, AdminUser, Permission } from '../types/auth';
import toast from 'react-hot-toast';

interface AuthContextType {
    isAuthenticated: boolean;
    isLoading: boolean;
    user: AdminUser | null;
    permissions: Permission[];
    allPermissions: Permission[];
    token: string | null;
    refreshToken: string | null;
    logout: () => void;
    restoreSession: () => void;
    hasPermission: (permissionId: number) => boolean;
    hasPermissionByTitle: (title: string) => boolean;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

type AuthAction =
    | { type: 'LOGIN'; payload: { user: AdminUser; permissions: Permission[]; allPermissions: Permission[]; token: string; refreshToken: string } }
    | { type: 'LOGOUT' }
    | { type: 'RESTORE_SESSION'; payload: { user: AdminUser; permissions: Permission[]; allPermissions: Permission[]; token: string; refreshToken: string } }
    | { type: 'SET_LOADING'; payload: boolean };

const authReducer = (state: AuthState, action: AuthAction): AuthState => {
    switch (action.type) {
        case 'LOGIN':
        case 'RESTORE_SESSION':
            return {
                ...state,
                isAuthenticated: true,
                isLoading: false,
                user: action.payload.user,
                permissions: action.payload.permissions,
                allPermissions: action.payload.allPermissions,
                token: action.payload.token,
                refreshToken: action.payload.refreshToken,
            };
        case 'LOGOUT':
            return {
                ...state,
                isAuthenticated: false,
                isLoading: false,
                user: null,
                permissions: [],
                allPermissions: [],
                token: null,
                refreshToken: null,
            };
        case 'SET_LOADING':
            return {
                ...state,
                isLoading: action.payload,
            };
        default:
            return state;
    }
};

const initialState: AuthState = {
    isAuthenticated: false,
    isLoading: true,
    user: null,
    permissions: [],
    allPermissions: [],
    token: null,
    refreshToken: null,
};

export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
    const [state, dispatch] = useReducer(authReducer, initialState);

    const restoreSession = () => {
        dispatch({ type: 'SET_LOADING', payload: true });

        const token = localStorage.getItem('admin_token');
        const refreshToken = localStorage.getItem('admin_refresh_token');
        const userStr = localStorage.getItem('admin_user');
        const permissionsStr = localStorage.getItem('admin_permissions');

        if (token && userStr && permissionsStr) {
            try {
                const user = JSON.parse(userStr);
                const permissions = JSON.parse(permissionsStr);

                dispatch({
                    type: 'RESTORE_SESSION',
                    payload: {
                        user,
                        permissions,
                        allPermissions: permissions,
                        token,
                        refreshToken: refreshToken || ''
                    }
                });
            } catch (error) {
                localStorage.removeItem('admin_token');
                localStorage.removeItem('admin_refresh_token');
                localStorage.removeItem('admin_user');
                localStorage.removeItem('admin_permissions');
                dispatch({ type: 'SET_LOADING', payload: false });
            }
        } else {
            dispatch({ type: 'SET_LOADING', payload: false });
        }
    };

    useEffect(() => {
        restoreSession();
    }, []);

    const logout = () => {
        localStorage.removeItem('admin_token');
        localStorage.removeItem('admin_refresh_token');
        localStorage.removeItem('admin_user');
        localStorage.removeItem('admin_permissions');
        dispatch({ type: 'LOGOUT' });
        toast.success('خروج موفقیت‌آمیز بود');
    };

    const hasPermission = (permissionId: number): boolean => {
        // اگر Super Admin (id=1) باشد، به همه چیز دسترسی دارد
        const isSuperAdmin = state.permissions.some(permission => permission.id === 1);
        if (isSuperAdmin) return true;

        // در غیر اینصورت چک کن permission مورد نیاز را دارد یا نه
        return state.permissions.some(permission => permission.id === permissionId);
    };

    const hasPermissionByTitle = (title: string): boolean => {
        // اگر Super Admin (AdminAll) باشد، به همه چیز دسترسی دارد
        const isSuperAdmin = state.permissions.some(permission => permission.title === "AdminAll");
        if (isSuperAdmin) return true;

        // در غیر اینصورت چک کن permission مورد نیاز را دارد یا نه
        return state.permissions.some(permission => permission.title === title);
    };

    return (
        <AuthContext.Provider value={{
            ...state,
            logout,
            restoreSession,
            hasPermission,
            hasPermissionByTitle,
        }}>
            {children}
        </AuthContext.Provider>
    );
};

export const useAuth = () => {
    const context = useContext(AuthContext);
    if (context === undefined) {
        throw new Error('useAuth must be used within an AuthProvider');
    }
    return context;
}; 