import { MangaCollection } from '../../domain/entities/manga';

export class ApiMangaRepository {
    async getCollection() {
        try {
            const response = await fetch('/api/mangas');
            if (!response.ok) {
                throw new Error('Failed to fetch manga collection');
            }
            const data = await response.json();
            return new MangaCollection(
                data.items,
                data.total,
                data.page,
                data.limit,
                data.hasNextPage,
                data.hasPreviousPage
            );
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async getMangaById(id) {
        try {
            const response = await fetch(`/api/mangas/by-id/${id}`);
            if (!response.ok) {
                throw new Error('Failed to fetch manga details');
            }
            return await response.json();
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async getChapters(mangaId) {
        try {
            let allChapters = [];
            let page = 1;
            let hasMore = true;

            while (hasMore) {
                const response = await fetch(`/api/mangas/${mangaId}/chapters?limit=500&page=${page}`);
                if (!response.ok) {
                    throw new Error('Failed to fetch manga chapters');
                }
                const data = await response.json();
                allChapters = allChapters.concat(data.items);
                hasMore = data.hasNextPage;
                page++;
            }

            // Filtrer pour ne garder que les chapitres visibles
            const visibleChapters = allChapters.filter(chapter => chapter.isVisible === true);

            return {
                items: visibleChapters,
                total: visibleChapters.length
            };
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async getMangaBySlug(slug) {
        try {
            const response = await fetch(`/api/mangas/by-slug/${slug}`);
            if (!response.ok) {
                throw new Error('Failed to fetch manga details');
            }
            return await response.json();
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async searchMangas(query) {
        try {
            const response = await fetch(`/api/manga-search?q=${encodeURIComponent(query)}`);
            if (!response.ok) {
                throw new Error('Failed to search mangas');
            }
            return await response.json();
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async searchMangaDex(query) {
        try {
            const response = await fetch(`/api/mangadex-search?title=${encodeURIComponent(query)}`);
            if (!response.ok) {
                throw new Error('Failed to search MangaDex');
            }
            return await response.json();
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async discoverManga() {
        try {
            const response = await fetch('/api/manga-discover');
            if (!response.ok) throw new Error('Failed to fetch discover recommendations');
            return await response.json();
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async createFromMangaDex(externalId) {
        try {
            const response = await fetch('/api/mangas/create-from-mangadex', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ externalId })
            });
            if (!response.ok) {
                throw new Error('Failed to create manga from MangaDex');
            }
            return await response.json();
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async fetchMangaChapters(mangaId) {
        try {
            const response = await fetch(`/api/manga/chapters/fetch`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ mangaId })
            });
            if (!response.ok) {
                throw new Error('Failed to fetch manga chapters');
            }
            return await response.json();
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async refreshMangaChapters(mangaId) {
        try {
            const response = await fetch(`/api/manga/${mangaId}/chapters/refresh`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({})
            });
            if (!response.ok) {
                throw new Error('Failed to refresh manga chapters');
            }
            // L'endpoint retourne 202 (Accepted), pas de contenu JSON à parser
            return true;
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async searchChapter(chapterId) {
        try {
            const response = await fetch('/api/scraping/chapters', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ chapterId })
            });
            if (!response.ok) {
                throw new Error('Échec de la recherche du chapitre');
            }
            return await response.json();
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async getPreferredSources(mangaId) {
        try {
            const response = await fetch(`/api/mangas/${mangaId}/preferred-sources`);
            if (!response.ok) {
                throw new Error('Failed to fetch preferred sources');
            }
            return await response.json();
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async setPreferredSources(mangaId, sourceIds) {
        try {
            const response = await fetch(`/api/mangas/${mangaId}/preferred-sources`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ sourceIds })
            });
            if (!response.ok) {
                throw new Error('Failed to set preferred sources');
            }
            return await response.json();
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async editManga(mangaId, updateData) {
        try {
            const response = await fetch(`/api/mangas/${mangaId}/edit`, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(updateData)
            });
            if (!response.ok) {
                throw new Error('Failed to edit manga');
            }
            return await response.json();
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async deleteChapter(chapterId) {
        try {
            const response = await fetch(`/api/manga/chapters/${chapterId}/cbz`, {
                method: 'DELETE'
            });
            if (!response.ok) {
                throw new Error('Failed to delete chapter');
            }
            return true;
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

                async downloadChapter(chapterId) {
        try {
            const response = await fetch(`/api/manga/chapters/${chapterId}/download`);
            if (!response.ok) {
                throw new Error('Failed to download chapter');
            }

            // Récupérer le nom du fichier depuis les headers
            const contentDisposition = response.headers.get('Content-Disposition');
            let filename = `chapter-${chapterId}.cbz`;

            if (contentDisposition) {
                const filenameMatch = contentDisposition.match(/filename="?(.+)"?/);
                if (filenameMatch) {
                    filename = filenameMatch[1];
                }
            }

            // Créer un blob à partir de la réponse
            const blob = await response.blob();

            // Créer un lien de téléchargement temporaire
            const url = window.URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.href = url;
            link.download = filename;
            document.body.appendChild(link);
            link.click();

            // Nettoyer
            document.body.removeChild(link);
            window.URL.revokeObjectURL(url);

            return true;
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async hideChapter(chapterId) {
        try {
            const response = await fetch(`/api/manga/chapters/${chapterId}`, {
                method: 'DELETE'
            });
            if (!response.ok) {
                throw new Error('Failed to hide chapter');
            }
            return true;
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async downloadVolume(mangaId, volumeNumber) {
        try {
            const response = await fetch(`/api/mangas/${mangaId}/volumes/${volumeNumber}/download`);
            if (!response.ok) {
                throw new Error('Failed to download volume');
            }

            // Récupérer le nom du fichier depuis les headers
            const contentDisposition = response.headers.get('Content-Disposition');
            let filename = `volume-${volumeNumber}.zip`;

            if (contentDisposition) {
                const filenameMatch = contentDisposition.match(/filename="?(.+)"?/);
                if (filenameMatch) {
                    filename = filenameMatch[1];
                }
            }

            // Créer un blob à partir de la réponse
            const blob = await response.blob();

            // Créer un lien de téléchargement temporaire
            const url = window.URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.href = url;
            link.download = filename;
            document.body.appendChild(link);
            link.click();

            // Nettoyer
            document.body.removeChild(link);
            window.URL.revokeObjectURL(url);

            return true;
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async toggleMonitoring(mangaId, enabled) {
        try {
            const response = await fetch(`/api/manga/${mangaId}/monitoring/toggle`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ enabled })
            });

            if (!response.ok) {
                // Tenter de récupérer le message d'erreur détaillé de l'API
                let errorMessage = 'Failed to toggle monitoring';
                try {
                    const errorData = await response.json();
                    if (errorData.detail) {
                        errorMessage = errorData.detail;
                    } else if (errorData.message) {
                        errorMessage = errorData.message;
                    } else if (errorData.violations && errorData.violations.length > 0) {
                        errorMessage = errorData.violations.map(v => v.message).join(', ');
                    }
                } catch (parseError) {
                    console.warn('Could not parse error response:', parseError);
                }
                throw new Error(errorMessage);
            }

            // L'endpoint retourne un statut 204 (No Content), donc pas de données à retourner
            return true;
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }

    async deleteManga(mangaId) {
        try {
            const response = await fetch(`/api/mangas/${mangaId}`, {
                method: 'DELETE',
                headers: {
                    'Content-Type': 'application/json',
                }
            });

            if (!response.ok) {
                throw new Error('Failed to delete manga');
            }

            return true;
        } catch (error) {
            console.error('API Error:', error);
            throw error;
        }
    }
}
