import { Injectable } from '@nestjs/common';
import { PlanningService } from './planning.service';
import * as ExcelJS from 'exceljs';
import PDFDocument from 'pdfkit';
import dayjs from 'dayjs';
import 'dayjs/locale/fr';

dayjs.locale('fr');

@Injectable()
export class PlanningExportService {
  constructor(private readonly planningService: PlanningService) {}

  // ─── Export Excel planning équipe ────────────────────────────────────────────
  async exportTeamPlanningExcel(
    teamId: number,
    view: 'month' | 'week',
    date: string,
  ): Promise<ExcelJS.Buffer> {
    const planning = await this.planningService.getTeamPlanning(teamId, view, date);
    const workbook  = new ExcelJS.Workbook();
    const sheet     = workbook.addWorksheet(
      `Planning ${planning.team_name} — ${dayjs(date).format('MMMM YYYY')}`
    );

    // ── Styles ────────────────────────────────────────────────────────────────
    const headerStyle: Partial<ExcelJS.Style> = {
      fill:   { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF1E88E5' } },
      font:   { bold: true, color: { argb: 'FFFFFFFF' }, size: 11 },
      alignment: { horizontal: 'center', vertical: 'middle' },
      border: {
        top:    { style: 'thin' },
        bottom: { style: 'thin' },
        left:   { style: 'thin' },
        right:  { style: 'thin' },
      },
    };

    const holidayStyle: Partial<ExcelJS.Style> = {
      fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFFDE68A' } },
      font: { italic: true, color: { argb: 'FF92400E' } },
    };

    const weekendStyle: Partial<ExcelJS.Style> = {
      fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFF1F5F9' } },
      font: { color: { argb: 'FF94A3B8' } },
    };

    // ── Titre ─────────────────────────────────────────────────────────────────
    sheet.mergeCells(1, 1, 1, planning.members.length + 1);
    const titleCell = sheet.getCell(1, 1);
    titleCell.value = `Planning ${planning.team_name} — ${dayjs(date).format('MMMM YYYY')}`;
    titleCell.style = {
      font:      { bold: true, size: 14, color: { argb: 'FF1E3A5F' } },
      alignment: { horizontal: 'center' },
    };
    sheet.getRow(1).height = 30;

    // ── Sous-titre ────────────────────────────────────────────────────────────
    sheet.mergeCells(2, 1, 2, planning.members.length + 1);
    sheet.getCell(2, 1).value =
      `Du ${dayjs(planning.period.start).format('DD/MM/YYYY')} au ${dayjs(planning.period.end).format('DD/MM/YYYY')} — Seuil minimum : ${planning.min_presence} personne(s)`;
    sheet.getCell(2, 1).style = {
      font:      { italic: true, size: 10, color: { argb: 'FF64748B' } },
      alignment: { horizontal: 'center' },
    };
    sheet.getRow(2).height = 20;

    // ── En-têtes colonnes (membres) ───────────────────────────────────────────
    const headerRow = sheet.getRow(3);
    headerRow.getCell(1).value = 'Date';
    headerRow.getCell(1).style = headerStyle;
    sheet.getColumn(1).width   = 18;

    planning.members.forEach((member, idx) => {
      const cell = headerRow.getCell(idx + 2);
      cell.value = `${member.first_name} ${member.last_name}`;
      cell.style = headerStyle;
      sheet.getColumn(idx + 2).width = 20;
    });
    headerRow.height = 25;

    // ── Lignes par jour ───────────────────────────────────────────────────────
    planning.days.forEach((day, rowIdx) => {
      const row     = sheet.getRow(rowIdx + 4);
      const dateStr = dayjs(day.date).format('ddd DD/MM');

      // Colonne date
      const dateCell  = row.getCell(1);
      dateCell.value  = dateStr;
      dateCell.style  = day.is_holiday ? holidayStyle :
                        day.is_weekend ? weekendStyle : {
                          font:      { size: 10 },
                          alignment: { horizontal: 'center' },
                        };

      if (day.is_holiday) {
        dateCell.value = `${dateStr} — ${day.holiday_label}`;
      }

      // Colonnes membres
      planning.members.forEach((member, colIdx) => {
        const cell    = row.getCell(colIdx + 2);
        const absence = day.absences.find(a => a.user_id === member.id);

        if (day.is_weekend) {
          cell.style = weekendStyle;
          cell.value = '—';
        } else if (day.is_holiday) {
          cell.style = holidayStyle;
          cell.value = '🎌';
        } else if (absence) {
          cell.value = absence.leave_type;
          cell.style = {
            fill: {
              type: 'pattern',
              pattern: 'solid',
              fgColor: { argb: 'FF' + absence.leave_color.replace('#', '') },
            },
            font:      { color: { argb: 'FFFFFFFF' }, size: 9 },
            alignment: { horizontal: 'center' },
          };
        } else {
          cell.value = '✓';
          cell.style = {
            font:      { color: { argb: 'FF22C55E' }, bold: true },
            alignment: { horizontal: 'center' },
          };
        }
      });

      row.height = 18;
    });

    // ── Légende ───────────────────────────────────────────────────────────────
    const legendRow = planning.days.length + 5;
    sheet.getRow(legendRow).getCell(1).value     = 'Légende :';
    sheet.getRow(legendRow).getCell(1).style      = { font: { bold: true } };
    sheet.getRow(legendRow + 1).getCell(1).value  = '✓ = Présent';
    sheet.getRow(legendRow + 2).getCell(1).value  = '🎌 = Jour férié';
    sheet.getRow(legendRow + 3).getCell(1).value  = '— = Week-end';
    sheet.getRow(legendRow + 4).getCell(1).value  = 'Couleur = Type de congé';

    return workbook.xlsx.writeBuffer();
  }

  // ─── Export Excel planning global ────────────────────────────────────────────
  async exportGlobalPlanningExcel(
    view: 'month' | 'week',
    date: string,
  ): Promise<ExcelJS.Buffer> {
    const planning = await this.planningService.getGlobalPlanning(view, date, undefined, undefined, 1, 1000);
    const workbook  = new ExcelJS.Workbook();
    const sheet     = workbook.addWorksheet(
      `Planning Global — ${dayjs(date).format('MMMM YYYY')}`
    );

    // ── Titre ─────────────────────────────────────────────────────────────────
    sheet.mergeCells(1, 1, 1, 5);
    sheet.getCell(1, 1).value = `Planning Global — ${dayjs(date).format('MMMM YYYY')}`;
    sheet.getCell(1, 1).style = {
      font:      { bold: true, size: 14 },
      alignment: { horizontal: 'center' },
    };

    // ── En-têtes ──────────────────────────────────────────────────────────────
    const headers = ['Matricule', 'Nom', 'Prénom', 'Équipe', 'Planning', 'Congés sur la période'];
    const headerRow = sheet.getRow(2);

    headers.forEach((h, i) => {
      const cell  = headerRow.getCell(i + 1);
      cell.value  = h;
      cell.style  = {
        fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF1E88E5' } },
        font: { bold: true, color: { argb: 'FFFFFFFF' } },
        alignment: { horizontal: 'center' },
      };
    });

    sheet.columns = [
      { width: 12 },
      { width: 18 },
      { width: 18 },
      { width: 20 },
      { width: 10 },
      { width: 50 },
    ];

    // ── Données ───────────────────────────────────────────────────────────────
    planning.members.forEach((member, idx) => {
      const row = sheet.getRow(idx + 3);

      const absenceSummary = member.absences.length > 0
        ? member.absences.map(a =>
            `${a.leave_type} (${dayjs(a.date_start).format('DD/MM')} → ${dayjs(a.date_end).format('DD/MM')} — ${a.days_count}j)`
          ).join(' | ')
        : 'Aucune absence';

      row.getCell(1).value = member.matricule;
      row.getCell(2).value = member.last_name;
      row.getCell(3).value = member.first_name;
      row.getCell(4).value = member.team_name;
      row.getCell(5).value = member.work_schedule;
      row.getCell(6).value = absenceSummary;

      if (member.absences.length > 0) {
        row.getCell(6).style = {
          font: { color: { argb: 'FFE53935' } },
        };
      }

      row.height = 18;
    });

    // ── Stats ─────────────────────────────────────────────────────────────────
    const statsRow = planning.members.length + 4;
    sheet.getRow(statsRow).getCell(1).value     = 'Taux d\'absence par équipe :';
    sheet.getRow(statsRow).getCell(1).style      = { font: { bold: true } };

    planning.stats.absence_rate_by_team.forEach((stat, idx) => {
      sheet.getRow(statsRow + idx + 1).getCell(1).value =
        `${stat.team_name} : ${stat.absent_today} absent(s) / ${stat.total_members} — ${stat.rate}%`;
    });

    return workbook.xlsx.writeBuffer();
  }

  // ─── Export PDF planning équipe ──────────────────────────────────────────────
  async exportTeamPlanningPDF(
    teamId: number,
    view: 'month' | 'week',
    date: string,
  ): Promise<Buffer> {
    const planning = await this.planningService.getTeamPlanning(teamId, view, date);

    return new Promise((resolve, reject) => {
      const doc = new PDFDocument({ margin: 40, size: 'A4', layout: 'landscape' });
      const chunks: Buffer[] = [];

      doc.on('data',  chunk => chunks.push(chunk));
      doc.on('end',   ()    => resolve(Buffer.concat(chunks)));
      doc.on('error', err   => reject(err));

      // ── Titre ───────────────────────────────────────────────────────────────
      doc.fontSize(16).fillColor('#1E3A5F')
        .text(`Planning ${planning.team_name}`, { align: 'center' });

      doc.fontSize(10).fillColor('#64748B')
        .text(
          `Du ${dayjs(planning.period.start).format('DD/MM/YYYY')} au ${dayjs(planning.period.end).format('DD/MM/YYYY')}`,
          { align: 'center' }
        );

      doc.moveDown();

      // ── Tableau ──────────────────────────────────────────────────────────────
      const colWidth    = Math.min(100, (doc.page.width - 120) / (planning.members.length + 1));
      const rowHeight   = 20;
      const startX      = 40;
      let   currentY    = doc.y + 10;

      // En-têtes
      doc.fontSize(8).fillColor('#FFFFFF');
      doc.rect(startX, currentY, colWidth, rowHeight).fill('#1E88E5');
      doc.fillColor('#FFFFFF').text('Date', startX + 4, currentY + 6, { width: colWidth - 8 });

      planning.members.forEach((member, idx) => {
        const x = startX + (idx + 1) * colWidth;
        doc.rect(x, currentY, colWidth, rowHeight).fill('#1E88E5');
        doc.fillColor('#FFFFFF').text(
          `${member.first_name[0]}. ${member.last_name}`,
          x + 4, currentY + 6,
          { width: colWidth - 8 }
        );
      });

      currentY += rowHeight;

      // Lignes
      planning.days.forEach(day => {
        if (currentY + rowHeight > doc.page.height - 60) {
          doc.addPage({ layout: 'landscape' });
          currentY = 40;
        }

        const bgColor = day.is_holiday ? '#FDE68A' :
                        day.is_weekend ? '#F1F5F9' : '#FFFFFF';

        doc.rect(startX, currentY, colWidth * (planning.members.length + 1), rowHeight)
          .fill(bgColor);

        // Bordures
        doc.rect(startX, currentY, colWidth * (planning.members.length + 1), rowHeight)
          .stroke('#E2E8F0');

        // Date
        const dateLabel = day.is_holiday
          ? `${dayjs(day.date).format('ddd DD/MM')} 🎌`
          : dayjs(day.date).format('ddd DD/MM');

        doc.fontSize(7)
          .fillColor(day.is_holiday ? '#92400E' : day.is_weekend ? '#94A3B8' : '#1E293B')
          .text(dateLabel, startX + 4, currentY + 6, { width: colWidth - 8 });

        // Membres
        planning.members.forEach((member, idx) => {
          const x       = startX + (idx + 1) * colWidth;
          const absence = day.absences.find(a => a.user_id === member.id);

          if (day.is_weekend || day.is_holiday) {
            doc.fontSize(7).fillColor('#94A3B8')
              .text('—', x + 4, currentY + 6, { width: colWidth - 8 });
          } else if (absence) {
            doc.rect(x + 2, currentY + 2, colWidth - 4, rowHeight - 4)
              .fill(absence.leave_color);
            doc.fontSize(6).fillColor('#FFFFFF')
              .text(absence.leave_type.substring(0, 8), x + 4, currentY + 6, { width: colWidth - 8 });
          } else {
            doc.fontSize(8).fillColor('#22C55E')
              .text('✓', x + 4, currentY + 6, { width: colWidth - 8, align: 'center' });
          }
        });

        currentY += rowHeight;
      });

      // ── Légende ──────────────────────────────────────────────────────────────
      doc.moveDown(2);
      doc.fontSize(8).fillColor('#1E293B').text('Légende :', { continued: false });
      doc.fontSize(7).fillColor('#22C55E').text('✓ Présent   ', { continued: true });
      doc.fillColor('#92400E').text('🎌 Jour férié   ', { continued: true });
      doc.fillColor('#94A3B8').text('— Week-end   ', { continued: true });
      doc.fillColor('#1E88E5').text('Couleur = Type de congé');

      // ── Pied de page ─────────────────────────────────────────────────────────
      doc.fontSize(7).fillColor('#94A3B8')
        .text(
          `G Fly — Document généré le ${dayjs().format('DD/MM/YYYY à HH:mm')}`,
          40,
          doc.page.height - 30,
          { align: 'center' }
        );

      doc.end();
    });
  }
}