import { useState, useCallback } from 'react' import { branchesApi } from '@/api/branches' import { toast } from '@/lib/toast' import type { BranchResponse, ForkCreateRequest, ForkPointResponse, BranchSwitchResponse, ReviveRequest, BranchMessageRequest, BranchMessageResponse, } from '@/types/branching' export interface UseBranching { // State branches: BranchResponse[] activeBranchId: string | null isLoading: boolean isProcessing: boolean // Actions loadBranches: (sessionId: string) => Promise createFork: (sessionId: string, data: ForkCreateRequest) => Promise switchBranch: (sessionId: string, branchId: string) => Promise updateStatus: (sessionId: string, branchId: string, status: string, reason?: string) => Promise reviveBranch: (sessionId: string, branchId: string, data: ReviveRequest) => Promise sendMessage: (sessionId: string, branchId: string, data: BranchMessageRequest) => Promise } export function useBranching(): UseBranching { const [branches, setBranches] = useState([]) const [activeBranchId, setActiveBranchId] = useState(null) const [isLoading, setIsLoading] = useState(false) const [isProcessing, setIsProcessing] = useState(false) const loadBranches = useCallback(async (sessionId: string) => { setIsLoading(true) try { const result = await branchesApi.getBranches(sessionId) setBranches(result.branches) setActiveBranchId(result.active_branch_id) } catch { toast.error('Failed to load branches') } finally { setIsLoading(false) } }, []) const createFork = useCallback(async ( sessionId: string, data: ForkCreateRequest ): Promise => { setIsProcessing(true) try { const result = await branchesApi.createFork(sessionId, data) // Reload branches to reflect the new fork const updated = await branchesApi.getBranches(sessionId) setBranches(updated.branches) setActiveBranchId(updated.active_branch_id) return result } catch { toast.error('Failed to create fork') return null } finally { setIsProcessing(false) } }, []) const switchBranch = useCallback(async ( sessionId: string, branchId: string ): Promise => { setIsProcessing(true) try { const result = await branchesApi.switchBranch(sessionId, branchId) setActiveBranchId(result.active_branch_id) setBranches(prev => prev.map(b => b.id === result.active_branch_id ? result.branch : b) ) return result } catch { toast.error('Failed to switch branch') return null } finally { setIsProcessing(false) } }, []) const updateStatus = useCallback(async ( sessionId: string, branchId: string, status: string, reason?: string ) => { setIsProcessing(true) try { await branchesApi.updateBranchStatus(sessionId, branchId, status, reason) setBranches(prev => prev.map(b => b.id === branchId ? { ...b, status: status as BranchResponse['status'], status_reason: reason ?? b.status_reason } : b ) ) } catch { toast.error('Failed to update branch status') } finally { setIsProcessing(false) } }, []) const reviveBranch = useCallback(async ( sessionId: string, branchId: string, data: ReviveRequest ) => { setIsProcessing(true) try { await branchesApi.reviveBranch(sessionId, branchId, data) // Reload to get updated statuses const updated = await branchesApi.getBranches(sessionId) setBranches(updated.branches) setActiveBranchId(updated.active_branch_id) toast.success('Branch revived') } catch { toast.error('Failed to revive branch') } finally { setIsProcessing(false) } }, []) const sendMessage = useCallback(async ( sessionId: string, branchId: string, data: BranchMessageRequest ): Promise => { setIsProcessing(true) try { const result = await branchesApi.sendBranchMessage(sessionId, branchId, data) return result } catch { toast.error('Failed to send message') return null } finally { setIsProcessing(false) } }, []) return { branches, activeBranchId, isLoading, isProcessing, loadBranches, createFork, switchBranch, updateStatus, reviveBranch, sendMessage, } }