import PDFDocument from 'pdfkit';
import { DashboardSummary, FunnelConversion } from '../stats/stats.service';

const FONT_REGULAR = 'Helvetica';
const FONT_BOLD = 'Helvetica-Bold';
const COLOR_PRIMARY = '#FF6B00';
const COLOR_HEADER = '#1A1A1A';
const COLOR_TEXT = '#374151';
const COLOR_MUTED = '#6B7280';
const COLOR_BORDER = '#E5E7EB';

interface ReportMeta {
  title: string;
  clubName: string;
  generatedBy: string;
  dateFrom?: string;
  dateTo?: string;
}

function addHeader(doc: PDFKit.PDFDocument, meta: ReportMeta) {
  doc.font(FONT_BOLD).fontSize(20).fillColor(COLOR_PRIMARY).text(meta.title);
  doc.moveDown(0.3);
  doc.font(FONT_REGULAR).fontSize(10).fillColor(COLOR_MUTED);
  doc.text(`Клуб: ${meta.clubName}  |  Сформировал: ${meta.generatedBy}  |  ${new Date().toLocaleDateString('ru-RU')}`);
  if (meta.dateFrom || meta.dateTo) {
    doc.text(`Период: ${meta.dateFrom ?? '—'} — ${meta.dateTo ?? '—'}`);
  }
  doc.moveDown(0.5);
  doc.moveTo(doc.x, doc.y).lineTo(doc.x + 500, doc.y).strokeColor(COLOR_BORDER).stroke();
  doc.moveDown(0.5);
}

function addSection(doc: PDFKit.PDFDocument, title: string) {
  doc.moveDown(0.5);
  doc.font(FONT_BOLD).fontSize(14).fillColor(COLOR_HEADER).text(title);
  doc.moveDown(0.3);
}

function addKV(doc: PDFKit.PDFDocument, label: string, value: string | number) {
  doc.font(FONT_REGULAR).fontSize(11).fillColor(COLOR_MUTED).text(label, { continued: true });
  doc.font(FONT_BOLD).fillColor(COLOR_TEXT).text(`  ${value}`);
}

function addTable(
  doc: PDFKit.PDFDocument,
  headers: string[],
  rows: (string | number)[][],
  colWidths?: number[],
) {
  const startX = doc.x;
  const widths = colWidths ?? headers.map(() => Math.floor(500 / headers.length));

  // Header row
  doc.font(FONT_BOLD).fontSize(9).fillColor(COLOR_MUTED);
  let x = startX;
  for (let i = 0; i < headers.length; i++) {
    doc.text(headers[i], x, doc.y, { width: widths[i], align: i === 0 ? 'left' : 'right' });
    x += widths[i];
  }
  doc.moveDown(0.3);
  doc.moveTo(startX, doc.y).lineTo(startX + 500, doc.y).strokeColor(COLOR_BORDER).stroke();
  doc.moveDown(0.2);

  // Data rows
  doc.font(FONT_REGULAR).fontSize(9).fillColor(COLOR_TEXT);
  for (const row of rows) {
    const rowY = doc.y;
    x = startX;
    for (let i = 0; i < row.length; i++) {
      doc.text(String(row[i]), x, rowY, { width: widths[i], align: i === 0 ? 'left' : 'right' });
      x += widths[i];
    }
    doc.moveDown(0.1);
    // Page break if near bottom
    if (doc.y > 700) {
      doc.addPage();
    }
  }
}

export function generateClientsSummaryPdf(
  meta: ReportMeta,
  summary: DashboardSummary,
  clients: { firstName: string; lastName: string; phone: string; status: string; createdAt: string }[],
): PDFKit.PDFDocument {
  const doc = new PDFDocument({ size: 'A4', margin: 50 });
  addHeader(doc, meta);

  addSection(doc, 'Общая статистика');
  addKV(doc, 'Всего клиентов:', summary.totalClients);
  addKV(doc, 'Новых за период:', summary.newClients);
  addKV(doc, 'Спящих:', summary.sleepingClients);
  addKV(doc, 'Всего тренировок:', summary.totalTrainings);

  if (clients.length > 0) {
    addSection(doc, 'Список клиентов');
    addTable(
      doc,
      ['Имя', 'Телефон', 'Статус', 'Дата создания'],
      clients.map((c) => [
        `${c.lastName} ${c.firstName}`,
        c.phone,
        c.status,
        new Date(c.createdAt).toLocaleDateString('ru-RU'),
      ]),
      [180, 120, 100, 100],
    );
  }

  doc.end();
  return doc;
}

export function generateFunnelConversionPdf(
  meta: ReportMeta,
  funnel: FunnelConversion,
): PDFKit.PDFDocument {
  const doc = new PDFDocument({ size: 'A4', margin: 50 });
  addHeader(doc, meta);

  addSection(doc, 'Воронка конверсии');
  addKV(doc, 'Новые:', funnel.totalNew);
  addKV(doc, 'Назначено:', funnel.totalAssigned);
  addKV(doc, 'Проведено:', funnel.totalCompleted);
  addKV(doc, 'Постоянные:', funnel.totalRegular);
  doc.moveDown(0.3);
  addKV(doc, 'Новые → Назначено:', `${funnel.newToAssigned}%`);
  addKV(doc, 'Назначено → Проведено:', `${funnel.assignedToCompleted}%`);
  addKV(doc, 'Проведено → Постоянные:', `${funnel.completedToRegular}%`);

  if (funnel.perTrainer.length > 0) {
    addSection(doc, 'Конверсия по тренерам');
    addTable(
      doc,
      ['Тренер', 'Новые', 'Назн.', 'Пров.', 'Пост.', 'Н→Н%', 'Н→П%', 'П→П%'],
      funnel.perTrainer.map((t) => [
        t.trainerName,
        t.totalNew,
        t.totalAssigned,
        t.totalCompleted,
        t.totalRegular,
        `${t.newToAssigned}%`,
        `${t.assignedToCompleted}%`,
        `${t.completedToRegular}%`,
      ]),
      [120, 50, 50, 50, 50, 55, 55, 55],
    );
  }

  doc.end();
  return doc;
}

export function generateSalesSummaryPdf(
  meta: ReportMeta,
  summary: DashboardSummary,
  sales: { trainerName: string; count: number; totalAmount: number; paidAmount: number }[],
): PDFKit.PDFDocument {
  const doc = new PDFDocument({ size: 'A4', margin: 50 });
  addHeader(doc, meta);

  addSection(doc, 'Продажи');
  addKV(doc, 'Общая сумма:', `${summary.totalSalesAmount.toLocaleString('ru-RU')} ₽`);
  addKV(doc, 'Оплачено:', `${summary.paidSalesAmount.toLocaleString('ru-RU')} ₽`);
  addKV(doc, 'Не оплачено:', `${(summary.totalSalesAmount - summary.paidSalesAmount).toLocaleString('ru-RU')} ₽`);

  if (sales.length > 0) {
    addSection(doc, 'По тренерам');
    addTable(
      doc,
      ['Тренер', 'Кол-во', 'Сумма', 'Оплачено', '% оплаты'],
      sales.map((s) => [
        s.trainerName,
        s.count,
        `${s.totalAmount.toLocaleString('ru-RU')} ₽`,
        `${s.paidAmount.toLocaleString('ru-RU')} ₽`,
        s.totalAmount > 0 ? `${Math.round((s.paidAmount / s.totalAmount) * 100)}%` : '—',
      ]),
      [150, 60, 100, 100, 80],
    );
  }

  doc.end();
  return doc;
}

export function generateSleepingClientsPdf(
  meta: ReportMeta,
  clients: { firstName: string; lastName: string; phone: string; lastActivity: string; trainerName: string }[],
): PDFKit.PDFDocument {
  const doc = new PDFDocument({ size: 'A4', margin: 50 });
  addHeader(doc, meta);

  addSection(doc, `Спящие клиенты (${clients.length})`);

  if (clients.length > 0) {
    addTable(
      doc,
      ['Имя', 'Телефон', 'Последняя активность', 'Тренер'],
      clients.map((c) => [
        `${c.lastName} ${c.firstName}`,
        c.phone,
        c.lastActivity ? new Date(c.lastActivity).toLocaleDateString('ru-RU') : '—',
        c.trainerName || '—',
      ]),
      [150, 120, 120, 110],
    );
  } else {
    doc.font(FONT_REGULAR).fontSize(11).fillColor(COLOR_MUTED).text('Спящих клиентов нет.');
  }

  doc.end();
  return doc;
}

export function generateTrainerPerformancePdf(
  meta: ReportMeta,
  trainer: { firstName: string; lastName: string },
  stats: {
    trainings: { total: number; completed: number; cancelled: number };
    sales: { totalAmount: number; paidAmount: number; count: number };
    clients: number;
    funnel: { newToAssigned: number; assignedToCompleted: number; completedToRegular: number };
  },
): PDFKit.PDFDocument {
  const doc = new PDFDocument({ size: 'A4', margin: 50 });
  addHeader(doc, meta);

  addSection(doc, `Тренер: ${trainer.lastName} ${trainer.firstName}`);

  addSection(doc, 'Тренировки');
  addKV(doc, 'Всего:', stats.trainings.total);
  addKV(doc, 'Проведено:', stats.trainings.completed);
  addKV(doc, 'Отменено:', stats.trainings.cancelled);

  addSection(doc, 'Продажи');
  addKV(doc, 'Кол-во:', stats.sales.count);
  addKV(doc, 'Сумма:', `${stats.sales.totalAmount.toLocaleString('ru-RU')} ₽`);
  addKV(doc, 'Оплачено:', `${stats.sales.paidAmount.toLocaleString('ru-RU')} ₽`);

  addSection(doc, 'Клиенты и конверсия');
  addKV(doc, 'Клиентов:', stats.clients);
  addKV(doc, 'Новые → Назначено:', `${stats.funnel.newToAssigned}%`);
  addKV(doc, 'Назначено → Проведено:', `${stats.funnel.assignedToCompleted}%`);
  addKV(doc, 'Проведено → Постоянные:', `${stats.funnel.completedToRegular}%`);

  doc.end();
  return doc;
}
