const PDFDocument = require('pdfkit');
const { all, one } = require('../db');
const { annualSchedule, money, monthlyFromAnnual } = require('../depreciation');
const { assetExportRows, assetFromRow } = require('./assets');
const { ruleSetForBook } = require('./ruleSets');

function depreciationReport(year, bookType, companyId) {
  const rules = ruleSetForBook(bookType);
  const rows = all(`
    SELECT a.*, b.book_type, b.active, b.cost, b.depreciation_method, b.convention, b.useful_life_months AS book_life,
      b.section_179_amount, b.bonus_percent, b.business_use_percent AS book_business_use_percent,
      b.investment_use_percent AS book_investment_use_percent, b.manual_depreciation, e.name AS entity_name
    FROM assets a
    JOIN asset_books b ON b.asset_id = a.id
    LEFT JOIN entities e ON e.id = a.entity_id
    WHERE b.active = 1 AND b.book_type = ? AND (? IS NULL OR a.entity_id = ?)
    ORDER BY a.asset_id
  `, [bookType, companyId || null, companyId || null]);

  const reportRows = rows.map((row) => {
    const asset = assetFromRow(row);
    const book = {
      ...row,
      useful_life_months: row.book_life,
      business_use_percent: row.book_business_use_percent,
      investment_use_percent: row.book_investment_use_percent
    };
    const schedule = annualSchedule(asset, book, rules, { startYear: year, endYear: year })[0] || {};
    return {
      asset_id: row.asset_id,
      description: row.description,
      entity_name: row.entity_name,
      category: row.category,
      book: bookType,
      method: row.depreciation_method,
      methodLabel: schedule.methodLabel || row.depreciation_method,
      cost: money(row.cost ?? row.acquisition_cost),
      depreciation: money(schedule.depreciation || 0),
      accumulated: money(schedule.accumulated || 0),
      net_book_value: money(schedule.netBookValue ?? row.acquisition_cost)
    };
  });

  return {
    year,
    book: bookType,
    totals: {
      cost: money(reportRows.reduce((sum, row) => sum + row.cost, 0)),
      depreciation: money(reportRows.reduce((sum, row) => sum + row.depreciation, 0)),
      accumulated: money(reportRows.reduce((sum, row) => sum + row.accumulated, 0)),
      netBookValue: money(reportRows.reduce((sum, row) => sum + row.net_book_value, 0))
    },
    rows: reportRows
  };
}

function monthlyDepreciationReport(year, bookType, companyId) {
  const rules = ruleSetForBook(bookType);
  const assets = all('SELECT * FROM assets WHERE (? IS NULL OR entity_id = ?) ORDER BY asset_id', [companyId || null, companyId || null]).map(assetFromRow);
  const rows = assets.flatMap((asset) => {
    const book = one('SELECT * FROM asset_books WHERE asset_id = ? AND book_type = ? AND active = 1', [asset.id, bookType]);
    if (!book) return [];
    return annualSchedule(asset, book, rules, { startYear: year, endYear: year }).flatMap(monthlyFromAnnual);
  });
  const months = Array.from({ length: 12 }, (_, index) => {
    const month = index + 1;
    return {
      month,
      depreciation: money(rows.filter((row) => row.month === month).reduce((sum, row) => sum + row.depreciation, 0))
    };
  });
  return { year, book: bookType, months };
}

function writeDepreciationPdf(res, year, book, companyId) {
  const rows = assetExportRows(companyId);
  const doc = new PDFDocument({ margin: 36, size: 'LETTER' });
  res.setHeader('Content-Type', 'application/pdf');
  res.setHeader('Content-Disposition', `attachment; filename="deprecore-${book}-${year}.pdf"`);
  doc.pipe(res);
  doc.fontSize(18).text('DepreCore Depreciation Report');
  doc.fontSize(10).text(`Book: ${book}  Year: ${year}  Generated: ${new Date().toLocaleString()}`);
  doc.moveDown();
  doc.fontSize(9).text('Asset ID', 36, doc.y, { continued: true, width: 80 });
  doc.text('Description', 100, doc.y, { continued: true, width: 210 });
  doc.text('Category', 300, doc.y, { continued: true, width: 110 });
  doc.text('Cost', 430, doc.y, { align: 'right' });
  doc.moveDown(0.5);
  rows.slice(0, 80).forEach((row) => {
    doc.text(row.asset_id, 36, doc.y, { continued: true, width: 80 });
    doc.text(String(row.description).slice(0, 36), 100, doc.y, { continued: true, width: 210 });
    doc.text(String(row.category).slice(0, 20), 300, doc.y, { continued: true, width: 110 });
    doc.text(money(row.acquisition_cost).toLocaleString(), 430, doc.y, { align: 'right' });
  });
  doc.end();
}

module.exports = {
  depreciationReport,
  monthlyDepreciationReport,
  writeDepreciationPdf
};
