export const dynamic = 'force-dynamic';
export const revalidate = 0;
export const runtime = 'nodejs';

import { NextRequest, NextResponse } from "next/server";
import { S3Client, ListObjectsV2Command } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { GetObjectCommand } from "@aws-sdk/client-s3";
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
import { cookies } from "next/headers";
import { getUserPermissions, canUploadDocuments, canAccessDocumentType } from "@/lib/permissions";

const s3Client = new S3Client({
  region: process.env.AWS_REGION || "eu-west-3",
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID || "",
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || "",
  },
});

const BUCKET_NAME = (process.env.AWS_S3_BUCKET || "odentas-docs").trim();

// Fonction pour slugifier les noms (enlever accents, espaces, etc.)
function slugify(text: string): string {
  return text
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '') // Enlever les accents
    .toLowerCase()
    .trim()
    .replace(/[^a-z0-9]+/g, '-') // Remplacer les caractères spéciaux par des tirets
    .replace(/^-+|-+$/g, ''); // Enlever les tirets en début/fin
}

// Types de documents généraux
const DOC_TYPES = {
  "contrat-odentas": "Contrat Odentas",
  "licence-spectacles": "Licence de spectacles",
  "rib": "RIB",
  "kbis-jo": "KBIS / Journal Officiel",
  "delegation-signature": "Délégation de signature"
};

interface GeneralDocument {
  type: string;
  label: string;
  available: boolean;
  key?: string;
  name?: string;
  size?: number;
  lastModified?: string;
  downloadUrl?: string;
}

export async function GET(req: NextRequest) {
  try {
    const { searchParams } = new URL(req.url);
    const requestedOrgId = searchParams.get('org_id');

    // 🔒 SÉCURITÉ : Authentification obligatoire
    const sb = createRouteHandlerClient({ cookies });
    const { data: { user }, error: userError } = await sb.auth.getUser();

    if (userError || !user) {
      console.error('❌ [SÉCURITÉ] Utilisateur non authentifié');
      return NextResponse.json({ 
        error: "Non authentifié",
        details: "Authentification requise"
      }, { status: 401 });
    }

    // 🔒 SÉCURITÉ : Vérifier si l'utilisateur est staff
    const { data: staffUser } = await sb
      .from("staff_users")
      .select("is_staff")
      .eq("user_id", user.id)
      .maybeSingle();

    const isStaff = !!staffUser?.is_staff;
    console.log('📄 Documents Généraux API - Is staff?', isStaff);

    let orgId: string;

    if (isStaff) {
      // 🔒 STAFF : Peut accéder à n'importe quelle organisation
      if (!requestedOrgId) {
        console.error('❌ [SÉCURITÉ] Staff sans organisation fournie');
        return NextResponse.json({ 
          error: "Organization ID requis pour le staff" 
        }, { status: 400 });
      }

      // Vérifier que l'organisation existe
      const { data: org, error: orgError } = await sb
        .from('organizations')
        .select('id')
        .eq('id', requestedOrgId)
        .maybeSingle();

      if (orgError || !org) {
        console.error('❌ [SÉCURITÉ] Staff a demandé une organisation inexistante:', requestedOrgId);
        return NextResponse.json({ 
          error: "Organisation non trouvée" 
        }, { status: 404 });
      }

      orgId = requestedOrgId;
      console.log('✅ [SÉCURITÉ] Staff accède à l\'organisation:', orgId);
    } else {
      // 🔒 CLIENT : Forcé à utiliser son organisation uniquement
      const { data: member, error: memberError } = await sb
        .from("organization_members")
        .select("org_id")
        .eq("user_id", user.id)
        .eq("revoked", false)
        .maybeSingle();

      if (!member?.org_id) {
        console.error('❌ [SÉCURITÉ] Client sans organisation trouvée');
        return NextResponse.json({ 
          error: "Aucune organisation trouvée pour cet utilisateur" 
        }, { status: 403 });
      }

      // 🔒 SÉCURITÉ CRITIQUE : Vérifier que l'org_id fourni correspond à celle de l'utilisateur
      if (requestedOrgId && requestedOrgId !== member.org_id) {
        console.error('❌ [SÉCURITÉ CRITIQUE] Client a tenté d\'accéder à une autre organisation !');
        console.error('   - org_id fourni:', requestedOrgId);
        console.error('   - org_id utilisateur:', member.org_id);
        console.error('   - User ID:', user.id);
        console.error('   - User email:', user.email);
        
        return NextResponse.json({ 
          error: "Accès non autorisé à cette organisation",
          details: "Vous ne pouvez accéder qu'aux documents de votre organisation"
        }, { status: 403 });
      }

      // Forcer l'utilisation de l'organisation de l'utilisateur
      orgId = member.org_id;
      console.log('✅ [SÉCURITÉ] Client forcé à son organisation:', orgId);
    }

    // Récupérer la clé de l'organisation (structure_api)
    const { data: org, error: orgError } = await sb
      .from('organizations')
      .select('structure_api')
      .eq('id', orgId)
      .single();

    if (orgError || !org?.structure_api) {
      return NextResponse.json({ 
        error: "Organisation non trouvée" 
      }, { status: 404 });
    }

    const orgKey = slugify(org.structure_api);
    const prefix = `documents/${orgKey}/docs-generaux/`;

    // Lister les fichiers dans S3
    const listCommand = new ListObjectsV2Command({
      Bucket: BUCKET_NAME,
      Prefix: prefix,
    });

    const listResponse = await s3Client.send(listCommand);

    // Initialiser tous les types de documents
    const documents: GeneralDocument[] = Object.entries(DOC_TYPES).map(([type, label]) => ({
      type,
      label,
      available: false
    }));

    // Si des fichiers existent, les associer aux types correspondants
    if (listResponse.Contents && listResponse.Contents.length > 0) {
      for (const item of listResponse.Contents) {
        if (!item.Key) continue;

        const fileName = item.Key.split('/').pop() || '';
        
        // Ignorer les fichiers système comme .DS_Store
        if (fileName.startsWith('.') || fileName === '.DS_Store') {
          continue;
        }
        
        // Déterminer le type de document basé sur le préfixe du nom de fichier
        for (const [type, label] of Object.entries(DOC_TYPES)) {
          if (fileName.toLowerCase().startsWith(type)) {
            // 🔒 SÉCURITÉ : Générer une URL pré-signée valide 15 minutes (au lieu de 1 heure)
            const getCommand = new GetObjectCommand({
              Bucket: BUCKET_NAME,
              Key: item.Key,
            });
            
            const signedUrl = await getSignedUrl(s3Client, getCommand, { 
              expiresIn: 900 // 15 minutes (900s)
            });

            // Trouver le document correspondant et le mettre à jour
            const docIndex = documents.findIndex(d => d.type === type);
            if (docIndex !== -1) {
              documents[docIndex] = {
                type,
                label,
                available: true,
                key: item.Key,
                name: fileName,
                size: item.Size || 0,
                lastModified: item.LastModified?.toISOString() || new Date().toISOString(),
                downloadUrl: signedUrl
              };
            }
            break;
          }
        }
      }
    }

    return NextResponse.json({
      documents,
      orgKey
    });

  } catch (error) {
    console.error("Erreur récupération documents généraux S3:", error);
    return NextResponse.json(
      { error: "Erreur lors de la récupération des documents" },
      { status: 500 }
    );
  }
}
