import type { RequestHandler } from './$types';
import { json, error } from '@sveltejs/kit';
import { getSurrealDB } from '$lib/server/db';
import { createRender, prepareRenderParameters } from '$lib/server/plainly';
import { generatePresignedUploadUrl, getCompanyAdPath } from '$lib/server/cloudflare';

export const POST: RequestHandler = async ({ request, locals, url }) => {
  if (!locals.user) {
    throw error(401, 'Non autorisé');
  }

  try {
    const { adId } = await request.json();

    if (!adId) {
      throw error(400, 'adId requis');
    }

    const db = await getSurrealDB();

    // Récupérer la publicité avec son template
    const adResult = await db.query<[any[]]>(
      `SELECT *, template.* as template_data FROM type::thing("ad", $adId)`,
      { adId }
    );

    const ad = adResult[0]?.[0];
    if (!ad) {
      throw error(404, 'Publicité non trouvée');
    }

    // Vérifier que l'utilisateur est propriétaire
    const userId = locals.user.id.replace('user:', '');
    const adUserId = typeof ad.user === 'string'
      ? ad.user.replace('user:', '')
      : ad.user?.id || ad.user;

    if (adUserId !== userId) {
      throw error(403, 'Accès refusé');
    }

    // Vérifier que le contenu est complet
    if (!ad.content?.is_complete) {
      throw error(400, 'Le contenu de la publicité n\'est pas complet');
    }

    // Récupérer le template pour avoir le plainly_template_id
    const templateResult = await db.query<[any[]]>(
      `SELECT * FROM type::thing("template", $templateId)`,
      { templateId: typeof ad.template === 'string' ? ad.template.replace('template:', '') : ad.template?.id }
    );

    const template = templateResult[0]?.[0];
    if (!template) {
      throw error(404, 'Template non trouvé');
    }

    if (!template.plainly_template_id) {
      throw error(400, 'Ce template n\'a pas de configuration Plainly');
    }

    // Récupérer le dossier R2 de l'entreprise
    let r2FolderName: string | null = null;
    try {
      const cleanUserId = typeof ad.user === 'string' 
        ? ad.user.replace('user:', '') 
        : ad.user?.id || ad.user;
      const [userResult] = await db.query<[any[]]>(
        `SELECT company.r2_folder_name FROM user WHERE id = type::thing("user", $userId)`,
        { userId: cleanUserId }
      );
      r2FolderName = userResult?.[0]?.company?.r2_folder_name || null;
      console.log(`[Render] Company folder: ${r2FolderName} for user ${cleanUserId}`);
    } catch (e) {
      console.warn('[Render] Could not fetch company folder:', e);
    }

    // Générer l'URL signée pour l'upload direct par Plainly
    const filename = `output-${Date.now()}.mp4`;
    const r2Key = r2FolderName 
      ? getCompanyAdPath(r2FolderName, adId, filename, ad.name)
      : `ads/${adId}/${filename}`;

    const { uploadUrl, publicUrl } = await generatePresignedUploadUrl(r2Key, 'video/mp4', 7200);
    console.log(`[Render] Generated presigned URL for ${r2Key}`);

    // Préparer les paramètres pour Plainly (inclure l'URL signée)
    const parameters = prepareRenderParameters(ad.content);
    parameters['uploadUrl'] = uploadUrl; // Paramètre pour l'intégration "Upload to signed URL"

    // URL du webhook pour recevoir le résultat (utilise l'origine de la requête)
    const webhookUrl = `${url.origin}/api/render/webhook`;

    // Lancer le rendu sur Plainly
    const render = await createRender(
      template.plainly_template_id,
      parameters,
      webhookUrl,
      adId // Passer l'adId pour le récupérer dans le webhook via passThroughData
    );

    // Mettre à jour la publicité avec l'ID du rendu et l'URL attendue
    await db.query(
      `UPDATE type::thing("ad", $adId) SET 
        render_id = $renderId,
        render_status = "rendering",
        pending_output_url = $publicUrl,
        pending_output_key = $r2Key,
        updated_at = time::now()`,
      { adId, renderId: render.id, publicUrl, r2Key }
    );

    return json({
      success: true,
      renderId: render.id,
      status: render.state,
    });

  } catch (err) {
    console.error('Error starting render:', err);
    if (err instanceof Error && 'status' in err) {
      throw err;
    }
    throw error(500, err instanceof Error ? err.message : 'Erreur lors du lancement du rendu');
  }
};
