<?php

namespace App\Service;

use App\Entity\ResearchReport;
use Dompdf\Dompdf;
use Dompdf\Options;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\IOFactory;
use PhpOffice\PhpWord\Style\Font;
use Symfony\Component\Filesystem\Filesystem;

/**
 * Service for exporting research reports to various formats
 */
class ReportExportService
{
    private string $projectDir;

    public function __construct(string $projectDir)
    {
        $this->projectDir = $projectDir;
    }

    /**
     * Export a research report to PDF format
     *
     * @param ResearchReport $report The research report to export
     * @return string The file path to the generated PDF
     * @throws \Exception If the PDF generation fails
     */
    public function exportToPdf(ResearchReport $report): string
    {
        try {
            // Create a new PDF options instance
            $pdfOptions = new Options();
            $pdfOptions->set('defaultFont', 'Arial');
            $pdfOptions->set('isRemoteEnabled', true);

            // Create a new PDF instance
            $dompdf = new Dompdf($pdfOptions);

            // Generate HTML for the PDF
            $html = $this->generateReportHtml($report);

            // Load HTML to Dompdf
            $dompdf->loadHtml($html);

            // Set paper size and orientation
            $dompdf->setPaper('A4', 'portrait');

            // Render the PDF
            $dompdf->render();

            // Create the reports directory if it doesn't exist
            $filesystem = new Filesystem();
            $reportsDir = $this->projectDir . '/var/reports';
            if (!$filesystem->exists($reportsDir)) {
                $filesystem->mkdir($reportsDir);
            }

            // Generate a unique filename
            $filename = sprintf(
                '%s/report_%s_%s.pdf',
                $reportsDir,
                $report->getCompany()->getName(),
                date('Y-m-d_H-i-s')
            );

            // Save the PDF to file
            file_put_contents($filename, $dompdf->output());

            return $filename;
        } catch (\Exception $e) {
            throw new \Exception('Failed to generate PDF: ' . $e->getMessage());
        }
    }

    /**
     * Export a research report to Excel format
     *
     * @param ResearchReport $report The research report to export
     * @return string The file path to the generated Excel file
     * @throws \Exception If the Excel generation fails
     */
    public function exportToExcel(ResearchReport $report): string
    {
        try {
            // Create a new Spreadsheet
            $spreadsheet = new Spreadsheet();

            // Create the overview sheet
            $overviewSheet = $spreadsheet->getActiveSheet();
            $overviewSheet->setTitle('Overview');

            // Add report title
            $overviewSheet->setCellValue('A1', 'Research Report');
            $overviewSheet->setCellValue('A2', $report->getTitle());
            $overviewSheet->getStyle('A1:A2')->getFont()->setBold(true);
            $overviewSheet->getStyle('A2')->getFont()->setSize(14);

            // Add company info
            $overviewSheet->setCellValue('A4', 'Company:');
            $overviewSheet->setCellValue('B4', $report->getCompany()->getName());
            $overviewSheet->setCellValue('A5', 'Report Type:');
            $overviewSheet->setCellValue('B5', $report->getReportType());
            $overviewSheet->setCellValue('A6', 'Generated On:');
            $overviewSheet->setCellValue('B6', $report->getCreatedAt()->format('Y-m-d H:i:s'));
            $overviewSheet->setCellValue('A7', 'Generated By:');
            $overviewSheet->setCellValue('B7', $report->getGeneratedBy() ?: 'Neuron AI');
            $overviewSheet->getStyle('A4:A7')->getFont()->setBold(true);

            // Add executive summary
            $overviewSheet->setCellValue('A9', 'Executive Summary');
            $overviewSheet->getStyle('A9')->getFont()->setBold(true);
            $overviewSheet->setCellValue('A10', $report->getExecutiveSummary());
            $overviewSheet->getStyle('A10')->getAlignment()->setWrapText(true);

            // Company Overview sheet
            $companySheet = $spreadsheet->createSheet();
            $companySheet->setTitle('Company Overview');
            $companySheet->setCellValue('A1', 'Company Overview');
            $companySheet->getStyle('A1')->getFont()->setBold(true);
            $companySheet->setCellValue('A2', $report->getCompanyOverview());
            $companySheet->getStyle('A2')->getAlignment()->setWrapText(true);

            // Industry Analysis sheet
            $industrySheet = $spreadsheet->createSheet();
            $industrySheet->setTitle('Industry Analysis');
            $industrySheet->setCellValue('A1', 'Industry Analysis');
            $industrySheet->getStyle('A1')->getFont()->setBold(true);
            $industrySheet->setCellValue('A2', $report->getIndustryAnalysis());
            $industrySheet->getStyle('A2')->getAlignment()->setWrapText(true);

            // Financial Analysis sheet
            $financialSheet = $spreadsheet->createSheet();
            $financialSheet->setTitle('Financial Analysis');
            $financialSheet->setCellValue('A1', 'Financial Analysis');
            $financialSheet->getStyle('A1')->getFont()->setBold(true);
            $financialSheet->setCellValue('A2', $report->getFinancialAnalysis());
            $financialSheet->getStyle('A2')->getAlignment()->setWrapText(true);

            // Competitive Analysis sheet
            $competitiveSheet = $spreadsheet->createSheet();
            $competitiveSheet->setTitle('Competitive Analysis');
            $competitiveSheet->setCellValue('A1', 'Competitive Analysis');
            $competitiveSheet->getStyle('A1')->getFont()->setBold(true);
            $competitiveSheet->setCellValue('A2', $report->getCompetitiveAnalysis());
            $competitiveSheet->getStyle('A2')->getAlignment()->setWrapText(true);

            // SWOT Analysis sheet
            $swotSheet = $spreadsheet->createSheet();
            $swotSheet->setTitle('SWOT Analysis');
            $swotSheet->setCellValue('A1', 'SWOT Analysis');
            $swotSheet->getStyle('A1')->getFont()->setBold(true);
            $swotSheet->setCellValue('A2', $report->getSwotAnalysis());
            $swotSheet->getStyle('A2')->getAlignment()->setWrapText(true);

            // Investment Highlights sheet
            $investmentSheet = $spreadsheet->createSheet();
            $investmentSheet->setTitle('Investment Highlights');
            $investmentSheet->setCellValue('A1', 'Investment Highlights');
            $investmentSheet->getStyle('A1')->getFont()->setBold(true);
            $investmentSheet->setCellValue('A2', $report->getInvestmentHighlights());
            $investmentSheet->getStyle('A2')->getAlignment()->setWrapText(true);

            // Risks & Challenges sheet
            $risksSheet = $spreadsheet->createSheet();
            $risksSheet->setTitle('Risks & Challenges');
            $risksSheet->setCellValue('A1', 'Risks & Challenges');
            $risksSheet->getStyle('A1')->getFont()->setBold(true);
            $risksSheet->setCellValue('A2', $report->getRisksAndChallenges());
            $risksSheet->getStyle('A2')->getAlignment()->setWrapText(true);

            // Conclusion sheet
            $conclusionSheet = $spreadsheet->createSheet();
            $conclusionSheet->setTitle('Conclusion');
            $conclusionSheet->setCellValue('A1', 'Conclusion');
            $conclusionSheet->getStyle('A1')->getFont()->setBold(true);
            $conclusionSheet->setCellValue('A2', $report->getConclusion());
            $conclusionSheet->getStyle('A2')->getAlignment()->setWrapText(true);

            // Auto-size columns for all sheets
            foreach ($spreadsheet->getAllSheets() as $sheet) {
                foreach (range('A', 'B') as $column) {
                    $sheet->getColumnDimension($column)->setAutoSize(true);
                }
                $sheet->getRowDimension(2)->setRowHeight(100);
            }

            // Create the reports directory if it doesn't exist
            $filesystem = new Filesystem();
            $reportsDir = $this->projectDir . '/var/reports';
            if (!$filesystem->exists($reportsDir)) {
                $filesystem->mkdir($reportsDir);
            }

            // Generate a unique filename
            $filename = sprintf(
                '%s/report_%s_%s.xlsx',
                $reportsDir,
                $report->getCompany()->getName(),
                date('Y-m-d_H-i-s')
            );

            // Save the Excel file
            $writer = new Xlsx($spreadsheet);
            $writer->save($filename);

            return $filename;
        } catch (\Exception $e) {
            throw new \Exception('Failed to generate Excel file: ' . $e->getMessage());
        }
    }

    /**
     * Export a research report to Word format
     *
     * @param ResearchReport $report The research report to export
     * @return string The file path to the generated Word file
     * @throws \Exception If the Word generation fails
     */
    public function exportToWord(ResearchReport $report): string
    {
        try {
            // Create new PhpWord object
            $phpWord = new PhpWord();

            // Set default font
            $phpWord->setDefaultFontName('Arial');
            $phpWord->setDefaultFontSize(12);

            // Add title page
            $section = $phpWord->addSection();

            // Add title
            $section->addText(
                $report->getTitle(),
                ['bold' => true, 'size' => 24],
                ['alignment' => 'center', 'spaceAfter' => 240]
            );

            // Add company name
            $section->addText(
                $report->getCompany()->getName(),
                ['bold' => true, 'size' => 18],
                ['alignment' => 'center', 'spaceAfter' => 120]
            );

            // Add report type
            $section->addText(
                'Report Type: ' . $report->getReportType(),
                ['size' => 14],
                ['alignment' => 'center', 'spaceAfter' => 120]
            );

            // Add generation date
            $section->addText(
                'Generated on: ' . $report->getCreatedAt()->format('F j, Y'),
                ['size' => 14],
                ['alignment' => 'center', 'spaceAfter' => 240]
            );

            // Add page break
            $section->addPageBreak();

            // Add sections

            // Executive Summary
            $section->addText('Executive Summary', ['bold' => true, 'size' => 16], ['spaceAfter' => 120]);
            $textLines = explode("\n", $report->getExecutiveSummary());
            foreach ($textLines as $line) {
                if (trim($line) !== '') {
                    $section->addText(trim($line), [], ['spaceAfter' => 120]);
                }
            }
            $section->addPageBreak();

            // Company Overview
            $section->addText('Company Overview', ['bold' => true, 'size' => 16], ['spaceAfter' => 120]);
            $textLines = explode("\n", $report->getCompanyOverview());
            foreach ($textLines as $line) {
                if (trim($line) !== '') {
                    $section->addText(trim($line), [], ['spaceAfter' => 120]);
                }
            }
            $section->addPageBreak();

            // Industry Analysis
            $section->addText('Industry Analysis', ['bold' => true, 'size' => 16], ['spaceAfter' => 120]);
            $textLines = explode("\n", $report->getIndustryAnalysis());
            foreach ($textLines as $line) {
                if (trim($line) !== '') {
                    $section->addText(trim($line), [], ['spaceAfter' => 120]);
                }
            }
            $section->addPageBreak();

            // Financial Analysis
            $section->addText('Financial Analysis', ['bold' => true, 'size' => 16], ['spaceAfter' => 120]);
            $textLines = explode("\n", $report->getFinancialAnalysis());
            foreach ($textLines as $line) {
                if (trim($line) !== '') {
                    $section->addText(trim($line), [], ['spaceAfter' => 120]);
                }
            }
            $section->addPageBreak();

            // Competitive Analysis
            $section->addText('Competitive Analysis', ['bold' => true, 'size' => 16], ['spaceAfter' => 120]);
            $textLines = explode("\n", $report->getCompetitiveAnalysis());
            foreach ($textLines as $line) {
                if (trim($line) !== '') {
                    $section->addText(trim($line), [], ['spaceAfter' => 120]);
                }
            }
            $section->addPageBreak();

            // SWOT Analysis
            $section->addText('SWOT Analysis', ['bold' => true, 'size' => 16], ['spaceAfter' => 120]);
            $textLines = explode("\n", $report->getSwotAnalysis());
            foreach ($textLines as $line) {
                if (trim($line) !== '') {
                    $section->addText(trim($line), [], ['spaceAfter' => 120]);
                }
            }
            $section->addPageBreak();

            // Investment Highlights
            $section->addText('Investment Highlights', ['bold' => true, 'size' => 16], ['spaceAfter' => 120]);
            $textLines = explode("\n", $report->getInvestmentHighlights());
            foreach ($textLines as $line) {
                if (trim($line) !== '') {
                    $section->addText(trim($line), [], ['spaceAfter' => 120]);
                }
            }
            $section->addPageBreak();

            // Risks and Challenges
            $section->addText('Risks and Challenges', ['bold' => true, 'size' => 16], ['spaceAfter' => 120]);
            $textLines = explode("\n", $report->getRisksAndChallenges());
            foreach ($textLines as $line) {
                if (trim($line) !== '') {
                    $section->addText(trim($line), [], ['spaceAfter' => 120]);
                }
            }
            $section->addPageBreak();

            // Conclusion
            $section->addText('Conclusion', ['bold' => true, 'size' => 16], ['spaceAfter' => 120]);
            $textLines = explode("\n", $report->getConclusion());
            foreach ($textLines as $line) {
                if (trim($line) !== '') {
                    $section->addText(trim($line), [], ['spaceAfter' => 120]);
                }
            }

            // Add footer
            $footer = $section->addFooter();
            $footer->addText(
                'Generated by Neuron AI | For research purposes only | Not investment advice',
                ['size' => 8],
                ['alignment' => 'center']
            );

            // Create the reports directory if it doesn't exist
            $filesystem = new Filesystem();
            $reportsDir = $this->projectDir . '/var/reports';
            if (!$filesystem->exists($reportsDir)) {
                $filesystem->mkdir($reportsDir);
            }

            // Generate a unique filename
            $filename = sprintf(
                '%s/report_%s_%s.docx',
                $reportsDir,
                $report->getCompany()->getName(),
                date('Y-m-d_H-i-s')
            );

            // Save the Word document
            $writer = IOFactory::createWriter($phpWord, 'Word2007');
            $writer->save($filename);

            return $filename;
        } catch (\Exception $e) {
            throw new \Exception('Failed to generate Word document: ' . $e->getMessage());
        }
    }

    /**
     * Generate HTML for a research report
     *
     * @param ResearchReport $report The research report
     * @return string The HTML content
     */
    private function generateReportHtml(ResearchReport $report): string
    {
        $company = $report->getCompany();

        $html = '
        <!DOCTYPE html>
        <html>
        <head>
            <meta charset="UTF-8">
            <title>' . htmlspecialchars($report->getTitle()) . '</title>
            <style>
                body {
                    font-family: Arial, sans-serif;
                    margin: 0;
                    padding: 20px;
                    color: #333;
                }
                .header {
                    text-align: center;
                    margin-bottom: 30px;
                }
                .report-title {
                    font-size: 24px;
                    font-weight: bold;
                    margin-bottom: 10px;
                }
                .company-name {
                    font-size: 18px;
                    margin-bottom: 5px;
                }
                .report-date {
                    font-size: 14px;
                    color: #666;
                    margin-bottom: 20px;
                }
                .section {
                    margin-bottom: 20px;
                }
                .section-title {
                    font-size: 18px;
                    font-weight: bold;
                    margin-bottom: 10px;
                    padding-bottom: 5px;
                    border-bottom: 1px solid #ddd;
                }
                .section-content {
                    line-height: 1.5;
                    text-align: justify;
                }
                .footer {
                    margin-top: 50px;
                    text-align: center;
                    font-size: 12px;
                    color: #666;
                }
                .page-break {
                    page-break-after: always;
                }
            </style>
        </head>
        <body>
            <div class="header">
                <div class="report-title">' . htmlspecialchars($report->getTitle()) . '</div>
                <div class="company-name">' . htmlspecialchars($company->getName()) . '</div>
                <div class="report-date">Report generated on ' . $report->getCreatedAt()->format('F j, Y') . '</div>
                <div class="report-type">Report type: ' . htmlspecialchars($report->getReportType()) . '</div>
            </div>

            <div class="section">
                <div class="section-title">Executive Summary</div>
                <div class="section-content">' . nl2br(htmlspecialchars($report->getExecutiveSummary())) . '</div>
            </div>

            <div class="section">
                <div class="section-title">Company Overview</div>
                <div class="section-content">' . nl2br(htmlspecialchars($report->getCompanyOverview())) . '</div>
            </div>

            <div class="section page-break">
                <div class="section-title">Industry Analysis</div>
                <div class="section-content">' . nl2br(htmlspecialchars($report->getIndustryAnalysis())) . '</div>
            </div>

            <div class="section">
                <div class="section-title">Financial Analysis</div>
                <div class="section-content">' . nl2br(htmlspecialchars($report->getFinancialAnalysis())) . '</div>
            </div>

            <div class="section page-break">
                <div class="section-title">Competitive Analysis</div>
                <div class="section-content">' . nl2br(htmlspecialchars($report->getCompetitiveAnalysis())) . '</div>
            </div>

            <div class="section">
                <div class="section-title">SWOT Analysis</div>
                <div class="section-content">' . nl2br(htmlspecialchars($report->getSwotAnalysis())) . '</div>
            </div>

            <div class="section page-break">
                <div class="section-title">Investment Highlights</div>
                <div class="section-content">' . nl2br(htmlspecialchars($report->getInvestmentHighlights())) . '</div>
            </div>

            <div class="section">
                <div class="section-title">Risks and Challenges</div>
                <div class="section-content">' . nl2br(htmlspecialchars($report->getRisksAndChallenges())) . '</div>
            </div>

            <div class="section">
                <div class="section-title">Conclusion</div>
                <div class="section-content">' . nl2br(htmlspecialchars($report->getConclusion())) . '</div>
            </div>

            <div class="footer">
                Generated by Neuron AI | For research purposes only | Not investment advice
            </div>
        </body>
        </html>
        ';

        return $html;
    }
}
