import type { RequestHandler } from "./$types";
import { json, error } from "@sveltejs/kit";
import { getSurrealDB } from "$lib/server/db";
import { uploadToR2, getCompanyAdPath } from "$lib/server/cloudflare";
import { createMediaRecord, getMediaType } from "$lib/server/media";
import { generateThumbnail, getVideoMetadata } from "$lib/server/ffmpeg";
import { Buffer } from "buffer";

// Augmenter la limite de taille du body pour les uploads de médias (10MB)
export const config = {
  body: {
    limit: '10mb'
  }
};

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

  try {
    const formData = await request.formData();
    const adId = params.id;
    const isDraft = formData.get("isDraft") === "true";
    
    // Vérifier que l'annonce appartient à l'utilisateur
    const db = await getSurrealDB();
    const adResult = await db.query<[any[]]>(
      'SELECT * FROM type::thing("ad", $adId)',
      { adId }
    );

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

    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é");
    }
    // Récupérer la company de l'utilisateur avec son r2_folder_name
    const userResult = await db.query<[any[]]>(
      'SELECT company, company.r2_folder_name as r2_folder FROM user WHERE id = type::thing("user", $userId)',
      { userId }
    );
    const userCompany = userResult[0]?.[0]?.company;
    const r2FolderName = userResult[0]?.[0]?.r2_folder;
    const companyId = userCompany 
      ? (typeof userCompany === 'string' ? userCompany.replace('company:', '') : userCompany.id?.replace?.('company:', '') || userCompany.id)
      : null;
    
    // Calculer le chemin de base pour les fichiers
    const getFilePath = (filename: string) => {
      if (r2FolderName) {
        return getCompanyAdPath(r2FolderName, adId, filename, ad.name);
      }
      return `ads/${adId}/${filename}`;
    };
    
    // Passer le userId avec le préfixe user: à createMediaRecord
    const userIdWithPrefix = `user:${userId}`;
    // Récupérer le contenu existant pour le merger
    const existingContent = ad.content || {};
    const existingMediaMap = existingContent.media_map || {};

    // Récupérer la map des médias
    const mediaMappingString = formData.get("mediaMapping") as string | null;
    const mediaMapping = mediaMappingString ? JSON.parse(mediaMappingString) : {};

    // Structure pour stocker les URLs des médias uploadés avec leurs thumbnails
    const mediaMap: Record<string, any> = {};
    
    // D'abord, ajouter les médias existants depuis la médiathèque
    for (const [mediaId, info] of Object.entries(mediaMapping)) {
      if ((info as any).type === 'existing') {
        mediaMap[mediaId] = {
          url: (info as any).url,
          thumbnail_url: (info as any).thumbnail_url
        };
      }
    }

    // Traiter les médias
    for (const [key, value] of formData.entries()) {
      if (key.startsWith("media_") && typeof value === "object" && value !== null && "name" in value) {
        const mediaId = key.replace("media_", "");
        const file = value as File;
        
        // Ignorer les fichiers vides ou virtuels (type: 'existing')
        if (file.size === 0 || file.type === 'existing') {
          console.log(`Skipping empty or virtual file for media ${mediaId}`);
          continue;
        }
        
        const timestamp = Date.now();
        const extension = file.name.split(".").pop();
        const fileName = getFilePath(`media/${mediaId}-${timestamp}.${extension}`);
        
        const result = await uploadToR2(file, fileName, file.type);
        
        // Générer thumbnail pour les vidéos
        let thumbnailUrl: string | null = null;
        let videoMetadata: any = null;
        const mediaType = getMediaType(file.type);
        
        if (mediaType === 'video') {
          try {
            // Convertir File en Buffer
            const arrayBuffer = await file.arrayBuffer();
            const buffer = Buffer.from(arrayBuffer);
            
            // Générer le thumbnail
            const thumbnailBuffer = await generateThumbnail(buffer, 1);
            
            // Extraire les métadonnées
            videoMetadata = await getVideoMetadata(buffer);
            
            // Upload du thumbnail vers R2 dans le dossier de l'entreprise
            const thumbnailKey = getFilePath(`thumbnails/${mediaId}-${timestamp}_thumb.jpg`);
            const thumbnailResult = await uploadToR2(
              new File([new Uint8Array(thumbnailBuffer)], 'thumbnail.jpg', { type: 'image/jpeg' }),
              thumbnailKey,
              'image/jpeg'
            );
            thumbnailUrl = thumbnailResult.url;
            
            console.log('Thumbnail généré pour customize:', thumbnailUrl);
          } catch (thumbErr) {
            console.warn('Warning: Could not generate thumbnail for video:', thumbErr);
            // Ne pas bloquer si le thumbnail échoue
          }
        }
        
        // Sauvegarder dans la médiathèque avec thumbnail
        try {
          console.log('Customize endpoint - Creating media record with:', {
            userId: userIdWithPrefix,
            companyId,
            name: `${ad.name} - Média ${mediaId}`,
            originalName: file.name,
            type: mediaType,
            mimeType: file.type,
            url: result.url,
            cloudflareKey: result.key,
            thumbnailUrl,
            sizeBytes: file.size
          });
          await createMediaRecord({
            userId: userIdWithPrefix,
            companyId,
            name: `${ad.name} - Média ${mediaId}`,
            originalName: file.name,
            type: mediaType,
            mimeType: file.type,
            url: result.url,
            cloudflareKey: result.key,
            thumbnailUrl: thumbnailUrl || undefined,
            sizeBytes: file.size,
            ...(videoMetadata && {
              width: videoMetadata.width,
              height: videoMetadata.height,
              durationSeconds: videoMetadata.duration,
              metadata: videoMetadata
            })
          });
        } catch (mediaErr) {
          console.error("Error creating media record:", mediaErr);
          // Ne pas bloquer si l'ajout à la médiathèque échoue
        }
        
        // Stocker l'URL du média avec son thumbnail s'il existe
        mediaMap[mediaId] = {
          url: result.url,
          thumbnail_url: thumbnailUrl
        };
      }
    }

    // Traiter le logo (garder l'existant si pas de nouveau)
    let logoUrl: string | null = existingContent.logo_url || null;
    
    // Vérifier s'il y a un logo depuis la médiathèque
    const logoInfoString = formData.get("logoInfo") as string | null;
    if (logoInfoString) {
      const logoInfo = JSON.parse(logoInfoString);
      if (logoInfo.type === 'existing') {
        logoUrl = logoInfo.url;
      }
    } else {
      // Sinon, vérifier s'il y a un nouveau fichier logo
      const logoFile = formData.get("logo") as File | null;
      if (logoFile && logoFile.size > 0 && logoFile.type !== 'existing') {
        const timestamp = Date.now();
        const extension = logoFile.name.split(".").pop();
        const fileName = getFilePath(`logo-${timestamp}.${extension}`);
        
        const result = await uploadToR2(logoFile, fileName, logoFile.type);
        logoUrl = result.url;
        
        // Sauvegarder dans la médiathèque
        try {
          await createMediaRecord({
            userId: userIdWithPrefix,
            companyId,
            name: `${ad.name} - Logo`,
            originalName: logoFile.name,
            type: getMediaType(logoFile.type),
            mimeType: logoFile.type,
            url: result.url,
            cloudflareKey: result.key,
            sizeBytes: logoFile.size
          });
        } catch (mediaErr) {
          console.error("Error creating logo media record:", mediaErr);
        }
      }
    }

    // Récupérer et merger les textes
    const textsString = formData.get("texts") as string;
    const newTexts = textsString ? JSON.parse(textsString) : {};
    const existingTexts = existingContent.texts || {};
    const texts = { ...existingTexts, ...newTexts };

    // Mettre à jour l'annonce avec le contenu personnalisé
    // Préserver les champs existants (comme url, file_name pour les uploads directs)
    const content = {
      ...existingContent, // Préserver tous les champs existants
      media_map: mediaMap,
      logo_url: logoUrl,
      texts: texts,
      customized_at: new Date().toISOString(),
      is_complete: !isDraft // Marquer comme complet si ce n'est pas un brouillon
    };

    // Définir le statut selon si c'est un brouillon ou non
    const newStatus = isDraft ? "draft" : "ready";

    const updateResult = await db.query<[any[]]>(
      `UPDATE type::thing("ad", $adId) SET 
        content = $content,
        status = $status,
        updated_at = time::now()
      RETURN *`,
      { adId, content, status: newStatus }
    );

    const updatedAd = updateResult[0]?.[0];

    return json({
      success: true,
      ad: updatedAd
    });

  } catch (err) {
    console.error("Error customizing ad:", err);
    throw error(500, err instanceof Error ? err.message : "Erreur lors de la personnalisation");
  }
};
