import React, { createContext, useContext, useReducer, useCallback } from 'react'; import { ApiMangaRepository } from '../../infrastructure/api/apiMangaRepository'; import { GetMangaCollection } from '../../application/useCases/getMangaCollection'; import { GetMangaDetail } from '../../application/useCases/getMangaDetail'; const mangaRepository = new ApiMangaRepository(); const getMangaCollection = new GetMangaCollection(mangaRepository); const getMangaDetail = new GetMangaDetail(mangaRepository); const MangaContext = createContext(null); const initialState = { collection: null, detailedMangas: {}, loading: false, error: null }; function mangaReducer(state, action) { switch (action.type) { case 'SET_LOADING': return { ...state, loading: action.payload }; case 'SET_ERROR': return { ...state, error: action.payload, loading: false }; case 'SET_COLLECTION': return { ...state, collection: action.payload, loading: false, error: null }; case 'SET_MANGA_DETAIL': return { ...state, detailedMangas: { ...state.detailedMangas, [action.payload.slug]: action.payload }, loading: false, error: null }; default: return state; } } export function MangaProvider({ children }) { const [state, dispatch] = useReducer(mangaReducer, initialState); const loadCollection = useCallback(async () => { if (state.collection) return; // Return if already loaded dispatch({ type: 'SET_LOADING', payload: true }); try { const collection = await getMangaCollection.execute(1); dispatch({ type: 'SET_COLLECTION', payload: collection }); } catch (error) { dispatch({ type: 'SET_ERROR', payload: 'Failed to load manga collection' }); console.error(error); } }, []); const loadMangaDetail = useCallback(async (slug) => { // Return cached data if available if (state.detailedMangas[slug]) return state.detailedMangas[slug]; dispatch({ type: 'SET_LOADING', payload: true }); try { const manga = await getMangaDetail.execute(slug); dispatch({ type: 'SET_MANGA_DETAIL', payload: manga }); return manga; } catch (error) { dispatch({ type: 'SET_ERROR', payload: 'Failed to load manga details' }); console.error(error); return null; } }, []); const getMangaFromCollection = useCallback((slug) => { if (!state.collection) return null; return state.collection.items.find(manga => manga.slug === slug); }, [state.collection]); const value = { ...state, loadCollection, loadMangaDetail, getMangaFromCollection }; return ( {children} ); } export function useManga() { const context = useContext(MangaContext); if (!context) { throw new Error('useManga must be used within a MangaProvider'); } return context; }