import { ExperienceTemplateState } from "@prisma/client";
import { NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import {
  canAccessExperienciometro,
  canConfigureExperienciometro,
  ensureExperienceBaseline,
  mapExperienceTemplate,
} from "@/lib/experienciometro";

export async function GET() {
  const session = await getServerSession(authOptions);
  if (!session?.user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  if (!canAccessExperienciometro(session.user.role)) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }

  await ensureExperienceBaseline(prisma, session.user.id);

  const templates = await prisma.experienceTemplate.findMany({
    include: {
      categories: {
        include: {
          items: {
            orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
          },
        },
        orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
      },
    },
    orderBy: [{ updatedAt: "desc" }, { createdAt: "desc" }],
    take: 50,
  });

  return NextResponse.json({
    ok: true,
    templates: templates.map(mapExperienceTemplate),
  });
}

export async function POST(request: Request) {
  const session = await getServerSession(authOptions);
  if (!session?.user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  if (!canConfigureExperienciometro(session.user.role)) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }

  await ensureExperienceBaseline(prisma, session.user.id);

  const body = (await request.json().catch(() => ({}))) as {
    name?: string;
    fromTemplateId?: string;
  };

  const name = body.name?.trim() || "Plantilla Experienciómetro";
  const fromTemplateId = body.fromTemplateId?.trim() || null;

  const latestVersion = await prisma.experienceTemplate.aggregate({
    _max: {
      version: true,
    },
  });

  let fromTemplate:
    | {
        categories: Array<{
          key: string;
          name: string;
          weight: number;
          sortOrder: number;
          items: Array<{
            key: string;
            label: string;
            weight: number;
            sortOrder: number;
            allowsComment: boolean;
            requiresObservation: boolean;
            allowsEvidence: boolean;
            isActive: boolean;
          }>;
        }>;
      }
    | null = null;

  if (fromTemplateId) {
    fromTemplate = await prisma.experienceTemplate.findUnique({
      where: { id: fromTemplateId },
      select: {
        categories: {
          include: {
            items: {
              orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
            },
          },
          orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
        },
      },
    });

    if (!fromTemplate) {
      return NextResponse.json({ error: "fromTemplateId not found." }, { status: 404 });
    }
  }

  const template = await prisma.experienceTemplate.create({
    data: {
      name,
      version: (latestVersion._max.version ?? 0) + 1,
      state: ExperienceTemplateState.draft,
      isDefault: false,
      createdById: session.user.id,
      categories: fromTemplate
        ? {
            create: fromTemplate.categories.map((category) => ({
              key: category.key,
              name: category.name,
              weight: category.weight,
              sortOrder: category.sortOrder,
              items: {
                create: category.items.map((item) => ({
                  key: item.key,
                  label: item.label,
                  weight: item.weight,
                  sortOrder: item.sortOrder,
                  allowsComment: item.allowsComment,
                  requiresObservation: item.requiresObservation,
                  allowsEvidence: item.allowsEvidence,
                  isActive: item.isActive,
                })),
              },
            })),
          }
        : undefined,
    },
    include: {
      categories: {
        include: {
          items: {
            orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
          },
        },
        orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
      },
    },
  });

  return NextResponse.json({
    ok: true,
    template: mapExperienceTemplate(template),
  });
}
