import React, { createContext, useContext, useState, useCallback, useEffect } from 'react';
import { authApi } from '../api';
import { setAccessToken } from '../api/client';
import { wsClient } from '../api/websocket';
import type { Profile, Company, UserRole, AuthState } from '../types';

interface RegisterData {
  username: string;
  password: string;
  displayName: string;
  companyName: string;
  phone: string;
  role: UserRole;
}

interface AuthContextType {
  auth: AuthState;
  login: (username: string, password: string) => Promise<boolean>;
  register: (data: RegisterData) => Promise<{ success: boolean; error?: string }>;
  logout: () => Promise<void>;
  selectRole: (role: UserRole) => void;
  loading: boolean;
}

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

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [auth, setAuth] = useState<AuthState>({
    isLoggedIn: false,
    user: null,
    company: null,
    currentRole: null
  });
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const initAuth = async () => {
      try {
        await authApi.refresh();
        const { user, company } = await authApi.me();
        setAuth({
          isLoggedIn: true,
          user,
          company,
          currentRole: company?.role || null
        });
        if (company?.role) {
          wsClient.connect(company.role);
        }
      } catch {
        // not logged in
      }
      setLoading(false);
    };
    initAuth();

    const handleExpired = () => {
      wsClient.disconnect();
      setAuth({
        isLoggedIn: false,
        user: null,
        company: null,
        currentRole: null
      });
    };
    window.addEventListener('auth:expired', handleExpired);
    return () => window.removeEventListener('auth:expired', handleExpired);
  }, []);

  const login = useCallback(async (username: string, password: string): Promise<boolean> => {
    try {
      const { user, company } = await authApi.login({ username, password });
      setAuth({
        isLoggedIn: true,
        user,
        company,
        currentRole: company?.role || null
      });
      if (company?.role) {
        wsClient.connect(company.role);
      }
      return true;
    } catch {
      return false;
    }
  }, []);

  const register = useCallback(async (data: RegisterData): Promise<{ success: boolean; error?: string }> => {
    try {
      const res = await authApi.register({
        username: data.username,
        password: data.password,
        display_name: data.displayName,
        company_name: data.companyName,
        phone: data.phone,
        role: data.role,
      });
      setAccessToken(res.access_token);
      setAuth({
        isLoggedIn: true,
        user: res.user,
        company: res.company,
        currentRole: res.company?.role || null
      });
      if (res.company?.role) {
        wsClient.connect(res.company.role);
      }
      return { success: true };
    } catch (err: unknown) {
      const message = err instanceof Error ? err.message : '注册失败，请稍后重试';
      return { success: false, error: message };
    }
  }, []);

  const logout = useCallback(async () => {
    try { await authApi.logout(); } catch { /* ignore */ }
    wsClient.disconnect();
    localStorage.removeItem('saved_username');
    localStorage.removeItem('saved_password');
    localStorage.removeItem('auto_login');
    localStorage.removeItem('auto_login_expiry');
    setAuth({
      isLoggedIn: false,
      user: null,
      company: null,
      currentRole: null
    });
  }, []);

  const selectRole = useCallback((role: UserRole) => {
    setAuth(prev => ({ ...prev, currentRole: role }));
  }, []);

  return (
    <AuthContext.Provider value={{ auth, login, register, logout, selectRole, loading }}>
      {children}
    </AuthContext.Provider>
  );
}

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