<?php

namespace UltraguardPro\modules\compliance_reports;

if ( ! defined( 'ABSPATH' ) ) { exit; }

use UltraguardPro\Plugin;
use UltraguardPro\core\BaseController;

class ReportBuilderEngine extends BaseController {

    public function __construct( Plugin $plugin ) {
        parent::__construct( $plugin );
    }

    public function build_report( string $type, array $options ): array {
        $table     = $this->plugin->modules->get_db_tables()->get_table( 'generated_reports' );
        $user      = wp_get_current_user();
        $title     = sanitize_text_field( $options['title'] ?? ucfirst( str_replace( '_', ' ', $type ) ) . ' Report' );
        // Always generate as HTML — PDF conversion is handled by the browser's
        // built-in Print → Save as PDF functionality. TCPDF has been removed.
        $format    = 'html';
        $date_from = sanitize_text_field( $options['date_from'] ?? gmdate( 'Y-m-01' ) );
        $date_to   = sanitize_text_field( $options['date_to'] ?? gmdate( 'Y-m-d' ) );
        $sections  = isset( $options['sections'] ) && is_array( $options['sections'] ) ? array_values( array_unique( array_map( 'sanitize_key', $options['sections'] ) ) ) : $this->get_default_sections_for_type( $type );

        $row = [
            'report_type'     => sanitize_key( $type ),
            'report_title'    => $title,
            'date_range_from' => $date_from,
            'date_range_to'   => $date_to,
            'format'          => $format,
            'file_path'       => '',
            'file_size'       => 0,
            'generated_by'    => get_current_user_id(),
            'status'          => 'generating',
            'sections'        => wp_json_encode( $sections ),
            'error_message'   => '',
        ];

        $report_id = $table && method_exists( $table, 'insert' ) ? (int) $table->insert( $row ) : 0;

        try {
            $meta = [
                'title'             => $title,
                'date_from'         => $date_from,
                'date_to'           => $date_to,
                'generated_at'      => current_time( 'mysql', true ),
                'generated_by_name' => $user && $user->exists() ? $user->display_name : __( 'System', 'ultraguard-security-suite' ),
                'format'            => $format,
            ];
            $collected = $this->collect_sections( $type, [
                'date_from' => $date_from,
                'date_to'   => $date_to,
                'sections'  => $sections,
            ], $meta );

            $output = $this->render_html_report( $collected, $meta );
            $path   = $this->write_report_file( $report_id, $title, 'html', $output );

            if ( $table && $report_id && method_exists( $table, 'update' ) ) {
                $table->update( $report_id, [
                    'status'    => 'complete',
                    'file_path' => $path,
                    'file_size' => file_exists( $path ) ? (int) filesize( $path ) : 0,
                ] );
            }

            return [
                'success'   => true,
                'report_id' => $report_id,
                'file_path' => $path,
                'format'    => 'html',
            ];
        } catch ( \Throwable $e ) {
            if ( $table && $report_id && method_exists( $table, 'update' ) ) {
                $table->update( $report_id, [
                    'status'        => 'failed',
                    'error_message' => $e->getMessage(),
                ] );
            }

            $this->logError( 'ComplianceReports', 'Report build failed.', [ 'exception' => $e->getMessage() ] );

            return [
                'success'   => false,
                'report_id' => $report_id,
                'message'   => $e->getMessage(),
            ];
        }
    }

    public function collect_sections( string $type, array $options = [], array $meta = [] ): array {
        return (array) apply_filters( 'ultraguard_pro/compliance/collect_data', [], $type, $options, $meta );
    }

    public function render_html_report( array $sections, array $meta ): string {
        $watermark = sanitize_text_field( (string) $this->plugin->settings->get_option( 'compliance_reports_watermark', '' ) );
        $org_name  = sanitize_text_field( (string) $this->plugin->settings->get_option( 'compliance_reports_organization_name', get_bloginfo( 'name' ) ) );
        $contact   = sanitize_text_field( (string) $this->plugin->settings->get_option( 'compliance_reports_contact_name', '' ) );
        $email     = sanitize_email( (string) $this->plugin->settings->get_option( 'compliance_reports_contact_email', get_option( 'admin_email', '' ) ) );

        $css = '
/* ── Base ────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { font-size: 14px; }
body {
    font-family: "Segoe UI", Arial, sans-serif;
    color: #172033;
    margin: 32px 40px;
    line-height: 1.6;
    background: #fff;
}
h1 { font-size: 22px; color: #0f172a; margin: 0 0 8px; font-weight: 700; }
h2 { font-size: 15px; color: #1e3a5f; margin: 24px 0 10px; font-weight: 700;
     border-bottom: 2px solid #e2e8f0; padding-bottom: 6px; }
h3 { font-size: 13px; color: #334155; margin: 16px 0 8px; font-weight: 600; }
p  { margin: 0 0 8px; }

/* ── Meta block ──────────────────────────────────────────── */
.report-header {
    display: flex; align-items: flex-start; gap: 24px;
    margin-bottom: 28px; padding-bottom: 20px;
    border-bottom: 3px solid #3b82f6;
}
.report-header-logo { flex-shrink: 0; }
.report-header-logo .shield {
    width: 48px; height: 48px; background: #1e3a5f;
    border-radius: 10px; display: flex; align-items: center;
    justify-content: center; font-size: 26px; color: #fff;
}
.report-header-text { flex: 1; }
.report-header-text h1 { margin-bottom: 4px; }
.report-header-text .subtitle { font-size: 12px; color: #64748b; }
.meta {
    margin-bottom: 28px; padding: 16px 20px;
    background: #f8fafc; border: 1px solid #e4e7ec;
    border-radius: 8px; display: grid;
    grid-template-columns: repeat(2, 1fr); gap: 6px 24px;
}
.meta p { margin: 0; font-size: 13px; }
.meta strong { color: #374151; }

/* ── Section ─────────────────────────────────────────────── */
.section { margin-bottom: 32px; }

/* ── Tables ──────────────────────────────────────────────── */
table {
    width: 100%; border-collapse: collapse;
    margin: 12px 0; font-size: 12.5px;
}
th, td {
    border: 1px solid #d0d5dd;
    padding: 8px 12px; text-align: left;
}
th {
    background: #f1f5f9; color: #374151;
    font-weight: 600; font-size: 12px;
    text-transform: uppercase; letter-spacing: 0.4px;
}
tr:nth-child(even) td { background: #f9fafb; }

/* ── Badges ──────────────────────────────────────────────── */
.badge-pass    { color: #067647; font-weight: 700; }
.badge-partial { color: #b54708; font-weight: 700; }
.badge-fail    { color: #b42318; font-weight: 700; }
.badge-info    { color: #1d4ed8; font-weight: 700; }

/* ── Watermark ───────────────────────────────────────────── */
.watermark {
    position: fixed; top: 42%; left: 18%;
    font-size: 80px; color: rgba(15,23,42,0.04);
    transform: rotate(-20deg); z-index: -1;
    font-weight: 900; pointer-events: none;
    white-space: nowrap;
}

/* ── Footer ──────────────────────────────────────────────── */
.report-footer {
    margin-top: 40px; padding-top: 16px;
    border-top: 1px solid #e2e8f0;
    font-size: 11px; color: #94a3b8;
    display: flex; justify-content: space-between;
}

/* ── Print-specific overrides ────────────────────────────── */
@media print {
    body { margin: 0; font-size: 12px; }
    h1 { font-size: 18px; }
    h2 { font-size: 13px; }
    .meta { grid-template-columns: repeat(2, 1fr); }
    tr { page-break-inside: avoid; }
    .section { page-break-inside: avoid; }
    h2, h3 { page-break-after: avoid; }
    table { page-break-inside: auto; }
    @page {
        size: A4;
        margin: 16mm 14mm 20mm 14mm;
    }
    @page :first { margin-top: 20mm; }
}
';

        $title       = esc_html( $meta['title'] ?? 'Compliance Report' );
        $date_from   = esc_html( $meta['date_from'] ?? '' );
        $date_to     = esc_html( $meta['date_to'] ?? '' );
        $gen_by      = esc_html( $meta['generated_by_name'] ?? '' );
        $gen_at      = esc_html( current_time( 'Y-m-d H:i' ) );
        $contact_str = esc_html( trim( $contact . ( $contact && $email ? ' — ' : '' ) . $email ) );

        $html  = '<!doctype html><html lang="en"><head>';
        $html .= '<meta charset="utf-8">';
        $html .= '<meta name="viewport" content="width=device-width,initial-scale=1">';
        $html .= '<title>' . $title . '</title>';
        $html .= '<style>' . $css . '</style>';
        $html .= '</head><body>';

        if ( '' !== $watermark ) {
            $html .= '<div class="watermark">' . esc_html( $watermark ) . '</div>';
        }

        // Report header
        $html .= '<div class="report-header">';
        $html .= '<div class="report-header-logo"><div class="shield">🛡</div></div>';
        $html .= '<div class="report-header-text">';
        $html .= '<h1>' . $title . '</h1>';
        $html .= '<div class="subtitle">UltraGuard Pro Security Compliance Report &mdash; ' . esc_html( $org_name ) . '</div>';
        $html .= '</div></div>';

        // Meta block
        $html .= '<div class="meta">';
        $html .= '<p><strong>Organisation:</strong> ' . esc_html( $org_name ) . '</p>';
        $html .= '<p><strong>Site URL:</strong> ' . esc_html( home_url() ) . '</p>';
        $html .= '<p><strong>Report Period:</strong> ' . $date_from . ' &rarr; ' . $date_to . '</p>';
        $html .= '<p><strong>Generated:</strong> ' . $gen_at . '</p>';
        $html .= '<p><strong>Generated By:</strong> ' . $gen_by . '</p>';
        if ( '' !== $contact_str ) {
            $html .= '<p><strong>Contact:</strong> ' . $contact_str . '</p>';
        }
        $html .= '</div>';

        // Sections
        foreach ( $sections as $section ) {
            $html .= '<div class="section">';
            $html .= '<h2>' . esc_html( $section['title'] ?? 'Section' ) . '</h2>';
            $html .= $this->render_section_content( $section['content'] ?? [] );
            $html .= '</div>';
        }

        // Footer
        $html .= '<div class="report-footer">';
        $html .= '<span>UltraGuard Pro &mdash; ' . esc_html( home_url() ) . '</span>';
        $html .= '<span>Generated ' . $gen_at . '</span>';
        $html .= '</div>';

        $html .= '</body></html>';

        return $html;
    }

    public function render_pdf_report( array $sections, array $meta ): string {
        $html = $this->render_html_report( $sections, $meta );

        $tcpdf_path = __DIR__ . '/vendor/TCPDF-main/tcpdf.php';
        if ( file_exists( $tcpdf_path ) ) {
            require_once $tcpdf_path;

            if ( class_exists( '\TCPDF', false ) ) {
                $pdf = new \TCPDF( PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false );
                $pdf->SetCreator( 'UltraGuard Pro' );
                $pdf->SetAuthor( 'UltraGuard Pro' );
                $pdf->SetTitle( (string) ( $meta['title'] ?? 'Compliance Report' ) );
                $pdf->SetSubject( 'Security Compliance Report' );
                $pdf->SetPrintHeader( false );
                $pdf->SetPrintFooter( false );
                $pdf->SetMargins( 14, 16, 14 );
                $pdf->SetAutoPageBreak( true, 16 );
                $pdf->setImageScale( PDF_IMAGE_SCALE_RATIO );
                $pdf->SetFont( 'helvetica', '', 10 );
                $pdf->AddPage();
                $pdf->writeHTML( $html, true, false, true, false, '' );

                return $pdf->Output( '', 'S' );
            }
        }

        if ( class_exists( '\\Mpdf\\Mpdf' ) ) {
            $tmp_path = wp_tempnam( 'ultraguard-report.pdf' );
            $mpdf     = new \Mpdf\Mpdf();
            $mpdf->WriteHTML( $html );
            $mpdf->Output( $tmp_path, \Mpdf\Output\Destination::FILE );
            return (string) file_get_contents( $tmp_path );
        }

        return $this->build_basic_pdf( wp_strip_all_tags( preg_replace( '/<\s*\/p\s*>|<\s*br\s*\/?>|<\s*\/tr\s*>|<\s*\/h[1-6]\s*>/i', "\n", $html ) ) );
    }

    public function get_available_sections(): array {
        return (array) apply_filters( 'ultraguard_pro/compliance/available_sections', [] );
    }

    public function get_gdpr_sections(): array {
        return [ 'cover_page', 'executive_summary', 'active_security_controls', 'compliance_checklist', 'audit_log', 'authentication_events' ];
    }

    public function get_pci_sections(): array {
        return [ 'cover_page', 'executive_summary', 'active_security_controls', 'compliance_checklist', 'firewall_rules', 'vulnerability_findings', 'malware_scan_history' ];
    }

    public function get_default_sections_for_type( string $type ): array {
        switch ( $type ) {
            case 'gdpr':
                return $this->get_gdpr_sections();
            case 'pci_dss':
                return $this->get_pci_sections();
            case 'custom':
                return array_keys( $this->get_available_sections() );
            default:
                return [ 'cover_page', 'executive_summary', 'active_security_controls', 'compliance_checklist', 'audit_log', 'firewall_rules', 'malware_scan_history', 'vulnerability_findings', 'authentication_events', 'hardening_checks' ];
        }
    }

    public function get_file_url( string $path ): string {
        $upload = wp_upload_dir();
        $path   = wp_normalize_path( $path );
        $base   = wp_normalize_path( $upload['basedir'] ?? '' );

        if ( '' !== $base && 0 === strpos( $path, $base ) ) {
            $relative = ltrim( substr( $path, strlen( $base ) ), '/\\' );
            return trailingslashit( $upload['baseurl'] ) . str_replace( '\\', '/', $relative );
        }

        return '';
    }

    private function write_report_file( int $report_id, string $title, string $format, string $contents ): string {
        $upload = wp_upload_dir();
        $dir    = trailingslashit( $upload['basedir'] ) . 'ultraguard-reports';
        wp_mkdir_p( $dir );

        $ext      = 'pdf' === $format ? 'pdf' : 'html';
        $filename = sanitize_title( $title ) . '-' . ( $report_id ?: time() ) . '.' . $ext;
        $path     = trailingslashit( $dir ) . $filename;

        file_put_contents( $path, $contents );

        return $path;
    }

    private function build_basic_pdf( string $text ): string {
        $lines        = preg_split( '/\r\n|\r|\n/', html_entity_decode( $text, ENT_QUOTES, 'UTF-8' ) );
        $wrapped      = [];
        $max_per_line = 95;

        foreach ( (array) $lines as $line ) {
            $clean = trim( preg_replace( '/\s+/', ' ', $line ) );
            if ( '' === $clean ) {
                $wrapped[] = '';
                continue;
            }

            foreach ( str_split( $clean, $max_per_line ) as $part ) {
                $wrapped[] = $part;
            }
        }

        $pages   = [];
        $current = [];
        $y       = 780;

        foreach ( $wrapped as $line ) {
            if ( $y < 60 ) {
                $pages[] = $current;
                $current = [];
                $y       = 780;
            }

            $escaped    = str_replace( [ '\\', '(', ')' ], [ '\\\\', '\\(', '\\)' ], $line );
            $current[]  = sprintf( 'BT /F1 10 Tf 40 %d Td (%s) Tj ET', $y, $escaped );
            $y         -= 14;
        }

        if ( ! empty( $current ) ) {
            $pages[] = $current;
        }

        if ( empty( $pages ) ) {
            $pages[] = [ 'BT /F1 10 Tf 40 780 Td (Compliance Report) Tj ET' ];
        }

        $objects  = [];
        $add      = static function ( string $body ) use ( &$objects ): int {
            $objects[] = $body;
            return count( $objects );
        };

        $catalog_id = $add( '' );
        $pages_id   = $add( '' );
        $font_id    = $add( '<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>' );

        $kids = [];

        foreach ( $pages as $page_lines ) {
            $stream      = implode( "\n", $page_lines );
            $content_id  = $add( '<< /Length ' . strlen( $stream ) . " >>\nstream\n" . $stream . "\nendstream" );
            $page_id     = $add( '<< /Type /Page /Parent ' . $pages_id . ' 0 R /MediaBox [0 0 595 842] /Resources << /Font << /F1 ' . $font_id . ' 0 R >> >> /Contents ' . $content_id . ' 0 R >>' );
            $kids[]      = $page_id . ' 0 R';
        }

        $objects[ $catalog_id - 1 ] = '<< /Type /Catalog /Pages ' . $pages_id . ' 0 R >>';
        $objects[ $pages_id - 1 ]   = '<< /Type /Pages /Kids [' . implode( ' ', $kids ) . '] /Count ' . count( $kids ) . ' >>';

        $pdf      = "%PDF-1.4\n";
        $offsets  = [ 0 ];
        $count    = count( $objects );

        for ( $i = 0; $i < $count; $i++ ) {
            $offsets[] = strlen( $pdf );
            $pdf      .= ( $i + 1 ) . " 0 obj\n" . $objects[ $i ] . "\nendobj\n";
        }

        $xref_offset = strlen( $pdf );
        $pdf        .= "xref\n0 " . ( $count + 1 ) . "\n";
        $pdf        .= "0000000000 65535 f \n";

        for ( $i = 1; $i <= $count; $i++ ) {
            $pdf .= sprintf( "%010d 00000 n \n", $offsets[ $i ] );
        }

        $pdf .= "trailer\n<< /Size " . ( $count + 1 ) . " /Root 1 0 R >>\nstartxref\n" . $xref_offset . "\n%%EOF";

        return $pdf;
    }

    private function render_section_content( $content ): string {
        if ( is_string( $content ) ) {
            return '<p>' . esc_html( $content ) . '</p>';
        }

        if ( ! is_array( $content ) ) {
            return '<p>' . esc_html__( 'No data available.', 'ultraguard-security-suite' ) . '</p>';
        }

        $first = reset( $content );
        if ( is_array( $first ) ) {
            $headers = array_keys( $first );
            $html    = '<table><thead><tr>';
            foreach ( $headers as $header ) {
                $html .= '<th>' . esc_html( ucwords( str_replace( '_', ' ', (string) $header ) ) ) . '</th>';
            }
            $html .= '</tr></thead><tbody>';

            foreach ( $content as $row ) {
                $html .= '<tr>';
                foreach ( $headers as $header ) {
                    $value = $row[ $header ] ?? '';
                    $class = '';
                    if ( 'status' === $header ) {
                        $class = ' class="badge-' . esc_attr( $this->normalize_status_class( (string) $value ) ) . '"';
                    }
                    $html .= '<td' . $class . '>' . esc_html( is_scalar( $value ) ? (string) $value : wp_json_encode( $value ) ) . '</td>';
                }
                $html .= '</tr>';
            }

            $html .= '</tbody></table>';
            return $html;
        }

        $html = '<table><tbody>';
        foreach ( $content as $key => $value ) {
            $html .= '<tr><th>' . esc_html( ucwords( str_replace( '_', ' ', (string) $key ) ) ) . '</th><td>' . esc_html( is_scalar( $value ) ? (string) $value : wp_json_encode( $value ) ) . '</td></tr>';
        }
        $html .= '</tbody></table>';

        return $html;
    }

    private function normalize_status_class( string $status ): string {
        if ( in_array( $status, [ 'pass', 'clean', 'complete' ], true ) ) {
            return 'pass';
        }
        if ( in_array( $status, [ 'partial', 'warning', 'suspicious' ], true ) ) {
            return 'partial';
        }
        return 'fail';
    }
}
