// app/api/virements-salaires/route.ts
import { NextRequest, NextResponse } from "next/server";
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
import { cookies } from "next/headers";
import { detectDemoModeFromHeaders } from "@/lib/demo-detector";
import { getUserPermissions, canAccessVirements, checkPermissionOrRespond } from "@/lib/permissions";

export async function GET(req: NextRequest) {
  // 🎭 En mode démo, retourner des données vides (les données fictives sont gérées côté client)
  if (detectDemoModeFromHeaders(req.headers)) {
    console.log('🎭 [VIREMENTS API] Mode démo détecté - retour géré côté client');
    return NextResponse.json({
      items: [],
      enabled: true,
      org: {
        structure_api: 'demo-org',
        virements_salaires: 'odentas',
        iban: null,
        bic: null,
      },
      client: undefined,
    }, { status: 200 });
  }

  try {
    const sb = createRouteHandlerClient({ cookies });
    
    // 🔒 VÉRIFICATION DES PERMISSIONS
    const permissions = await getUserPermissions(sb);
    const permissionCheck = canAccessVirements(permissions);
    const errorResponse = checkPermissionOrRespond(permissionCheck);
    if (errorResponse) return errorResponse;
    
    const { searchParams } = new URL(req.url);
    const year = searchParams.get("year");
    const period = searchParams.get("period");
    const from = searchParams.get("from");
    const to = searchParams.get("to");
    const orgIdParam = searchParams.get("org_id"); // Pour le staff uniquement

    console.log("[virements-salaires][incoming] url=", req.url);
    console.log("[virements-salaires][incoming] searchParams=", {
      year,
      period,
      from,
      to,
      orgIdParam,
    });

    // ✅ AJOUT : Récupération de l'identification du client côté serveur
    const { data: { user }, error: userError } = await sb.auth.getUser();
    
    if (!user) {
      console.error("[virements-salaires][auth] No authenticated user");
      return new NextResponse("Unauthorized", { status: 401 });
    }

    // Vérification staff
    let isStaff = false;
    try {
      const { data: staffData } = await sb
        .from("staff_users")
        .select("is_staff")
        .eq("user_id", user.id)
        .maybeSingle();
      isStaff = !!staffData?.is_staff;
    } catch {}

    // Récupération organisation active
    let activeOrgId: string | null = null;
    let orgName: string | null = null;
    let orgApiName: string | null = null;

    if (isStaff) {
      // Staff: utilise le paramètre org_id si fourni, sinon les cookies
      if (orgIdParam) {
        activeOrgId = orgIdParam;
        try {
          const { data } = await sb
            .from("organizations")
            .select("name, structure_api")
            .eq("id", activeOrgId)
            .maybeSingle();
          orgName = data?.name ?? null;
          orgApiName = data?.structure_api ?? null;
        } catch {}
      } else {
        const cookiesStore = cookies();
        activeOrgId = cookiesStore.get("active_org_id")?.value || null;
        if (activeOrgId) {
          try {
            const { data } = await sb
              .from("organizations")
              .select("name, structure_api")
              .eq("id", activeOrgId)
              .maybeSingle();
            orgName = data?.name ?? null;
            orgApiName = data?.structure_api ?? null;
          } catch {}
        }
      }
    } else {
      // Client: récupérer l'organisation via requête directe
      try {
        const { data: memberData } = await sb
          .from("organization_members")
          .select(`
            organization:organizations(id, name, structure_api)
          `)
          .eq("user_id", user.id)
          .eq("revoked", false)
          .maybeSingle();
          
        if (memberData?.organization) {
          const org = memberData.organization as any;
          activeOrgId = org.id ?? null;
          orgName = org.name ?? null;
          orgApiName = org.structure_api ?? null;
        }
      } catch {}
    }

    // If no active org found: allow staff users to continue (global access).
    // For non-staff users, deny as before.
    if (!activeOrgId || !orgName) {
      if (!isStaff) {
        console.error("[virements-salaires][auth] No active organization found (non-staff)");
        return new NextResponse("No active organization", { status: 403 });
      }
      console.log("[virements-salaires][auth] No active org found but user is staff — continuing with null-org semantics");
    }

    console.log("[virements-salaires][auth] User authenticated:", {
      userId: user.id,
      orgId: activeOrgId,
      orgName: orgName,
      isStaff: isStaff
    });

    // Récupération des informations de l'organisation pour déterminer le mode de gestion
    let orgSummary: any = null;
    let isOdentasMode = false;
    
    if (activeOrgId) {
      try {
        // Récupération des données de base de l'organisation
        const { data: orgData } = await sb
          .from("organizations")
          .select("structure_api, iban, bic")
          .eq("id", activeOrgId)
          .maybeSingle();
        
        // Récupération des détails incluant virements_salaires
        const { data: orgDetailsData, error: orgDetailsError } = await sb
          .from("organization_details")
          .select("virements_salaires")
          .eq("org_id", activeOrgId)
          .maybeSingle();
        
        console.log("[virements-salaires][debug] orgDetailsData query result:", {
          data: orgDetailsData,
          error: orgDetailsError,
          activeOrgId
        });
        
        orgSummary = {
          ...orgData,
          virements_salaires: orgDetailsData?.virements_salaires || null
        };
        
        isOdentasMode = orgDetailsData?.virements_salaires === 'Odentas';
        
        console.log("[virements-salaires][mode] Organization details:", {
          orgId: activeOrgId,
          virements_salaires: orgDetailsData?.virements_salaires,
          isOdentasMode
        });
      } catch (e) {
        console.error("[virements-salaires][org] Error fetching org data:", e);
      }
    }

  // Utilisation exclusive de Supabase - interrogation de salary_transfers
  console.log("[virements-salaires][supabase] Using Supabase for all organizations");
    
    if (activeOrgId) {
      try {
        let query = sb
          .from("salary_transfers")
          .select("*")
          .eq("org_id", activeOrgId)
          .order("period_month", { ascending: false });

        // Filtrage par année si spécifié
        if (year) {
          const yearNum = Number(year);
          const startOfYear = `${yearNum}-01-01`;
          const endOfYear = `${yearNum}-12-31`;
          query = query.gte("period_month", startOfYear).lte("period_month", endOfYear);
        }

        const { data: salaryTransfers, error } = await query;
        
        if (error) {
          console.error("[virements-salaires][supabase] Error:", error);
          return new NextResponse("Database error", { status: 500 });
        }

        // Transformation des données pour correspondre au format attendu par le frontend
        const transformedItems = (salaryTransfers || []).map((transfer: any) => {
          // Logique pour le statut "virement reçu"
          // Pour juillet 2025 et avant : automatiquement marqué comme reçu
          // À partir d'août 2025 : basé sur client_wire_received_at
          const periodDate = new Date(transfer.period_month);
          const cutoffDate = new Date('2025-08-01'); // 1er août 2025
          
          let virementRecu: boolean;
          let virementRecuDate: string | null = null;
          
          if (periodDate < cutoffDate) {
            // Juillet 2025 et avant : automatiquement reçu
            virementRecu = true;
          } else {
            // Août 2025 et après : basé sur client_wire_received_at
            virementRecu = transfer.client_wire_received_at ? true : false;
            virementRecuDate = transfer.client_wire_received_at;
          }

          return {
            id: transfer.id,
            periode_label: transfer.period_label,
            periode: transfer.period_month,
            callsheet: transfer.callsheet_url,
            num_appel: transfer.num_appel,
            date_mois: transfer.period_month,
            date: transfer.deadline,
            total_salaries_eur: parseFloat(transfer.total_net || '0'),
            total: parseFloat(transfer.total_net || '0'),
            virement_recu: virementRecu,
            virement_recu_date: virementRecuDate, // Date de réception pour affichage
            salaires_payes: transfer.notification_ok === true,
            pdf_url: transfer.callsheet_url || null  // Retourne directement l'URL S3 signée
          };
        });

        console.log("[virements-salaires][supabase] Retrieved", transformedItems.length, "salary transfers");
        
        // Si le mode n'est pas Odentas, récupérer les payslips non virés (transfer_done = false)
        let clientData = undefined;
        if (!isOdentasMode && activeOrgId) {
          try {
            console.log("[virements-salaires][payslips] Mode 'Votre structure' - récupération des payslips transfer_done = false");

            // Base query payslips de l'organisation
            let payslipsQuery = sb
              .from("payslips")
              .select("id, contract_id, organization_id, transfer_done, transfer_done_at, net_after_withholding, period_start, period_end, pay_date, updated_at, processed")
              .eq("organization_id", activeOrgId);

            // Filtrage par année (période de paie)
            if (year) {
              const yearNum = Number(year);
              const startOfYear = `${yearNum}-01-01`;
              const endOfYear = `${yearNum}-12-31`;
              payslipsQuery = payslipsQuery.gte("period_start", startOfYear).lte("period_start", endOfYear);
            }

            const { data: allPayslips, error: payslipsError } = await payslipsQuery.order("period_start", { ascending: false });
            if (payslipsError) {
              console.error("[virements-salaires][payslips] Error:", payslipsError);
            } else {
              // Masquer les payslips dont processed est FALSE
              const unpaidPayslips = (allPayslips || []).filter(p => !p.transfer_done && p.processed !== false);
              
              // Filtrer les paies récentes (virées dans les 30 derniers jours)
              // On utilise transfer_done_at (date exacte du marquage) au lieu de updated_at
              const thirtyDaysAgo = new Date();
              thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
              const recentPayslips = (allPayslips || []).filter(p => {
                if (p.transfer_done && p.processed !== false && p.transfer_done_at) {
                  const ts = new Date(p.transfer_done_at);
                  return ts >= thirtyDaysAgo;
                }
                return false;
              });

              // Récupérer les contrats liés pour enrichir l'affichage
              const contractIds = Array.from(new Set((unpaidPayslips.concat(recentPayslips)).map(p => p.contract_id).filter(Boolean)));
              let contractsById: Record<string, any> = {};
              if (contractIds.length > 0) {
                const { data: contracts, error: contractsErr } = await sb
                  .from("cddu_contracts")
                  .select("id, contract_number, employee_name, employee_matricule, contract_kind, profession, start_date, end_date")
                  .in("id", contractIds as any);
                if (contractsErr) {
                  console.error("[virements-salaires][contracts] Error fetching contracts:", contractsErr);
                } else {
                  for (const c of contracts || []) contractsById[c.id] = c;
                }
              }

              const mapPayslip = (p: any) => {
                const c = contractsById[p.contract_id] || {};
                return {
                  id: p.id,
                  kind: (c.contract_kind || 'CDDU_MONO') as 'CDDU_MONO' | 'CDDU_MULTI' | 'RG',
                  source: 'payslip' as const,
                  contract_id: p.contract_id,
                  salarie: c.employee_name || null,
                  salarie_matricule: c.employee_matricule || null,
                  reference: c.contract_number || null,
                  profession: c.profession || null,
                  date_debut: c.start_date || null,
                  date_fin: c.end_date || null,
                  periode: p.period_start || null,
                  net_a_payer: p.net_after_withholding != null ? parseFloat(p.net_after_withholding as any) : null,
                  virement_effectue: (p.transfer_done ? 'oui' : 'non') as 'oui' | 'non' | 'na'
                };
              };

              const unpaid = unpaidPayslips.map(mapPayslip);
              const recent = recentPayslips.map(mapPayslip);

              console.log("[virements-salaires][payslips] unpaid:", unpaid.length, "recent:", recent.length);
              clientData = { unpaid, recent };
            }
          } catch (e) {
            console.error("[virements-salaires][payslips] Exception:", e);
          }
        }
        
        const responseData = {
          items: transformedItems,
          enabled: isOdentasMode, // true seulement si virements_salaires = "Odentas"
          org: orgSummary,
          client: clientData
        };

        return NextResponse.json(responseData);
        
      } catch (e: any) {
        console.error("[virements-salaires][supabase] Exception:", e?.message);
        return new NextResponse("Database error", { status: 500 });
      }
    } else {
      // Pas d'organisation active
      return NextResponse.json({ 
        items: [], 
        enabled: false, 
        org: orgSummary,
        client: undefined
      });
    }
  } catch (e: any) {
    console.error("[virements-salaires][auth] Error:", e?.message);
    return new NextResponse("Authentication error", { status: 500 });
  }
}