import { createTextPdf, type PdfAssets, type PdfBlock } from '../shared/pdf';
import { addDays, calendarDays } from '../shared/dates';
import { calculatePlan, type Plan } from './core';

/** The brief carries full text; separate numbered timeline pages stay readable. */
export async function generatePlanPdf(plan: Plan, assets: PdfAssets, pageSize: 'A4' | 'Letter' = 'A4'): Promise<Uint8Array> {
  const result = calculatePlan(plan);
  const money = (value: string) => `${plan.currency} ${value}`;
  const blocks: PdfBlock[] = [
    { text: 'Project Timeline & Budget Planner', size: 18, bold: true },
    { text: plan.title, size: 16, bold: true },
    { text: plan.description || 'Project description not supplied.' },
    { text: 'Planning estimate based on your inputs—not a quotation.' },
    { text: `Reference date: ${plan.referenceDate}. Total hours: ${result.totalHours}.` },
    { text: `Base cost: ${money(result.baseCost)}. Contingency (${plan.contingencyPercent}%): ${money(result.contingency)}. Total estimated cost: ${money(result.totalCost)}.`, size: 12, bold: true },
    { text: `Schedule: ${result.start} to ${result.end}, inclusive. ${result.calendarDays} calendar days; ${result.workingDays} Monday–Friday working days. Holidays are not deducted. Hours are entered separately from duration.` },
    { text: 'Dependencies mean finish-to-start with zero lag. A following task should start no earlier than the next working day after its predecessor ends. Dependent tasks are never moved automatically.' },
    { text: 'The numbered timeline appears on separate landscape pages after the task details. Each page repeats the same date scale and shows at most 18 tasks; numbers refer to the task list below. Exact inclusive dates are printed beside every task.' },
    { text: 'Task details', size: 15, bold: true },
  ];
  for (const [index, task] of plan.tasks.entries()) blocks.push(
    { text: `${index + 1}. ${task.title} — ${task.phase}`, size: 12, bold: true },
    { text: `${task.start} to ${task.end} (inclusive). ${task.hours} hours × ${money(task.rate)} per hour = ${money(result.taskCosts[task.id])}. Progress: ${task.progressPercent}%.` },
    { text: `Task ID: ${task.id}. Predecessors: ${task.predecessors.map(id => `${plan.tasks.findIndex(other => other.id === id) + 1} (${id})`).join(', ') || 'None'}.` },
  );
  const { validatePlan } = await import('./core');
  const checked = validatePlan(plan);
  if (checked.warnings.length) blocks.push({ text: 'Schedule conflicts to review', size: 14, bold: true }, ...checked.warnings.map(warning => ({ text: warning.message })));
  const textPdf = await createTextPdf(blocks, assets, pageSize);
  const { PDFDocument, StandardFonts, rgb } = await import('@pdfme/pdf-lib');
  const doc = await PDFDocument.load(textPdf);
  const font = await doc.embedFont(StandardFonts.Helvetica);
  const bold = await doc.embedFont(StandardFonts.HelveticaBold);
  const totalPages = Math.ceil(plan.tasks.length / 18);
  for (let group = 0; group < totalPages; group++) {
    const page = doc.addPage(pageSize === 'Letter' ? [792, 612] : [841.89, 595.28]);
    const width = page.getWidth(); const height = page.getHeight();
    const labelX = 30; const chartX = 245; const chartWidth = width - chartX - 30;
    page.drawText(`Project timeline ${group + 1} of ${totalPages}`, { x: labelX, y: height - 35, size: 18, font: bold });
    page.drawText('Task numbers match the full task details. Dates include both the first and last day.', { x: labelX, y: height - 55, size: 10, font });
    const ticks = 5;
    for (let tick = 0; tick <= ticks; tick++) {
      const offset = Math.round((result.calendarDays - 1) * tick / ticks);
      const label = addDays(result.start, offset);
      const x = chartX + chartWidth * tick / ticks;
      page.drawText(label, { x: Math.min(x - 20, width - 85), y: height - 83, size: 8, font });
      page.drawLine({ start: { x, y: height - 92 }, end: { x, y: 40 }, thickness: 0.4, color: rgb(0.87, 0.87, 0.89) });
    }
    for (const [row, task] of plan.tasks.slice(group * 18, group * 18 + 18).entries()) {
      const index = group * 18 + row;
      const y = height - 116 - row * 24;
      const offset = calendarDays(result.start, task.start) - 1;
      const duration = calendarDays(task.start, task.end);
      const x = chartX + offset / result.calendarDays * chartWidth;
      const barWidth = Math.max(1.5, duration / result.calendarDays * chartWidth);
      page.drawText(`${index + 1}. ${task.start} - ${task.end}`, { x: labelX, y, size: 9, font });
      page.drawRectangle({ x, y: y - 2, width: Math.min(barWidth, width - 30 - x), height: 13, color: rgb(0.42, 0.27, 1) });
    }
    page.drawText('Long spans use the same proportional scale on every timeline page. Exact dates appear at left.', { x: labelX, y: 20, size: 8, font });
  }
  doc.setTitle(plan.title);
  doc.setSubject('Planning estimate based on user inputs; not a quotation.');
  doc.setCreator('Essential Tools Project Planner');
  return doc.save();
}
