import { NextRequest, NextResponse } from "next/server"; import { db } from "@/lib/db"; import ZAI from "z-ai-web-dev-sdk"; // GET - Listar publicaciones export async function GET(request: NextRequest) { try { const { searchParams } = new URL(request.url); const status = searchParams.get("status"); const platform = searchParams.get("platform"); const type = searchParams.get("type"); const limit = parseInt(searchParams.get("limit") || "50"); const where: Record = {}; if (status) where.status = status; if (type) where.type = type; if (platform) where.platformId = platform; const posts = await db.post.findMany({ where, include: { content: true, platform: true, story: true, }, orderBy: { scheduledAt: "asc" }, take: limit, }); // Estadísticas const stats = { total: await db.post.count(), draft: await db.post.count({ where: { status: "draft" } }), scheduled: await db.post.count({ where: { status: "scheduled" } }), published: await db.post.count({ where: { status: "published" } }), failed: await db.post.count({ where: { status: "failed" } }), }; // Próximas publicaciones const upcoming = await db.post.findMany({ where: { status: "scheduled", scheduledAt: { gte: new Date() } }, orderBy: { scheduledAt: "asc" }, take: 5, }); return NextResponse.json({ success: true, posts, stats, upcoming }); } catch (error) { console.error("Error fetching posts:", error); return NextResponse.json( { success: false, error: "Error al obtener publicaciones" }, { status: 500 } ); } } // POST - Crear nueva publicación export async function POST(request: NextRequest) { try { const body = await request.json(); const { title, caption, type, // reel, photo, carousel, story, post contentId, platformId, scheduledAt, hashtags, storyId, autoGenerateCaption, optimizeForPlatform, } = body; if (!type) { return NextResponse.json( { success: false, error: "El tipo de publicación es requerido" }, { status: 400 } ); } let finalCaption = caption; let finalHashtags = hashtags; // Generar caption con IA si se solicita if (autoGenerateCaption && contentId) { const content = await db.content.findUnique({ where: { id: contentId } }); if (content) { const zai = await ZAI.create(); const platform = await db.monetizationPlatform.findUnique({ where: { id: platformId } }); const platformName = platform?.name || "general"; const platformRules = PLATFORM_RULES[platformName.toLowerCase()] || {}; const completion = await zai.chat.completions.create({ messages: [ { role: "system", content: `Eres un experto en marketing de contenidos para ${platformName}. Genera captions atractivos que: ${platformRules.maxCaptionLength ? `- No excedan ${platformRules.maxCaptionLength} caracteres` : ''} - Incluyan emojis relevantes - Tengan un CTA (call to action) efectivo - Sean ${platformRules.tone || 'profesionales pero cercanos'} - Maximizen el engagement ${platformRules.hashtagLimit ? `- Incluyan máximo ${platformRules.hashtagLimit} hashtags relevantes` : ''}` }, { role: "user", content: `Genera un caption para este contenido: Tipo: ${type} Título: ${title || content.title} Descripción: ${content.description || content.prompt} Plataforma: ${platformName}` } ], temperature: 0.8, }); finalCaption = completion.choices[0]?.message?.content || caption; } } // Optimizar hashtags si se solicita if (optimizeForPlatform && !hashtags) { const zai = await ZAI.create(); const platform = await db.monetizationPlatform.findUnique({ where: { id: platformId } }); const completion = await zai.chat.completions.create({ messages: [ { role: "system", content: `Eres un experto en SEO de redes sociales. Genera hashtags optimizados. Responde SOLO con un JSON array de hashtags sin el símbolo #. Ejemplo: ["tendencias", "viral", "lifestyle"]` }, { role: "user", content: `Genera hashtags para un ${type} en ${platform?.name || "redes sociales"}. Tema: ${title || "contenido general"} Máximo 10 hashtags.` } ], temperature: 0.7, }); try { const response = completion.choices[0]?.message?.content || "[]"; const match = response.match(/\[[\s\S]*\]/); if (match) { finalHashtags = match[0]; } } catch { finalHashtags = "[]"; } } // Crear publicación const post = await db.post.create({ data: { title: title || null, caption: finalCaption, hashtags: finalHashtags, type, status: scheduledAt ? "scheduled" : "draft", contentId: contentId || null, platformId: platformId || null, scheduledAt: scheduledAt ? new Date(scheduledAt) : null, storyId: storyId || null, }, include: { content: true, platform: true, } }); // Crear tarea de agente await db.agentTask.create({ data: { type: "create_post", status: "completed", input: `Crear ${type}: ${title || "sin título"}`, output: `Post creado con ID: ${post.id}`, completedAt: new Date(), } }); return NextResponse.json({ success: true, post, message: scheduledAt ? `Publicación programada para ${new Date(scheduledAt).toLocaleString()}` : "Publicación creada como borrador" }); } catch (error) { console.error("Error creating post:", error); return NextResponse.json( { success: false, error: "Error al crear publicación" }, { status: 500 } ); } } // PUT - Actualizar publicación export async function PUT(request: NextRequest) { try { const body = await request.json(); const { id, status, scheduledAt, caption, hashtags, publishedAt, engagementStats } = body; if (!id) { return NextResponse.json( { success: false, error: "ID requerido" }, { status: 400 } ); } const updateData: Record = {}; if (status) updateData.status = status; if (scheduledAt) updateData.scheduledAt = new Date(scheduledAt); if (caption) updateData.caption = caption; if (hashtags) updateData.hashtags = hashtags; if (publishedAt) updateData.publishedAt = new Date(publishedAt); if (engagementStats) updateData.engagementStats = engagementStats; const post = await db.post.update({ where: { id }, data: updateData, }); return NextResponse.json({ success: true, post }); } catch (error) { console.error("Error updating post:", error); return NextResponse.json( { success: false, error: "Error al actualizar publicación" }, { status: 500 } ); } } // DELETE - Eliminar publicación export async function DELETE(request: NextRequest) { try { const { searchParams } = new URL(request.url); const id = searchParams.get("id"); if (!id) { return NextResponse.json( { success: false, error: "ID requerido" }, { status: 400 } ); } await db.post.delete({ where: { id } }); return NextResponse.json({ success: true, message: "Publicación eliminada" }); } catch (error) { console.error("Error deleting post:", error); return NextResponse.json( { success: false, error: "Error al eliminar publicación" }, { status: 500 } ); } } // Reglas específicas por plataforma const PLATFORM_RULES: Record = { instagram: { maxCaptionLength: 2200, hashtagLimit: 30, tone: "inspirador y visual", bestPostingTimes: ["11:00", "14:00", "19:00", "21:00"] }, tiktok: { maxCaptionLength: 300, hashtagLimit: 5, tone: "casual y divertido", bestPostingTimes: ["09:00", "12:00", "19:00"] }, youtube: { maxCaptionLength: 5000, tone: "profesional e informativo", bestPostingTimes: ["15:00", "16:00", "17:00"] }, onlyfans: { maxCaptionLength: 1000, tone: "personal y exclusivo", bestPostingTimes: ["10:00", "18:00", "22:00"] }, patreon: { maxCaptionLength: 5000, tone: "profesional y cercano", bestPostingTimes: ["10:00", "14:00", "18:00"] }, twitter: { maxCaptionLength: 280, hashtagLimit: 3, tone: "conciso y directo", bestPostingTimes: ["09:00", "12:00", "17:00", "20:00"] } };