<?php

namespace UltraguardPro\modules\compliance_reports\ajax;

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

// phpcs:disable WordPress.Security.NonceVerification.Missing -- Compliance Reports AJAX handlers are registered through the shared protected AJAX framework.

use UltraguardPro\modules\compliance_reports\ReportBuilderEngine;
use UltraguardPro\modules\core\AbstractAjaxHandler;

class ComplianceReportsAjax extends AbstractAjaxHandler {

    protected const NONCE = 'ultraguard_admin_nonce';

    private ?ReportBuilderEngine $engine = null;

    public function register(): void {
        $this->register_actions( [
            'ultraguard_compliance_generate'              => [ $this, 'handle_generate' ],
            'ultraguard_compliance_get_status'            => [ $this, 'handle_get_status' ],
            'ultraguard_compliance_list_reports'          => [ $this, 'handle_list_reports' ],
            'ultraguard_compliance_delete_report'         => [ $this, 'handle_delete_report' ],
            'ultraguard_save_compliance_reports_settings' => [ $this, 'handle_save_settings' ],
        ] );

        $this->add_priv_action( 'ultraguard_compliance_download_report', [ $this, 'handle_download_report' ] );
    }

    public function handle_generate(): void {
        $this->require_pro_feature( 'compliance_reports', __( 'generate compliance reports', 'ultraguard-security-suite' ) );
        $type      = sanitize_key( wp_unslash( $_POST['report_type'] ?? 'security_audit' ) );
        $title     = sanitize_text_field( wp_unslash( $_POST['report_title'] ?? '' ) );
        $date_from = sanitize_text_field( wp_unslash( $_POST['date_from'] ?? gmdate( 'Y-m-01' ) ) );
        $date_to   = sanitize_text_field( wp_unslash( $_POST['date_to'] ?? gmdate( 'Y-m-d' ) ) );
        $sections  = isset( $_POST['sections'] ) ? array_map( 'sanitize_key', (array) wp_unslash( $_POST['sections'] ) ) : $this->engine()->get_default_sections_for_type( $type );

        // Always generate as HTML — browser print handles PDF conversion.
        // TCPDF is no longer used; format is stored as 'html' for all reports.
        $result = $this->engine()->build_report( $type, [
            'title'     => '' !== $title ? $title : ucfirst( str_replace( '_', ' ', $type ) ) . ' Report',
            'date_from' => $date_from,
            'date_to'   => $date_to,
            'format'    => 'html',
            'sections'  => $sections,
        ] );

        if ( empty( $result['success'] ) ) {
            $this->send_error( $result['message'] ?? __( 'Report generation failed.', 'ultraguard-security-suite' ), 500, 'generation_failed' );
        }

        // Return only the report ID and a page-reload instruction.
        // The JS will reload the dashboard; the new row in the table will have
        // a "Print / Download PDF" button that opens the print view.
        // No file_url or download_url in the response — browser handles printing.
        $this->send_success( [
            'message'   => __( 'Report generated. Use the Print / Download PDF button to save it.', 'ultraguard-security-suite' ),
            'report_id' => $result['report_id'],
            'reload'    => true,
        ] );
    }

    public function handle_get_status(): void {
        $report = $this->get_report( absint( $_POST['report_id'] ?? 0 ) );
        if ( empty( $report ) ) {
            $this->send_error( __( 'Report not found.', 'ultraguard-security-suite' ), 404, 'not_found' );
        }

        $this->send_success( [ 'report' => $report ] );
    }

    public function handle_list_reports(): void {
        $table   = $this->t( 'generated_reports' );
        $reports = $table ? $table->get_recent( max( 1, min( 100, absint( $_POST['limit'] ?? 30 ) ) ) ) : [];
        $this->send_success( [ 'reports' => $reports ] );
    }

    public function handle_download_report(): void {
        $this->verify_cap( 'manage_options' );

        $report = $this->get_report( absint( $_POST['report_id'] ?? 0 ) );
        if ( empty( $report ) ) {
            $report = $this->get_report( absint( $_GET['report_id'] ?? 0 ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Fallback download route is capability-gated and reads a scalar id only.
        }

        if ( empty( $report['file_path'] ) || ! file_exists( $report['file_path'] ) ) {
            $this->send_error( __( 'The report file is unavailable.', 'ultraguard-security-suite' ), 404, 'missing_file' );
        }

        $mime = 'pdf' === ( $report['format'] ?? 'html' ) && 'pdf' === strtolower( pathinfo( $report['file_path'], PATHINFO_EXTENSION ) ) ? 'application/pdf' : 'text/html; charset=utf-8';
        nocache_headers();
        header( 'Content-Type: ' . $mime );
        header( 'Content-Disposition: attachment; filename="' . basename( $report['file_path'] ) . '"' );
        header( 'Content-Length: ' . filesize( $report['file_path'] ) );
        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_readfile -- direct streaming of a generated local report file to the browser.
        readfile( $report['file_path'] );
        exit;
    }

    public function handle_delete_report(): void {
        $this->require_pro_feature( 'compliance_reports', __( 'manage generated compliance reports', 'ultraguard-security-suite' ) );
        $report_id = absint( $_POST['report_id'] ?? 0 );
        $report    = $this->get_report( $report_id );
        if ( empty( $report ) ) {
            $this->send_error( __( 'Report not found.', 'ultraguard-security-suite' ), 404, 'not_found' );
        }

        if ( ! empty( $report['file_path'] ) && file_exists( $report['file_path'] ) ) {
            wp_delete_file( $report['file_path'] );
        }

        $table = $this->t( 'generated_reports' );
        if ( ! $table || ! method_exists( $table, 'delete' ) || ! $table->delete( $report_id ) ) {
            $this->send_error( __( 'Could not delete the report.', 'ultraguard-security-suite' ), 500, 'delete_failed' );
        }

        $this->send_success( [ 'message' => __( 'Report deleted.', 'ultraguard-security-suite' ) ] );
    }

    public function handle_save_settings(): void {
        $this->require_pro_feature( 'compliance_reports', __( 'save Compliance Reports settings', 'ultraguard-security-suite' ) );

        $data = $this->sanitize_fields( (array) wp_unslash( $_POST ), [
            'compliance_reports_organization_name' => [ 'type' => 'text', 'default' => get_bloginfo( 'name' ) ],
            'compliance_reports_contact_name'      => [ 'type' => 'text', 'default' => '' ],
            'compliance_reports_contact_email'     => [ 'type' => 'email', 'default' => get_option( 'admin_email', '' ) ],
            'compliance_reports_include_logo'      => [ 'type' => 'bool', 'default' => false ],
            'compliance_reports_logo_url'          => [ 'type' => 'text', 'default' => '' ],
            'compliance_reports_auto_monthly'      => [ 'type' => 'bool', 'default' => false ],
            'compliance_reports_email_monthly'     => [ 'type' => 'bool', 'default' => false ],
            'compliance_reports_watermark'         => [ 'type' => 'text', 'default' => '' ],
            'compliance_reports_include_raw_logs'  => [ 'type' => 'bool', 'default' => false ],
        ] );

        $ok = $this->plugin->settings->save_module_settings( 'compliance_reports', $data );
        if ( ! $ok ) {
            $this->send_error( __( 'Failed to save Compliance Reports settings.', 'ultraguard-security-suite' ), 500, 'save_failed' );
        }

        $module = $this->plugin->modules->get( 'compliance_reports' );
        if ( $module && method_exists( $module, 'maybe_setup_schedule' ) ) {
            $module->maybe_setup_schedule();
        }

        $this->send_success( [ 'message' => __( 'Compliance Reports settings saved.', 'ultraguard-security-suite' ) ] );
    }

    private function get_download_url( int $report_id ): string {
        return add_query_arg( [
            'action'    => 'ultraguard_compliance_download_report',
            'report_id' => $report_id,
            'nonce'     => wp_create_nonce( static::NONCE ),
        ], self_admin_url( 'admin-ajax.php' ) );
    }

    private function get_report( int $report_id ): array {
        $table = $this->t( 'generated_reports' );
        if ( ! $table || ! method_exists( $table, 'get' ) ) {
            return [];
        }

        $report = $table->get( $report_id );
        return is_array( $report ) ? $report : [];
    }

    private function engine(): ReportBuilderEngine {
        if ( null === $this->engine ) {
            $this->engine = new ReportBuilderEngine( $this->plugin );
        }

        return $this->engine;
    }
}

// phpcs:enable
