import { NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from "@/lib/auth";
import { prisma } from '@/lib/prisma';

interface ImportTask {
    id?: string;
    title: string;
    description?: string | null;
    markdownContent?: string | null;
    completed?: boolean;
    isRolling?: boolean;
    order?: number;
    dayOfWeek?: number | null;
    scheduledDate?: string | null;
    somedayListId?: string | null;
    originalDate?: string | null;
    startTime?: string | null;
    endTime?: string | null;
    isRecurring?: boolean;
    recurrenceInterval?: number | null;
    recurrenceUnit?: string | null;
    recurrenceTime?: string | null;
    recurrenceEndDate?: string | null;
    createdAt?: string;
    updatedAt?: string;
    parentTaskId?: string | null;
    somedaySlotIndex?: number | null;
    projectId?: string | null;
    subTasks?: ImportTask[];
}

interface ImportWeeklyGoal {
    id?: string;
    weekStart: string;
    text: string;
    createdAt?: string;
    updatedAt?: string;
}

interface ImportData {
    exportVersion: number;
    somedayLists?: Array<{
        id?: string;
        title: string;
        order?: number;
        createdAt?: string;
        updatedAt?: string;
    }>;
    projects?: Array<{
        id?: string;
        name: string;
        icon?: string | null;
        color?: string | null;
        description?: string | null;
        order?: number;
        createdAt?: string;
        updatedAt?: string;
    }>;
    tasks?: ImportTask[];
    weeklyGoals?: ImportWeeklyGoal[];
}

export async function POST(request: Request) {
    const session = await getServerSession(authOptions);

    if (!session || !session.user?.email) {
        return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    try {
        const user = await prisma.user.findUnique({
            where: { email: session.user.email },
        });

        if (!user) {
            return NextResponse.json({ error: 'User not found' }, { status: 404 });
        }

        const { searchParams } = new URL(request.url);
        const mode = searchParams.get('mode') || 'merge';

        const body: ImportData = await request.json();

        // Validate structure
        if (!body.exportVersion || typeof body.exportVersion !== 'number') {
            return NextResponse.json({ error: 'Invalid export file: missing exportVersion' }, { status: 400 });
        }

        const somedayLists = body.somedayLists || [];
        const projects = body.projects || [];
        const tasks = body.tasks || [];
        const weeklyGoals = body.weeklyGoals || [];

        // ID mapping: old export ID -> new DB ID
        const listIdMap = new Map<string, string>();
        const projectIdMap = new Map<string, string>();
        const taskIdMap = new Map<string, string>();

        let importedLists = 0;
        let importedProjects = 0;
        let importedTasks = 0;
        let importedGoals = 0;

        // In replace mode, delete all existing data first
        if (mode === 'replace') {
            await prisma.task.deleteMany({ where: { userId: user.id } });
            await prisma.somedayList.deleteMany({ where: { userId: user.id } });
            await prisma.project.deleteMany({ where: { userId: user.id } });
            await prisma.weeklyGoal.deleteMany({ where: { userId: user.id } });
        }

        // 1. Import someday lists
        for (const list of somedayLists) {
            const created = await prisma.somedayList.create({
                data: {
                    userId: user.id,
                    title: list.title,
                    order: list.order ?? 0,
                },
            });
            if (list.id) {
                listIdMap.set(list.id, created.id);
            }
            importedLists++;
        }

        // 2. Import projects
        for (const project of projects) {
            const created = await prisma.project.create({
                data: {
                    userId: user.id,
                    name: project.name,
                    icon: project.icon ?? null,
                    color: project.color ?? null,
                    description: project.description ?? null,
                    order: project.order ?? 0,
                },
            });
            if (project.id) {
                projectIdMap.set(project.id, created.id);
            }
            importedProjects++;
        }

        // 3. Import tasks (two-pass: parents first, then link subtasks)
        // Flatten all tasks with their subtasks
        const flatTasks: Array<{ task: ImportTask; originalParentId: string | null }> = [];

        function flattenTasks(taskList: ImportTask[], parentId: string | null) {
            for (const task of taskList) {
                flatTasks.push({ task, originalParentId: parentId });
                if (task.subTasks && task.subTasks.length > 0) {
                    flattenTasks(task.subTasks, task.id || null);
                }
            }
        }

        flattenTasks(tasks, null);

        // Pass 1: Create all tasks without parentTaskId
        for (const { task } of flatTasks) {
            const resolvedListId = task.somedayListId ? listIdMap.get(task.somedayListId) : null;
            const resolvedProjectId = task.projectId ? projectIdMap.get(task.projectId) : null;

            const created = await prisma.task.create({
                data: {
                    userId: user.id,
                    title: task.title,
                    description: task.description ?? null,
                    markdownContent: task.markdownContent ?? null,
                    completed: task.completed ?? false,
                    isRolling: task.isRolling ?? false,
                    order: task.order ?? 0,
                    dayOfWeek: task.dayOfWeek ?? null,
                    scheduledDate: task.scheduledDate ? new Date(task.scheduledDate) : null,
                    somedayListId: resolvedListId ?? null,
                    originalDate: task.originalDate ? new Date(task.originalDate) : null,
                    startTime: task.startTime ?? null,
                    endTime: task.endTime ?? null,
                    isRecurring: task.isRecurring ?? false,
                    recurrenceInterval: task.recurrenceInterval ?? null,
                    recurrenceUnit: task.recurrenceUnit ?? null,
                    recurrenceTime: task.recurrenceTime ?? null,
                    recurrenceEndDate: task.recurrenceEndDate ? new Date(task.recurrenceEndDate) : null,
                    somedaySlotIndex: task.somedaySlotIndex ?? null,
                    projectId: resolvedProjectId ?? null,
                },
            });

            if (task.id) {
                taskIdMap.set(task.id, created.id);
            }
            importedTasks++;
        }

        // Pass 2: Link subtasks to their parents
        for (const { task, originalParentId } of flatTasks) {
            if (originalParentId && task.id) {
                const newTaskId = taskIdMap.get(task.id);
                const newParentId = taskIdMap.get(originalParentId);
                if (newTaskId && newParentId) {
                    await prisma.task.update({
                        where: { id: newTaskId },
                        data: { parentTaskId: newParentId },
                    });
                }
            }
        }

        // 4. Import weekly goals (upsert by weekStart to avoid duplicates)
        for (const goal of weeklyGoals) {
            const weekStart = new Date(goal.weekStart);
            await prisma.weeklyGoal.upsert({
                where: {
                    userId_weekStart: {
                        userId: user.id,
                        weekStart,
                    },
                },
                update: {
                    text: goal.text,
                },
                create: {
                    userId: user.id,
                    weekStart,
                    text: goal.text,
                },
            });
            importedGoals++;
        }

        return NextResponse.json({
            success: true,
            mode,
            imported: {
                somedayLists: importedLists,
                projects: importedProjects,
                tasks: importedTasks,
                weeklyGoals: importedGoals,
            },
        });
    } catch (error) {
        console.error('Import data error:', error);
        const message = error instanceof SyntaxError
            ? 'Invalid JSON file'
            : 'Import failed. Please check the file format.';
        return NextResponse.json({ error: message }, { status: 500 });
    }
}
