import PDFDocument from "pdfkit";
import * as XLSX from "xlsx";

type AnalyticsPayload = {
  period: string;
  periodLabel: string;
  comparisonLabel: string;
  startDate: string;
  endDate: string;
  summary: {
    totalReservations: number;
    salleReservations: number;
    materialReservations: number;
    occupancyRate: number;
    activeAssociations: number;
    totalMaterialUnits: number;
    averageReservationsPerAssociation: number;
  };
  associationUsage: Array<{
    associationName: string;
    thematics: string[];
    totalReservations: number;
    salleReservations: number;
    materialReservations: number;
    lastReservationAt: string;
  }>;
  roomOccupancy: Array<{
    roomName: string;
    bookedDays: number;
    occupancyRate: number;
  }>;
  materialUsage: Array<{
    label: string;
    quantity: number;
    requests: number;
  }>;
  history: Array<{
    type: string;
    associationName: string;
    title: string;
    startDate: string;
    endDate: string;
    resources: string;
    status: string;
    createdAt: Date;
  }>;
};

const requestTypeLabels: Record<string, string> = {
  demande_salle: "Demande salle",
  demande_materiel_evenementiel: "Matériel événementiel",
};

const statusLabels: Record<string, string> = {
  brouillon: "Brouillon",
  soumise: "Soumise",
  en_cours_traitement: "En cours",
  information_complementaire: "Info requise",
  validee: "Validée",
  refusee: "Refusée",
  annulee: "Annulée",
};

function formatDateFr(value: string | Date | null | undefined) {
  if (!value) return "-";
  try {
    return new Date(value).toLocaleDateString("fr-FR", {
      day: "2-digit",
      month: "2-digit",
      year: "numeric",
    });
  } catch {
    return String(value);
  }
}

function buildFileBaseName(data: AnalyticsPayload) {
  return `rapport-statistiques-ccds-${data.period}-${data.endDate}`;
}

export async function generateReservationAnalyticsPdf(data: AnalyticsPayload) {
  const doc = new PDFDocument({
    size: "A4",
    margin: 40,
    info: {
      Title: `Rapport statistiques CCDS - ${data.periodLabel}`,
      Author: "Portail Associations CCDS",
    },
  });

  const chunks: Buffer[] = [];
  doc.on("data", (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));

  const done = new Promise<Buffer>((resolve) => {
    doc.on("end", () => resolve(Buffer.concat(chunks)));
  });

  doc.fontSize(20).fillColor("#000091").text("Rapport statistiques CCDS");
  doc.moveDown(0.3);
  doc.fontSize(11).fillColor("#475569").text(`${data.periodLabel} - ${formatDateFr(data.startDate)} au ${formatDateFr(data.endDate)}`);
  doc.moveDown(1);

  doc.fontSize(14).fillColor("#0f172a").text("Synthèse");
  doc.moveDown(0.5);
  [
    ["Réservations totales", String(data.summary.totalReservations)],
    ["Réservations de salles", String(data.summary.salleReservations)],
    ["Réservations de matériel", String(data.summary.materialReservations)],
    ["Taux d'occupation des salles", `${data.summary.occupancyRate}%`],
    ["Associations utilisatrices", String(data.summary.activeAssociations)],
    ["Unités matérielles demandées", String(data.summary.totalMaterialUnits)],
    ["Fréquence moyenne par association", String(data.summary.averageReservationsPerAssociation)],
  ].forEach(([label, value]) => {
    doc.font("Helvetica-Bold").fontSize(10).fillColor("#0f172a").text(`${label} : `, { continued: true });
    doc.font("Helvetica").text(value);
  });

  doc.moveDown(1);
  doc.font("Helvetica-Bold").fontSize(14).text("Top associations");
  doc.moveDown(0.5);
  data.associationUsage.slice(0, 10).forEach((entry) => {
    doc.fontSize(10).font("Helvetica-Bold").text(entry.associationName);
    doc.font("Helvetica").text(
      `Catégories: ${entry.thematics.join(" / ") || "Non renseignée"} • Total: ${entry.totalReservations} • Salles: ${entry.salleReservations} • Matériel: ${entry.materialReservations} • Dernière réservation: ${formatDateFr(entry.lastReservationAt)}`
    );
    doc.moveDown(0.4);
  });

  doc.addPage();
  doc.font("Helvetica-Bold").fontSize(14).text("Occupation des salles");
  doc.moveDown(0.5);
  data.roomOccupancy.forEach((entry) => {
    doc.fontSize(10).font("Helvetica-Bold").text(entry.roomName, { continued: true });
    doc.font("Helvetica").text(` - ${entry.bookedDays} jour(s) réservé(s), ${entry.occupancyRate}% d'occupation`);
  });

  doc.moveDown(1);
  doc.font("Helvetica-Bold").fontSize(14).text("Matériels les plus demandés");
  doc.moveDown(0.5);
  data.materialUsage.forEach((entry) => {
    doc.fontSize(10).font("Helvetica-Bold").text(entry.label, { continued: true });
    doc.font("Helvetica").text(` - Quantité: ${entry.quantity} • Dossiers: ${entry.requests}`);
  });

  doc.moveDown(1);
  doc.font("Helvetica-Bold").fontSize(14).text("Historique récent");
  doc.moveDown(0.5);
  data.history.slice(0, 20).forEach((entry) => {
    const period = entry.startDate === entry.endDate
      ? formatDateFr(entry.startDate)
      : `${formatDateFr(entry.startDate)} au ${formatDateFr(entry.endDate)}`;
    doc.fontSize(10).font("Helvetica-Bold").text(`${requestTypeLabels[entry.type] || entry.type} - ${entry.associationName}`);
    doc.font("Helvetica").text(`${entry.title} • ${period} • ${entry.resources || "-"} • ${statusLabels[entry.status] || entry.status}`);
    doc.moveDown(0.35);
  });

  doc.end();
  const buffer = await done;
  return {
    buffer,
    fileName: `${buildFileBaseName(data)}.pdf`,
    contentType: "application/pdf",
  };
}

export function generateReservationAnalyticsExcel(data: AnalyticsPayload) {
  const workbook = XLSX.utils.book_new();

  const summaryRows = [
    ["Rapport statistiques CCDS", ""],
    ["Période", `${data.periodLabel} (${data.startDate} au ${data.endDate})`],
    ["Comparaison", data.comparisonLabel],
    [],
    ["Indicateur", "Valeur"],
    ["Réservations totales", data.summary.totalReservations],
    ["Réservations de salles", data.summary.salleReservations],
    ["Réservations de matériel", data.summary.materialReservations],
    ["Taux d'occupation des salles", `${data.summary.occupancyRate}%`],
    ["Associations utilisatrices", data.summary.activeAssociations],
    ["Unités matérielles demandées", data.summary.totalMaterialUnits],
    ["Fréquence moyenne par association", data.summary.averageReservationsPerAssociation],
  ];

  const associationRows = [
    ["Association", "Catégories", "Total", "Salles", "Matériel", "Dernière réservation"],
    ...data.associationUsage.map((item) => [
      item.associationName,
      item.thematics.join(" / "),
      item.totalReservations,
      item.salleReservations,
      item.materialReservations,
      item.lastReservationAt,
    ]),
  ];

  const roomRows = [
    ["Salle", "Jours réservés", "Taux d'occupation"],
    ...data.roomOccupancy.map((item) => [item.roomName, item.bookedDays, `${item.occupancyRate}%`]),
  ];

  const materialRows = [
    ["Matériel", "Quantité", "Dossiers"],
    ...data.materialUsage.map((item) => [item.label, item.quantity, item.requests]),
  ];

  const historyRows = [
    ["Type", "Association", "Dossier", "Début", "Fin", "Ressources", "Statut"],
    ...data.history.map((item) => [
      requestTypeLabels[item.type] || item.type,
      item.associationName,
      item.title,
      item.startDate,
      item.endDate,
      item.resources,
      statusLabels[item.status] || item.status,
    ]),
  ];

  XLSX.utils.book_append_sheet(workbook, XLSX.utils.aoa_to_sheet(summaryRows), "Synthèse");
  XLSX.utils.book_append_sheet(workbook, XLSX.utils.aoa_to_sheet(associationRows), "Associations");
  XLSX.utils.book_append_sheet(workbook, XLSX.utils.aoa_to_sheet(roomRows), "Salles");
  XLSX.utils.book_append_sheet(workbook, XLSX.utils.aoa_to_sheet(materialRows), "Matériel");
  XLSX.utils.book_append_sheet(workbook, XLSX.utils.aoa_to_sheet(historyRows), "Historique");

  const buffer = XLSX.write(workbook, { type: "buffer", bookType: "xlsx" }) as Buffer;
  return {
    buffer,
    fileName: `${buildFileBaseName(data)}.xlsx`,
    contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  };
}
