import { createContext, useContext, useEffect, useState } from 'react';
import { generateId } from '@/lib/utils';
import { AdminUser, createSuperUser, createAdminUser, hasPermission } from '@/lib/admin';

interface User extends AdminUser {}

interface AuthContextType {
  user: User | null;
  isLoading: boolean;
  login: (email: string, password: string) => Promise<boolean>;
  register: (email: string, username: string, displayName: string, password: string) => Promise<boolean>;
  logout: () => void;
  updateProfile: (updates: Partial<User>) => Promise<boolean>;
  createSuperUser: (userData: { email: string; username: string; displayName: string; password: string; bio?: string; avatarUrl?: string }) => Promise<boolean>;
  createAdminUser: (userData: { email: string; username: string; displayName: string; password: string; bio?: string; avatarUrl?: string }) => Promise<boolean>;
  hasPermission: (permission: string) => boolean;
}

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

interface AuthProviderProps {
  children: React.ReactNode;
}

export function AuthProvider({ children }: AuthProviderProps) {
  const [user, setUser] = useState<User | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    // Check for existing session on mount
    const checkAuth = async () => {
      try {
        const token = localStorage.getItem('scriptshare-auth-token');
        if (token) {
          // In a real app, you'd validate the token with your backend
          // For now, we'll just check if it exists
          const userData = localStorage.getItem('scriptshare-user-data');
          if (userData) {
            setUser(JSON.parse(userData));
          }
        }
      } catch (error) {
        console.error('Auth check failed:', error);
      } finally {
        setIsLoading(false);
      }
    };

    checkAuth();
  }, []);

  const login = async (email: string, _password: string): Promise<boolean> => {
    try {
      setIsLoading(true);
      
      // In a real app, you'd make an API call to your backend
      // For now, we'll simulate a successful login
      await new Promise(resolve => setTimeout(resolve, 1000));
      
      // Simulate user data
      const mockUser: User = {
        id: generateId(),
        email,
        username: email.split('@')[0],
        displayName: email.split('@')[0],
        isAdmin: false,
        isModerator: false,
        isSuperUser: false,
        permissions: [],
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
      };

      const token = generateId();
      localStorage.setItem('scriptshare-auth-token', token);
      localStorage.setItem('scriptshare-user-data', JSON.stringify(mockUser));
      
      setUser(mockUser);
      return true;
    } catch (error) {
      console.error('Login failed:', error);
      return false;
    } finally {
      setIsLoading(false);
    }
  };

  const register = async (email: string, username: string, displayName: string, _password: string): Promise<boolean> => {
    try {
      setIsLoading(true);
      
      // In a real app, you'd make an API call to your backend
      // For now, we'll simulate a successful registration
      await new Promise(resolve => setTimeout(resolve, 1000));
      
      const mockUser: User = {
        id: generateId(),
        email,
        username,
        displayName,
        isAdmin: false,
        isModerator: false,
        isSuperUser: false,
        permissions: [],
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
      };

      const token = generateId();
      localStorage.setItem('scriptshare-auth-token', token);
      localStorage.setItem('scriptshare-user-data', JSON.stringify(mockUser));
      
      setUser(mockUser);
      return true;
    } catch (error) {
      console.error('Registration failed:', error);
      return false;
    } finally {
      setIsLoading(false);
    }
  };

  const logout = () => {
    localStorage.removeItem('scriptshare-auth-token');
    localStorage.removeItem('scriptshare-user-data');
    setUser(null);
  };

  const updateProfile = async (updates: Partial<User>): Promise<boolean> => {
    try {
      if (!user) return false;
      
      const updatedUser = { ...user, ...updates, updatedAt: new Date().toISOString() };
      localStorage.setItem('scriptshare-user-data', JSON.stringify(updatedUser));
      setUser(updatedUser);
      return true;
    } catch (error) {
      console.error('Profile update failed:', error);
      return false;
    }
  };

  const createSuperUserLocal = async (userData: { email: string; username: string; displayName: string; password: string; bio?: string; avatarUrl?: string }): Promise<boolean> => {
    try {
      // In a real app, you'd make an API call to your backend
      // For now, we'll simulate creating a superuser
      await new Promise(resolve => setTimeout(resolve, 1000));
      
      const newSuperUser = createSuperUser(userData);
      
      // Store in localStorage for demo purposes
      const existingUsers = JSON.parse(localStorage.getItem('scriptshare-admin-users') || '[]');
      existingUsers.push(newSuperUser);
      localStorage.setItem('scriptshare-admin-users', JSON.stringify(existingUsers));
      
      return true;
    } catch (error) {
      console.error('Super user creation failed:', error);
      return false;
    }
  };

  const createAdminUserLocal = async (userData: { email: string; username: string; displayName: string; password: string; bio?: string; avatarUrl?: string }): Promise<boolean> => {
    try {
      // In a real app, you'd make an API call to your backend
      // For now, we'll simulate creating an admin user
      await new Promise(resolve => setTimeout(resolve, 1000));
      
      const newAdminUser = createAdminUser(userData);
      
      // Store in localStorage for demo purposes
      const existingUsers = JSON.parse(localStorage.getItem('scriptshare-admin-users') || '[]');
      existingUsers.push(newAdminUser);
      localStorage.setItem('scriptshare-admin-users', JSON.stringify(existingUsers));
      
      return true;
    } catch (error) {
      console.error('Admin user creation failed:', error);
      return false;
    }
  };

  const hasPermission = (permission: string): boolean => {
    return hasPermission(user, permission);
  };

  const value = {
    user,
    isLoading,
    login,
    register,
    logout,
    updateProfile,
    createSuperUser: createSuperUserLocal,
    createAdminUser: createAdminUserLocal,
    hasPermission,
  };

  return (
    <AuthContext.Provider value={value}>
      {children}
    </AuthContext.Provider>
  );
}

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