'use client' import { useState, useEffect, useCallback } from 'react' import { apiFetch } from '@/lib/api' export type EmployeeRole = 'OWNER' | 'MANAGER' | 'AGENT' export type InvitationStatus = 'accepted' | 'pending' | 'revoked' export interface TeamMember { id: string firstName: string lastName: string email: string phone: string | null role: EmployeeRole isActive: boolean createdAt: string updatedAt: string lastActiveAt: string | null invitationStatus: InvitationStatus } export interface TeamStats { total: number active: number pending: number inactive: number } export interface InvitePayload { firstName: string lastName: string email: string role: 'MANAGER' | 'AGENT' } export function appendInvitedMember(members: TeamMember[], employee: TeamMember): TeamMember[] { return [...members, employee] } export function incrementInvitedStats(stats: TeamStats): TeamStats { return { ...stats, total: stats.total + 1, pending: stats.pending + 1 } } export function applyMemberRoleUpdate(members: TeamMember[], memberId: string, role: 'MANAGER' | 'AGENT'): TeamMember[] { return members.map((member) => (member.id === memberId ? { ...member, role } : member)) } export function applyMemberActivation(members: TeamMember[], memberId: string, isActive: boolean): TeamMember[] { return members.map((member) => (member.id === memberId ? { ...member, isActive } : member)) } export function applyActivationStats(stats: TeamStats, direction: 'deactivate' | 'reactivate'): TeamStats { return direction === 'deactivate' ? { ...stats, active: stats.active - 1, inactive: stats.inactive + 1 } : { ...stats, active: stats.active + 1, inactive: stats.inactive - 1 } } export function removeTeamMemberState(members: TeamMember[], stats: TeamStats, memberId: string): { members: TeamMember[]; stats: TeamStats } { const target = members.find((member) => member.id === memberId) return { members: members.filter((member) => member.id !== memberId), stats: { ...stats, total: stats.total - (target ? 1 : 0), active: target?.isActive ? stats.active - 1 : stats.active, pending: target?.invitationStatus === 'pending' ? stats.pending - 1 : stats.pending, inactive: !target?.isActive && target?.invitationStatus === 'accepted' ? stats.inactive - 1 : stats.inactive, }, } } export function useTeam() { const [members, setMembers] = useState([]) const [stats, setStats] = useState({ total: 0, active: 0, pending: 0, inactive: 0 }) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const refetch = useCallback(async () => { setLoading(true) setError(null) try { const [membersData, statsData] = await Promise.all([ apiFetch('/team'), apiFetch('/team/stats'), ]) setMembers(membersData) setStats(statsData) } catch (err: any) { setError(err.message) } finally { setLoading(false) } }, []) useEffect(() => { refetch() }, [refetch]) const invite = useCallback(async (payload: InvitePayload) => { const result = await apiFetch<{ employee: TeamMember; invitationId: string }>( '/team/invite', { method: 'POST', body: JSON.stringify(payload) } ) setMembers((prev) => appendInvitedMember(prev, result.employee)) setStats(incrementInvitedStats) return result }, []) const updateRole = useCallback(async (memberId: string, role: 'MANAGER' | 'AGENT') => { const updated = await apiFetch(`/team/${memberId}/role`, { method: 'PATCH', body: JSON.stringify({ role }), }) setMembers((prev) => applyMemberRoleUpdate(prev, memberId, updated.role as 'MANAGER' | 'AGENT')) return updated }, []) const deactivate = useCallback(async (memberId: string) => { const updated = await apiFetch(`/team/${memberId}/deactivate`, { method: 'POST', }) setMembers((prev) => applyMemberActivation(prev, memberId, false)) setStats((prev) => applyActivationStats(prev, 'deactivate')) return updated }, []) const reactivate = useCallback(async (memberId: string) => { const updated = await apiFetch(`/team/${memberId}/reactivate`, { method: 'POST', }) setMembers((prev) => applyMemberActivation(prev, memberId, true)) setStats((prev) => applyActivationStats(prev, 'reactivate')) return updated }, []) const remove = useCallback(async (memberId: string) => { await apiFetch<{ success: boolean }>(`/team/${memberId}`, { method: 'DELETE', }) const nextState = removeTeamMemberState(members, stats, memberId) setMembers(nextState.members) setStats(nextState.stats) }, [members, stats]) return { members, stats, loading, error, refetch, invite, updateRole, deactivate, reactivate, remove, } }