'use client';

import { useState, useEffect } from 'react';
import {
    BookProject,
    Chapter,
    Entity,
    EntityType,
    UserProfile,
} from '@/lib/types';
import api from '@/lib/api';
import {
    DEFAULT_BOOK_TITLE,
    DEFAULT_AUTHOR,
    INITIAL_CHAPTER
} from '@/lib/constants';

export const useProjects = (user: UserProfile | null) => {
    const [projects, setProjects] = useState<BookProject[]>([]);
    const [currentProjectId, setCurrentProjectId] = useState<string | null>(null);
    const [loading, setLoading] = useState(false);

    // Load Projects
    useEffect(() => {
        if (!user) {
            setProjects([]);
            return;
        }
        const loadProjects = async () => {
            setLoading(true);
            try {
                const data = await api.projects.list();
                const mapped: BookProject[] = (data || []).map((p: any) => ({
                    id: p.id,
                    title: p.title,
                    author: p.author,
                    lastModified: new Date(p.updatedAt).getTime(),
                    // Use _count for display before full details are loaded
                    chapters: Array.from({ length: p._count?.chapters || 0 }, (_, i) => ({ id: `placeholder-${i}`, title: '', content: '' })),
                    entities: Array.from({ length: p._count?.entities || 0 }, (_, i) => ({ id: `placeholder-${i}`, type: 'character' as any, name: '', description: '' })),
                    ideas: [],
                    settings: p.settings || undefined
                }));
                setProjects(mapped);
            } catch (err) {
                console.error('Failed to load projects', err);
            } finally {
                setLoading(false);
            }
        };
        loadProjects();
    }, [user]);

    // Load details when project is selected
    useEffect(() => {
        if (!currentProjectId) return;

        const loadProjectDetails = async () => {
            try {
                const fullProject = await api.projects.get(currentProjectId);
                const mapped: BookProject = {
                    id: fullProject.id,
                    title: fullProject.title,
                    author: fullProject.author,
                    lastModified: new Date(fullProject.updatedAt).getTime(),
                    settings: fullProject.settings || undefined,
                    styleGuide: fullProject.styleGuide || undefined,
                    chapters: (fullProject.chapters || []).map((c: any) => ({
                        id: c.id,
                        title: c.title,
                        content: c.content,
                        summary: c.summary,
                    })),
                    entities: (fullProject.entities || []).map((e: any) => ({
                        id: e.id,
                        type: e.type,
                        name: e.name,
                        description: e.description,
                        details: e.details,
                        storyContext: e.storyContext,
                        attributes: e.attributes,
                        customValues: e.customValues,
                    })),
                    ideas: (fullProject.ideas || []).map((i: any) => ({
                        id: i.id,
                        title: i.title,
                        description: i.description,
                        status: i.status,
                        category: i.category,
                        createdAt: new Date(i.createdAt).getTime(),
                    })),
                    workflow: {
                        nodes: (fullProject.plotNodes || []).map((n: any) => ({
                            id: n.id,
                            x: n.x,
                            y: n.y,
                            title: n.title,
                            description: n.description,
                            color: n.color,
                            type: n.type,
                        })),
                        connections: (fullProject.plotConnections || []).map((c: any) => ({
                            id: c.id,
                            source: c.source,
                            target: c.target,
                        })),
                    },
                };
                setProjects(prev => prev.map(p => p.id === currentProjectId ? mapped : p));
            } catch (err) {
                console.error("Failed to load project details", err);
            }
        };
        loadProjectDetails();
    }, [currentProjectId]);

    const createProject = async () => {
        if (!user) return;

        try {
            const created = await api.projects.create({
                title: DEFAULT_BOOK_TITLE,
                author: user.name || DEFAULT_AUTHOR,
                settings: { genre: 'Fantasy', targetAudience: 'Adult', tone: 'Epic' },
            });

            const newProject: BookProject = {
                id: created.id,
                title: created.title,
                author: created.author,
                lastModified: Date.now(),
                chapters: [],
                entities: [],
                ideas: [],
                settings: created.settings,
            };

            setProjects(prev => [...prev, newProject]);
            await addChapter(created.id, INITIAL_CHAPTER);
            return created.id;
        } catch (err) {
            console.error('Failed to create project', err);
            throw err;
        }
    };

    const updateProject = async (id: string, data: Partial<BookProject>) => {
        setProjects(prev => prev.map(p => p.id === id ? { ...p, ...data } : p));

        try {
            // Persist project fields
            const payload: any = {};
            if (data.title !== undefined) payload.title = data.title;
            if (data.author !== undefined) payload.author = data.author;
            if (data.settings !== undefined) payload.settings = data.settings;
            if (data.styleGuide !== undefined) payload.styleGuide = data.styleGuide;
            if (Object.keys(payload).length > 0) {
                await api.projects.update(id, payload);
            }

            // Persist workflow (nodes + connections) separately
            if (data.workflow) {
                await api.projects.syncWorkflow(id, {
                    nodes: data.workflow.nodes || [],
                    connections: data.workflow.connections || [],
                });
            }
        } catch (err) {
            console.error("Failed to update project", err);
        }
    };

    const addChapter = async (projectId: string, chapterData: Partial<Chapter>) => {
        try {
            const newChap = await api.chapters.create({
                projectId,
                title: chapterData.title || 'New Chapter',
                content: chapterData.content || '',
                summary: chapterData.summary || undefined,
            });

            setProjects(prev => prev.map(p => {
                if (p.id !== projectId) return p;
                return {
                    ...p,
                    chapters: [...p.chapters, {
                        id: newChap.id,
                        title: newChap.title,
                        content: newChap.content,
                        summary: newChap.summary,
                    }]
                };
            }));
            return newChap.id;
        } catch (err) {
            console.error("Failed to add chapter", err);
            return null;
        }
    };

    const updateChapter = async (projectId: string, chapterId: string, data: Partial<Chapter>) => {
        setProjects(prev => prev.map(p => {
            if (p.id !== projectId) return p;
            return {
                ...p,
                chapters: p.chapters.map(c => c.id === chapterId ? { ...c, ...data } : c)
            };
        }));

        try {
            await api.chapters.update(chapterId, data);
        } catch (err) {
            console.error("Failed to update chapter", err);
        }
    };

    const createEntity = async (projectId: string, type: EntityType, initialData?: Partial<Entity>) => {
        try {
            const newEntity = await api.entities.create({
                projectId,
                type,
                name: initialData?.name || `Nouveau ${type}`,
                description: initialData?.description || '',
                details: initialData?.details || '',
                attributes: initialData?.attributes || undefined,
                customValues: initialData?.customValues || undefined,
            });

            setProjects(prev => prev.map(p => {
                if (p.id !== projectId) return p;
                return {
                    ...p,
                    entities: [...p.entities, {
                        id: newEntity.id,
                        type: newEntity.type,
                        name: newEntity.name,
                        description: newEntity.description,
                        details: newEntity.details,
                        attributes: newEntity.attributes,
                        customValues: newEntity.customValues || {},
                    }]
                };
            }));
            return newEntity.id;
        } catch (err) {
            console.error("Failed to create entity", err);
            throw err;
        }
    };

    const updateEntity = async (projectId: string, entityId: string, data: Partial<Entity>) => {
        setProjects(prev => prev.map(p => {
            if (p.id !== projectId) return p;
            return {
                ...p,
                entities: p.entities.map(e => e.id === entityId ? { ...e, ...data } : e)
            };
        }));

        try {
            await api.entities.update(entityId, data);
        } catch (err) {
            console.error("Failed to update entity", err);
        }
    };

    const deleteEntity = async (projectId: string, entityId: string) => {
        setProjects(prev => prev.map(p => {
            if (p.id !== projectId) return p;
            return {
                ...p,
                entities: p.entities.filter(e => e.id !== entityId)
            };
        }));

        try {
            await api.entities.delete(entityId);
        } catch (err) {
            console.error("Failed to delete entity", err);
        }
    };

    return {
        projects,
        currentProjectId,
        setCurrentProjectId,
        createProject,
        updateProject,
        addChapter,
        updateChapter,
        createEntity,
        updateEntity,
        deleteEntity,
        deleteProject: async (projectId: string) => {
            try {
                // Cascade delete is handled by Prisma, just delete the project
                await api.projects.delete(projectId);

                setProjects(prev => prev.filter(p => p.id !== projectId));
                if (currentProjectId === projectId) {
                    setCurrentProjectId(null);
                }
            } catch (err) {
                console.error("Failed to delete project", err);
            }
        }
    };
};
