import { NextRequest, NextResponse } from 'next/server';
import fs from 'fs/promises';
import path from 'path';
import matter from 'gray-matter';
import { getIdeaMotriz, getPersonajes } from '@/lib/file-service';

const PROJECTS_DIR = path.join(process.cwd(), 'projects');

async function findCapDir(capitulosDir: string, numero: string) {
  const dirs = await fs.readdir(capitulosDir, { withFileTypes: true });
  return dirs.find(d =>
    d.isDirectory() && d.name.startsWith(numero.padStart(2, '0'))
  );
}

export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ slug: string; numero: string }> }
) {
  try {
    const { slug, numero } = await params;
    const capitulosDir = path.join(PROJECTS_DIR, slug, 'capitulos');
    const capDir = await findCapDir(capitulosDir, numero);
    
    if (!capDir) {
      return NextResponse.json(null);
    }
    
    const guionPath = path.join(capitulosDir, capDir.name, 'guion-conductor.md');
    
    try {
      const fileContent = await fs.readFile(guionPath, 'utf-8');
      const { data, content } = matter(fileContent);

      // Load structured actos from JSON (saved alongside markdown)
      let actos;
      try {
        const actosPath = path.join(capitulosDir, capDir.name, 'guion-actos.json');
        const actosJson = await fs.readFile(actosPath, 'utf-8');
        actos = JSON.parse(actosJson);
      } catch { /* no actos file yet — old guion */ }

      return NextResponse.json({ ...data, actos, contenidoMarkdown: content });
    } catch {
      return NextResponse.json(null);
    }
  } catch (error: any) {
    console.error('Error fetching guion:', error);
    return NextResponse.json({ error: error.message }, { status: 500 });
  }
}

export async function POST(
  request: NextRequest,
  { params }: { params: Promise<{ slug: string; numero: string }> }
) {
  try {
    const { slug, numero } = await params;
    const body = await request.json();
    const { action } = body;

    const capitulosDir = path.join(PROJECTS_DIR, slug, 'capitulos');
    const capDir = await findCapDir(capitulosDir, numero);

    if (!capDir) {
      return NextResponse.json({ error: 'Capítulo no encontrado' }, { status: 404 });
    }

    const guionPath = path.join(capitulosDir, capDir.name, 'guion-conductor.md');

    if (action === 'generate') {
      const ideaMotriz = await getIdeaMotriz(slug);
      if (!ideaMotriz) {
        return NextResponse.json({ error: 'Primero debes crear la Idea Motriz' }, { status: 400 });
      }
      const personajes = await getPersonajes(slug);
      if (personajes.length === 0) {
        return NextResponse.json({ error: 'Primero debes crear los personajes' }, { status: 400 });
      }

      const { generateGuionConductor } = await import('@/lib/llm-service');
      const guion = await generateGuionConductor(ideaMotriz, personajes, parseInt(numero));

      // Separate actos (too complex for frontmatter) and save as JSON
      const { contenidoMarkdown: _ignore, actos, ...frontmatterData } = guion as any;
      const mdContent = generateGuionMarkdown(guion);
      const fileContent = matter.stringify(mdContent, frontmatterData);
      await fs.writeFile(guionPath, fileContent);

      // Save actos as structured JSON for downstream escaleta generation
      if (actos) {
        const actosPath = path.join(capitulosDir, capDir.name, 'guion-actos.json');
        await fs.writeFile(actosPath, JSON.stringify(actos, null, 2));
      }

      // Return with actos included so frontend can pass them to escaleta generation
      return NextResponse.json({ ...frontmatterData, actos, contenidoMarkdown: mdContent });
    }

    if (action === 'regenerate-actos') {
      // Read current guión metadata from disk
      let currentGuion: Record<string, any> = {};
      try {
        const existing = await fs.readFile(guionPath, 'utf-8');
        const { data } = matter(existing);
        currentGuion = data;
      } catch {
        return NextResponse.json({ error: 'No hay guión existente para regenerar actos' }, { status: 400 });
      }

      const ideaMotriz = await getIdeaMotriz(slug);
      if (!ideaMotriz) {
        return NextResponse.json({ error: 'Primero debes crear la Idea Motriz' }, { status: 400 });
      }
      const personajes = await getPersonajes(slug);
      if (personajes.length === 0) {
        return NextResponse.json({ error: 'Primero debes crear los personajes' }, { status: 400 });
      }

      const { regenerateGuionActos } = await import('@/lib/llm-service');
      const guionMetadata = {
        titulo: currentGuion.titulo || '',
        duracionTotal: currentGuion.duracionTotal || '20:00',
        virtudGanada: currentGuion.virtudGanada || '',
        nudoDelMundo: currentGuion.nudoDelMundo || '',
        aliado: currentGuion.aliado || { nombre: '', descripcion: '' },
        gemaGanada: currentGuion.gemaGanada || '',
      };

      const result = await regenerateGuionActos(guionMetadata, ideaMotriz, personajes, parseInt(numero));
      const actos = result.actos;

      // Merge: keep existing metadata, replace actos
      const fullGuion = { ...guionMetadata, actos };
      const { actos: _a, contenidoMarkdown: _c, ...frontmatterData } = fullGuion as any;
      const mdContent = generateGuionMarkdown(fullGuion);
      const fileContent = matter.stringify(mdContent, frontmatterData);
      await fs.writeFile(guionPath, fileContent);

      // Save actos as structured JSON
      if (actos) {
        const actosPath = path.join(capitulosDir, capDir.name, 'guion-actos.json');
        await fs.writeFile(actosPath, JSON.stringify(actos, null, 2));
      }

      return NextResponse.json({ ...frontmatterData, actos, contenidoMarkdown: mdContent });
    }

    if (action === 'save' && body.contenidoMarkdown !== undefined) {
      // Leer frontmatter actual y guardar con nuevo contenido
      let frontmatterData: Record<string, any> = {};
      try {
        const existing = await fs.readFile(guionPath, 'utf-8');
        const { data } = matter(existing);
        frontmatterData = data;
      } catch { /* no existing file */ }

      const fileContent = matter.stringify(body.contenidoMarkdown, frontmatterData);
      await fs.writeFile(guionPath, fileContent);
      return NextResponse.json({ success: true });
    }

    if (action === 'save-fields') {
      const guionData = body.guionData;
      if (!guionData) {
        return NextResponse.json({ error: 'Se necesita guionData' }, { status: 400 });
      }

      // Extract actos from the guion data (stored separately as JSON)
      const { actos, contenidoMarkdown: _ignore2, ...frontmatterFields } = guionData;

      // Regenerate markdown from updated fields
      const mdContent = generateGuionMarkdown(guionData);
      const fileContent = matter.stringify(mdContent, frontmatterFields);
      await fs.writeFile(guionPath, fileContent);

      // Save actos as structured JSON
      const actosPath = path.join(capitulosDir, capDir.name, 'guion-actos.json');
      if (actos) {
        await fs.writeFile(actosPath, JSON.stringify(actos, null, 2));
      }

      return NextResponse.json({ ...frontmatterFields, actos, contenidoMarkdown: mdContent });
    }

    return NextResponse.json({ error: 'Acción inválida' }, { status: 400 });
  } catch (error: any) {
    console.error('Error en guion:', error);
    return NextResponse.json({ error: error.message }, { status: 500 });
  }
}

function generateGuionMarkdown(guion: any): string {
  let md = `# ${guion.titulo}\n\n`;
  md += `**VIRTUD GANADA: ${guion.virtudGanada?.toUpperCase()}**\n\n`;
  md += `## Introducción\n\n`;
  md += `| Categoría | Detalle |\n|-----------|--------|\n`;
  md += `| **Duración Total** | ${guion.duracionTotal} |\n`;
  md += `| **Nudo del Mundo** | ${guion.nudoDelMundo} |\n`;
  md += `| **Aliado** | ${guion.aliado?.nombre} — ${guion.aliado?.descripcion} |\n`;
  md += `| **Gema Ganada** | ${guion.gemaGanada} |\n\n---\n\n`;

  if (guion.actos) {
    for (const acto of guion.actos) {
      md += `## ACTO ${acto.numero}: ${acto.nombre?.toUpperCase()} (${acto.tiempoInicio} - ${acto.tiempoFin})\n\n`;
      if (acto.segmentos) {
        for (const seg of acto.segmentos) {
          md += `### ${seg.id} ${seg.nombre} (${seg.tiempo})\n`;
          md += `| Tiempo | Acción Visual Clave | Diseño de Fondo | Diseño de Sonido |\n`;
          md += `|--------|---------------------|-----------------|------------------|\n`;
          md += `| ${seg.tiempo} | ${seg.accionVisualClave} | ${seg.disenoFondo || ''} | ${seg.disenoSonido} |\n\n`;
        }
      }
      md += `---\n\n`;
    }
  }

  return md;
}
