import type { RequestHandler } from './$types';
import { json, error } from '@sveltejs/kit';
import { getSurrealDB } from '$lib/server/db';
import { uploadToR2, generateAdFolderName } from '$lib/server/cloudflare';
import { generateThumbnail } from '$lib/server/ffmpeg';

export const POST: RequestHandler = async ({ request }) => {
  try {
    const rawBody = await request.text();
    console.log('[Plainly Webhook] Raw body:', rawBody);
    
    let payload;
    try {
      payload = JSON.parse(rawBody);
    } catch (parseErr) {
      console.error('[Plainly Webhook] JSON parse error:', parseErr);
      throw error(400, 'Invalid JSON body');
    }
    
    console.log('[Plainly Webhook] Parsed payload:', JSON.stringify(payload, null, 2));

    // Plainly v2 webhook format:
    // { renderingId, projectId, success, output, outputWatermark, passthrough, error, ... }
    const renderData = payload.render || payload;
    
    const renderId = renderData.renderingId || renderData.id || renderData.renderId;
    const state = renderData.success === true ? 'DONE' : (renderData.success === false ? 'FAILED' : (renderData.state || renderData.status));
    const outputUrl = renderData.output || renderData.outputUrl;
    const renderError = renderData.error;
    const passThroughData = renderData.passthrough || renderData.passThroughData || payload.passThroughData;

    console.log('[Plainly Webhook] Extracted - renderId:', renderId, 'state:', state, 'outputUrl:', outputUrl);

    if (!renderId) {
      console.error('[Plainly Webhook] No renderId found in payload');
      throw error(400, 'id (renderId) requis');
    }

    const db = await getSurrealDB();

    // Trouver la publicité associée à ce rendu
    // D'abord par render_id, sinon par passThroughData
    let ad;
    const adResult = await db.query<[any[]]>(
      `SELECT * FROM ad WHERE render_id = $renderId`,
      { renderId }
    );

    ad = adResult[0]?.[0];
    
    // Fallback: utiliser l'adId passé dans passThroughData
    if (!ad && passThroughData?.adId) {
      const fallbackResult = await db.query<[any[]]>(
        `SELECT * FROM type::thing("ad", $adId)`,
        { adId: passThroughData.adId }
      );
      ad = fallbackResult[0]?.[0];
      if (ad) {
        console.log(`[Plainly Webhook] Found ad via passThroughData: ${passThroughData.adId}`);
      }
    }

    if (!ad) {
      console.warn(`Ad not found for render ${renderId}`);
      return json({ success: true, message: 'Ad not found, ignoring' });
    }

    const adId = typeof ad.id === 'string' 
      ? ad.id.replace('ad:', '') 
      : ad.id?.id || ad.id;

    if (state === 'DONE') {
      // Toujours télécharger depuis Plainly et uploader sur R2
      // (L'upload direct via presigned URL nécessite une config Plainly spécifique)
      let finalOutputUrl: string | null = null;
      let thumbnailUrl: string | null = null;
      let videoBuffer: Buffer | null = null;
      let r2BasePath = `ads/${adId}`;
      
      // Récupérer les infos de l'entreprise via l'utilisateur de la pub
      try {
        const userId = typeof ad.user === 'string' 
          ? ad.user.replace('user:', '') 
          : ad.user?.id || ad.user;
        
        if (userId) {
          const [userResult] = await db.query<[any[]]>(
            `SELECT company.r2_folder_name FROM user WHERE id = type::thing("user", $userId)`,
            { userId }
          );
          
          const r2FolderName = userResult?.[0]?.company?.r2_folder_name;
          
          if (r2FolderName) {
            const adFolderName = generateAdFolderName(ad.name || 'ad', adId);
            r2BasePath = `clients/annonceurs/${r2FolderName}/ads/${adFolderName}`;
          }
        }
      } catch (companyErr) {
        console.warn(`[Plainly Webhook] Could not fetch company info:`, companyErr);
      }
      
      if (outputUrl) {
        // Télécharger depuis Plainly et uploader sur R2
        console.log(`[Plainly Webhook] Downloading from Plainly: ${outputUrl}`);
        
        const videoResponse = await fetch(outputUrl);
        if (!videoResponse.ok) {
          throw new Error(`Failed to download video: ${videoResponse.status}`);
        }

        const videoArrayBuffer = await videoResponse.arrayBuffer();
        videoBuffer = Buffer.from(videoArrayBuffer);

        const r2Path = `${r2BasePath}/output-${Date.now()}.mp4`;
        const uploadResult = await uploadToR2(videoBuffer, r2Path, 'video/mp4');
        finalOutputUrl = uploadResult.url;
        console.log(`[Plainly Webhook] Uploaded to R2: ${finalOutputUrl}`);
      } else {
        console.warn(`[Plainly Webhook] No output URL provided by Plainly`);
      }

      // Générer et uploader la thumbnail automatique
      if (videoBuffer) {
        try {
          console.log(`[Plainly Webhook] Generating thumbnail...`);
          const thumbnailBuffer = await generateThumbnail(videoBuffer, 1);
          const thumbnailPath = `${r2BasePath}/thumbnail-${Date.now()}.jpg`;
          const thumbnailResult = await uploadToR2(thumbnailBuffer, thumbnailPath, 'image/jpeg');
          thumbnailUrl = thumbnailResult.url;
          console.log(`[Plainly Webhook] Thumbnail uploaded: ${thumbnailUrl}`);
        } catch (thumbErr) {
          console.warn(`[Plainly Webhook] Could not generate thumbnail:`, thumbErr);
        }
      }

      // Mettre à jour la publicité
      await db.query(
        `UPDATE type::thing("ad", $adId) SET 
          render_status = "done",
          output_url = $outputUrl,
          content.preview_url = $outputUrl,
          thumbnail_url = $thumbnailUrl,
          status = "ready",
          pending_output_url = NONE,
          pending_output_key = NONE,
          updated_at = time::now()`,
        { adId, outputUrl: finalOutputUrl, thumbnailUrl }
      );

      console.log(`[Plainly Webhook] Ad ${adId} updated with rendered video: ${finalOutputUrl}, thumbnail: ${thumbnailUrl}`);

    } else if (state === 'FAILED' || state === 'INVALID') {
      // Marquer comme échoué
      const errorMessage = renderError?.message || renderError?.code || 'Unknown error';
      await db.query(
        `UPDATE type::thing("ad", $adId) SET 
          render_status = "failed",
          render_error = $error,
          updated_at = time::now()`,
        { adId, error: errorMessage }
      );

      console.error(`[Plainly Webhook] Render ${renderId} failed:`, errorMessage);

    } else if (state === 'CANCELLED') {
      await db.query(
        `UPDATE type::thing("ad", $adId) SET 
          render_status = "cancelled",
          updated_at = time::now()`,
        { adId }
      );
      console.log(`[Plainly Webhook] Render ${renderId} cancelled`);

    } else {
      // Mise à jour du statut intermédiaire (PENDING, QUEUED, IN_PROGRESS)
      const statusMap: Record<string, string> = {
        'PENDING': 'pending',
        'QUEUED': 'queued',
        'IN_PROGRESS': 'rendering',
        'THROTTLED': 'queued'
      };
      const mappedStatus = statusMap[state] || state.toLowerCase();
      
      await db.query(
        `UPDATE type::thing("ad", $adId) SET 
          render_status = $status,
          updated_at = time::now()`,
        { adId, status: mappedStatus }
      );
      console.log(`[Plainly Webhook] Ad ${adId} status updated to ${mappedStatus}`);
    }

    return json({ success: true });

  } catch (err) {
    console.error('Webhook error:', err);
    // Retourner 200 même en cas d'erreur pour éviter les retry de Plainly
    return json({ 
      success: false, 
      error: err instanceof Error ? err.message : 'Unknown error' 
    });
  }
};
