import { createContext, useCallback, useContext, useEffect, useMemo, useState, type ReactNode, } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import type { Company } from "@paperclip/shared"; import { companiesApi } from "../api/companies"; import { queryKeys } from "../lib/queryKeys"; interface CompanyContextValue { companies: Company[]; selectedCompanyId: string | null; selectedCompany: Company | null; loading: boolean; error: Error | null; setSelectedCompanyId: (companyId: string) => void; reloadCompanies: () => Promise; createCompany: (data: { name: string; description?: string | null; budgetMonthlyCents?: number; }) => Promise; } const STORAGE_KEY = "paperclip.selectedCompanyId"; const CompanyContext = createContext(null); export function CompanyProvider({ children }: { children: ReactNode }) { const queryClient = useQueryClient(); const [selectedCompanyId, setSelectedCompanyIdState] = useState( () => localStorage.getItem(STORAGE_KEY) ); const { data: companies = [], isLoading, error } = useQuery({ queryKey: queryKeys.companies.all, queryFn: () => companiesApi.list(), }); // Auto-select first company when list loads useEffect(() => { if (companies.length === 0) return; const stored = localStorage.getItem(STORAGE_KEY); if (stored && companies.some((c) => c.id === stored)) return; if (selectedCompanyId && companies.some((c) => c.id === selectedCompanyId)) return; const next = companies[0]!.id; setSelectedCompanyIdState(next); localStorage.setItem(STORAGE_KEY, next); }, [companies, selectedCompanyId]); const setSelectedCompanyId = useCallback((companyId: string) => { setSelectedCompanyIdState(companyId); localStorage.setItem(STORAGE_KEY, companyId); }, []); const reloadCompanies = useCallback(async () => { await queryClient.invalidateQueries({ queryKey: queryKeys.companies.all }); }, [queryClient]); const createMutation = useMutation({ mutationFn: (data: { name: string; description?: string | null; budgetMonthlyCents?: number }) => companiesApi.create(data), onSuccess: (company) => { queryClient.invalidateQueries({ queryKey: queryKeys.companies.all }); setSelectedCompanyId(company.id); }, }); const createCompany = useCallback( async (data: { name: string; description?: string | null; budgetMonthlyCents?: number }) => { return createMutation.mutateAsync(data); }, [createMutation], ); const selectedCompany = useMemo( () => companies.find((company) => company.id === selectedCompanyId) ?? null, [companies, selectedCompanyId], ); const value = useMemo( () => ({ companies, selectedCompanyId, selectedCompany, loading: isLoading, error: error as Error | null, setSelectedCompanyId, reloadCompanies, createCompany, }), [ companies, selectedCompanyId, selectedCompany, isLoading, error, setSelectedCompanyId, reloadCompanies, createCompany, ], ); return {children}; } export function useCompany() { const ctx = useContext(CompanyContext); if (!ctx) { throw new Error("useCompany must be used within CompanyProvider"); } return ctx; }