/**
 * Function/Reports/report-history.js
 * ---------------------------------------------------------------------------
 * REPORT HISTORY
 *
 * Every report this application has generated: name, type, date, size and
 * location - with view, open and (confirmed) delete.
 * ---------------------------------------------------------------------------
 */

'use strict';

const fs = require('fs');
const { execFile } = require('child_process');
const kit = require('../../core/kit');
const system = require('../../core/system');
const reportManager = require('../../core/report-manager');

module.exports = {
  name: 'Report History',
  menuName: 'Report History',
  description: 'Lists the generated reports with type, date, size and location.',
  version: '1.0.0',
  author: 'InfinitySniper HFX',
  category: 'Reports',
  order: 20,
  requiredPermissions: 'normal',
  destructive: true,
  dependencies: [],
  minimumAppVersion: '1.0.0',
  permissions: ['filesystem:read(reports)', 'filesystem:delete(reports, confirmed)'],
  tags: ['reports', 'history', 'files', 'export'],
  documentation:
    'Shows every .txt report in the reports folder, newest first, with the report type derived from ' +
    'the file name. A report can be previewed in the console, opened in Notepad, or deleted after a ' +
    'confirmation. Only files inside the reports folder can ever be deleted here.',

  async selfTest() {
    const reports = reportManager.listReports();
    return { ok: true, message: `${reports.length} report(s) on disk` };
  },

  async execute(ctx) {
    const { ui, prompt } = ctx;
    kit.header('Report History', ['Reports generated by this application.']);

    for (;;) {
      const reports = reportManager.listReports();

      ui.blank();
      ui.section('SUMMARY');
      ui.blank();
      kit.kv('Reports Stored', system.formatNumber(reports.length));
      kit.kv('Total Size', system.formatBytes(reports.reduce((sum, report) => sum + report.size, 0)));
      kit.kv('Folder', ctx.paths.reports);

      if (!reports.length) {
        ui.blank();
        ui.info('No report has been generated yet.');
        ui.println('  ' + ui.c.gray('Most functions offer "Save this information as a TXT report".'));
        await prompt.pause('Press ENTER to go back');
        return { ok: true, reports: 0 };
      }

      ui.blank();
      ui.section('REPORTS');
      ui.blank();
      kit.table(
        ['#', 'REPORT', 'TYPE', 'SIZE', 'DATE'],
        reports.map((report, index) => [
          ui.c.gray(String(index + 1)),
          ui.c.brightWhite(ui.truncate(report.name, 30)),
          ui.c.brightCyan(ui.truncate(report.type, 18)),
          ui.c.gray(system.formatBytes(report.size)),
          ui.c.gray(system.isoLocal(report.modified).slice(0, 16)),
        ]),
        { align: ['right', 'left', 'left', 'right', 'left'], limit: 25 }
      );

      ui.blank();
      ui.menu(
        [
          { key: '1', label: 'Preview a report' },
          { key: '2', label: 'Open a report in Notepad' },
          { key: '3', label: 'Open the reports folder' },
          { key: '4', label: 'Delete a report', color: 'brightRed' },
          { separator: true },
          { key: '0', label: 'Back', color: 'gray' },
        ],
        { title: 'REPORT HISTORY' }
      );
      ui.blank();

      const answer = await prompt.select();
      if (!answer && prompt.isClosed()) break;
      if (answer === '0') break;

      if (answer === '1') {
        const index = await prompt.choose(
          'Which report?',
          reports.map((report) => ({ label: report.name, hint: `${report.type} - ${system.formatBytes(report.size)}` }))
        );
        if (index === null) continue;
        const report = reports[index];

        ui.blank();
        ui.section(ui.truncate(report.name, 44));
        ui.blank();
        try {
          const lines = fs.readFileSync(report.path, 'utf8').split(/\r?\n/);
          for (const line of lines.slice(0, 60)) {
            const color = /^\[ .* \]$/.test(line.trim()) ? 'brightYellow' : /^=+$/.test(line.trim()) ? 'gray' : 'white';
            ui.println('  ' + ui.c[color](ui.truncate(line, ui.getWidth())));
          }
          if (lines.length > 60) {
            ui.blank();
            ui.println('  ' + ui.c.gray(`... and ${lines.length - 60} more line(s) - open it in Notepad for the rest`));
          }
        } catch (err) {
          ui.error(`The report could not be read: ${err.message}`);
        }
        await prompt.pause();
      } else if (answer === '2') {
        const index = await prompt.choose('Which report?', reports.map((report) => report.name));
        if (index === null) continue;
        try {
          execFile('notepad.exe', [reports[index].path], { windowsHide: false }, () => {});
          ui.blank();
          ui.ok('Notepad was opened with the report.');
        } catch (err) {
          ui.error(`Notepad could not be started: ${err.message}`);
        }
        await prompt.pause();
      } else if (answer === '3') {
        try {
          execFile('explorer.exe', [ctx.paths.reports], { windowsHide: false }, () => {});
          ui.blank();
          ui.ok('Explorer window requested.');
        } catch (err) {
          ui.error(`The folder could not be opened: ${err.message}`);
        }
        await prompt.pause();
      } else if (answer === '4') {
        if (ctx.safeMode) {
          ui.blank();
          ui.warning('Safe Mode is enabled - deleting reports is blocked.');
          await prompt.pause();
          continue;
        }
        const index = await prompt.choose(
          'Which report should be deleted?',
          reports.map((report) => ({ label: report.name, hint: system.formatBytes(report.size) }))
        );
        if (index === null) continue;
        const report = reports[index];

        if (ctx.dryRun) {
          ui.blank();
          ui.info(`Dry Run: "${report.name}" would be deleted. Nothing was changed.`);
          await prompt.pause();
          continue;
        }

        const confirmed = await prompt.confirm(`Permanently delete "${report.name}"?`, { danger: true });
        if (confirmed !== true) {
          ui.info('Nothing was deleted.');
          await prompt.pause();
          continue;
        }

        const result = reportManager.deleteReport(report.name);
        ui.blank();
        if (result.ok) ui.ok('Report deleted.');
        else ui.error(`The report could not be deleted: ${result.error}`);
        await prompt.pause();
      } else {
        ui.warning('Enter one of the numbers shown above, or 0 to go back.');
        await prompt.pause();
      }
    }

    return kit.done('Report history closed.');
  },
};
