<?php
/**
 * OVP-Sponsorizare
 *
 * @package   OVPSPO_Sponsorizare
 * @author    Ovidiu Pantiru - OVP-Digital
 * @copyright 2024 Ovidiu Pantiru
 * @license   GPL-2.0+
 * @link      https://ovidiupantiru.ro
 */

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

if ( ! class_exists('OVPSPO_Ajax177') ) {
class OVPSPO_Ajax177 {

    public static function init() {
        add_action( 'wp_ajax_ovpspo_submit177',        array( __CLASS__, 'handle' ) ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
        add_action( 'wp_ajax_nopriv_ovpspo_submit177', array( __CLASS__, 'handle' ) ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
    }

    public static function handle() {
        if ( ! check_ajax_referer( 'ovpspo_submit177', 'ovpspo_nonce177', false ) ) {
            wp_send_json_error( array('message' => 'Cerere invalidă. Reîncarcă pagina.') );
        }

        $p = wp_unslash( $_POST ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

        // ── Date contribuabil ──
        $cif        = sanitize_text_field( $p['cif'] ?? '' );
        $denC       = sanitize_text_field( $p['denC'] ?? '' );
        $an         = absint( $p['an'] ?? gmdate('Y')-1 );
        $luna       = absint( $p['luna'] ?? gmdate('m') );
        $dataInc    = sanitize_text_field( $p['dataInceput'] ?? '' );
        $dataSf     = sanitize_text_field( $p['dataSfarsit'] ?? '' );
        $sumaMax    = absint( $p['sumaMax'] ?? 0 );
        $sumaAnt    = absint( $p['sumaAnt'] ?? 0 );
        $sumaRest   = max(0, $sumaMax - $sumaAnt);
        $emailC     = sanitize_email( $p['emailC'] ?? '' );
        $telC       = sanitize_text_field( $p['telC'] ?? '' );
        $d_rec      = ! empty($p['d_rec']) ? 1 : 0;
        $d_rec_notif= ! empty($p['d_rec_notif']) ? 1 : 0;
        $index      = sanitize_text_field( $p['index'] ?? '' );

        // Adresa contribuabil combinata
        $adresaC = self::build_address(
            $p['stradaC'] ?? '', $p['infoC'] ?? '',
            $p['localitateC'] ?? '', $p['judetC'] ?? '',
            $p['sectorC'] ?? '', $p['codPostalC'] ?? ''
        );

        // Imputernicit
        $cifR  = sanitize_text_field( $p['cifR'] ?? '' );
        $denR  = sanitize_text_field( $p['denR'] ?? '' );
        $telR  = sanitize_text_field( $p['telR'] ?? '' );
        $emailR= sanitize_email( $p['emailR'] ?? '' );
        $adresaR = self::build_address(
            $p['stradaR'] ?? '', '',
            $p['localitateR'] ?? '', $p['judetR'] ?? '',
            $p['sectorR'] ?? '', $p['codPostalR'] ?? ''
        );

        // ── Validare ──
        $errors = array();
        if ( empty($cif) )    $errors[] = 'CIF contribuabil este obligatoriu.';
        if ( empty($denC) )   $errors[] = 'Denumirea contribuabilului este obligatorie.';
        if ( empty($emailC) ) $errors[] = 'Email-ul este obligatoriu.';
        if ( ! is_email($emailC) ) $errors[] = 'Email-ul nu este valid.';
        if ( $sumaMax <= 0 )  $errors[] = 'Suma maximă trebuie să fie pozitivă.';
        if ( empty($dataInc) ) $errors[] = 'Data de început a perioadei este obligatorie.';
        if ( empty($dataSf) )  $errors[] = 'Data de sfârșit a perioadei este obligatorie.';

        // ── Beneficiari ──
        $beneficiari = array();
        $tipB_arr    = $p['tipB'] ?? array();
        $denB_arr    = $p['denB'] ?? array();
        $cuiB_arr    = $p['cuiB'] ?? array();
        $ibanB_arr   = $p['ibanB'] ?? array();
        $sumaB_arr   = $p['sumaB'] ?? array();
        $acord_arr   = $p['acord'] ?? array();
        $contractB_arr = $p['contractB'] ?? array();
        $telB_arr    = $p['telB'] ?? array();
        $emailB_arr  = $p['emailB'] ?? array();

        if ( empty($tipB_arr) ) {
            $errors[] = 'Trebuie adăugat cel puțin un beneficiar.';
        }

        foreach ( $tipB_arr as $nr => $tipB ) {
            $denB  = sanitize_text_field( $denB_arr[$nr] ?? '' );
            $cuiB  = sanitize_text_field( $cuiB_arr[$nr] ?? '' );
            $ibanB = sanitize_text_field( $ibanB_arr[$nr] ?? '' );
            $sumaB = absint( $sumaB_arr[$nr] ?? 0 );

            if ( empty($denB) )  $errors[] = "Beneficiar $nr: Denumirea este obligatorie.";
            if ( empty($cuiB) )  $errors[] = "Beneficiar $nr: CIF-ul este obligatoriu.";
            if ( empty($ibanB) ) $errors[] = "Beneficiar $nr: IBAN-ul este obligatoriu.";
            if ( $sumaB <= 0 )   $errors[] = "Beneficiar $nr: Suma trebuie să fie pozitivă.";

            $adresaB = self::build_address(
                $p['stradaB'][$nr] ?? '', $p['infoB'][$nr] ?? '',
                $p['localitateB'][$nr] ?? '', $p['judetB'][$nr] ?? '',
                $p['sectorB'][$nr] ?? '', $p['codPostalB'][$nr] ?? ''
            );

            $beneficiari[] = array(
                'acord'     => ! empty($acord_arr[$nr]) ? 1 : 0,
                'tipB'      => absint($tipB),
                'cuiB'      => $cuiB,
                'denB'      => $denB,
                'adresaB'   => $adresaB,
                'contractB' => sanitize_text_field( $contractB_arr[$nr] ?? '' ),
                'telB'      => sanitize_text_field( $telB_arr[$nr] ?? '' ),
                'emailB'    => sanitize_email( $emailB_arr[$nr] ?? '' ),
                'ibanB'     => $ibanB,
                'sumaB'     => $sumaB,
            );
        }

        if ( ! empty($errors) ) {
            wp_send_json_error( array('message' => implode('<br>', $errors)) );
        }

        // ── Formatare date pentru XML ──
        $dataInc_fmt = self::format_date($dataInc);
        $dataSf_fmt  = self::format_date($dataSf);

        // ── Genereaza XML ──
        $xml = self::generate_xml(array(
            'd_rec'       => $d_rec,
            'd_rec_notif' => $d_rec_notif,
            'index'       => $index,
            'an'          => $an,
            'luna'        => $luna,
            'dataInceput' => $dataInc_fmt,
            'dataSfarsit' => $dataSf_fmt,
            'cif'         => $cif,
            'denC'        => $denC,
            'sumaMax'     => $sumaMax,
            'sumaAnt'     => $sumaAnt,
            'sumaRest'    => $sumaRest,
            'adresaC'     => $adresaC,
            'telC'        => substr(preg_replace('/\D/', '', $telC), 0, 10),
            'emailC'      => $emailC,
            'cifR'        => $cifR,
            'denR'        => $denR,
            'adresaR'     => $adresaR,
            'telR'        => substr(preg_replace('/\D/', '', $telR), 0, 10),
            'emailR'      => $emailR,
        ), $beneficiari);

        // ── Salveaza in DB ──
        global $wpdb;
        $table = $wpdb->prefix . 'f177_submissions';

        // Creeaza tabela daca nu exista
        if ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $table ) ) !== $table ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery
            require_once ABSPATH . 'wp-admin/includes/upgrade.php';
            $charset = $wpdb->get_charset_collate();
            dbDelta( "CREATE TABLE IF NOT EXISTS $table (
                id               BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
                data_trimitere   DATETIME NOT NULL,
                an               YEAR,
                data_inceput     DATE,
                data_sfarsit     DATE,
                rectificativa    TINYINT(1) DEFAULT 0,
                tip_platitor     VARCHAR(20),
                cif              VARCHAR(13),
                denumire         VARCHAR(200),
                email            VARCHAR(200),
                telefon          VARCHAR(20),
                suma_max         DECIMAL(14,2) DEFAULT 0,
                suma_anterioara  DECIMAL(14,2) DEFAULT 0,
                suma_ramasa      DECIMAL(14,2) DEFAULT 0,
                tip_beneficiar   TINYINT(1) DEFAULT 1,
                bnf_denumire     VARCHAR(200),
                bnf_cif          VARCHAR(13),
                bnf_iban         VARCHAR(34),
                bnf_suma         DECIMAL(14,2) DEFAULT 0,
                xml_path         VARCHAR(255),
                ip               VARCHAR(45),
                PRIMARY KEY (id)
            ) $charset;" );
        }

        if ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $table ) ) === $table ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery
            // Asigura ca coloanele xml_path si pdf_path exista
            $cols = $wpdb->get_results( "SHOW COLUMNS FROM " . esc_sql($table), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $col_names = array_column( $cols ?: array(), 'Field' );
            if ( ! in_array( 'xml_path', $col_names, true ) ) {
                $wpdb->query( "ALTER TABLE " . esc_sql($table) . " ADD COLUMN xml_path VARCHAR(255) DEFAULT NULL" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.SchemaChange
            }
            if ( ! in_array( 'pdf_path', $col_names, true ) ) {
                $wpdb->query( "ALTER TABLE " . esc_sql($table) . " ADD COLUMN pdf_path VARCHAR(255) DEFAULT NULL" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.SchemaChange
            }

            $wpdb->insert( $table, array( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
                'data_trimitere'  => current_time('mysql'),
                'an'              => $an,
                'data_inceput'    => $dataInc,
                'data_sfarsit'    => $dataSf,
                'rectificativa'   => $d_rec,
                'tip_platitor'    => 'profit',
                'cif'             => $cif,
                'denumire'        => $denC,
                'email'           => $emailC,
                'telefon'         => $telC,
                'suma_max'        => $sumaMax,
                'suma_anterioara' => $sumaAnt,
                'suma_ramasa'     => $sumaRest,
                'tip_beneficiar'  => absint($beneficiari[0]['tipB'] ?? 1),
                'bnf_denumire'    => $beneficiari[0]['denB'] ?? '',
                'bnf_cif'         => $beneficiari[0]['cuiB'] ?? '',
                'bnf_iban'        => $beneficiari[0]['ibanB'] ?? '',
                'bnf_suma'        => $beneficiari[0]['sumaB'] ?? 0,
                'ip'              => isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '',
                'xml_path'        => '',
                'pdf_path'        => '',
            ));
            $id = $wpdb->insert_id;
            if ( ! $id ) {
            }
        } else {
            $id = time();
        }

        // ── Salveaza XML pe server ──
        $xml_path = '';
        $upload_dir = wp_upload_dir();
        $dir = $upload_dir['basedir'] . '/formular177/';
        if ( ! file_exists($dir) ) wp_mkdir_p( $dir );
        $safe_den = substr( preg_replace( '/[^A-Za-z0-9]/', '_', sanitize_file_name( $denC ) ), 0, 40 );
        $filename = 'D177_' . $safe_den . '_' . intval( $id ) . '.xml';
        $xml_path = $dir . $filename;
        file_put_contents( $xml_path, $xml ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents

        // ── Genereaza PDF D177 ──
        // Construieste array beneficiari in formatul nou
        $bnf_for_pdf = array();
        foreach ( $beneficiari as $bnf ) {
            $bnf_for_pdf[] = array(
                'tip'        => absint($bnf['tipB'] ?? 1),
                'denumire'   => $bnf['denB'] ?? '',
                'prenume'    => $bnf['prenumeB'] ?? '',
                'cif'        => $bnf['cuiB'] ?? '',
                'iban'       => $bnf['ibanB'] ?? '',
                'suma'       => $bnf['sumaB'] ?? 0,
                'contract'   => $bnf['contractB'] ?? '',
                'strada'     => $bnf['stradaB'] ?? '',
                'numar'      => $bnf['nrB'] ?? '',
                'bloc'       => $bnf['blocB'] ?? '',
                'scara'      => $bnf['scaraB'] ?? '',
                'etaj'       => $bnf['etajB'] ?? '',
                'ap'         => $bnf['apB'] ?? '',
                'judet'      => $bnf['judetB'] ?? '',
                'localitate' => $bnf['localitateB'] ?? '',
                'cod_postal' => $bnf['codPostalB'] ?? '',
                'email'      => $bnf['emailB'] ?? '',
                'telefon'    => $bnf['telB'] ?? '',
                'info'       => $bnf['infoB'] ?? '',
                'sector'     => $bnf['sectorB'] ?? '',
                'acord_gdpr' => !empty($bnf['acordB']),
            );
        }

        $pdf_data = array(
            'an'              => $an,
            'data_inceput'    => $dataInc,
            'data_sfarsit'    => $dataSf,
            'rectificativa'   => $d_rec,
            'data_rectif'     => sanitize_text_field( wp_unslash( $_POST['data_rectif'] ?? '' ) ),
            'tip_platitor'    => 'profit',
            'cif'             => $cif,
            'denumire'        => $denC,
            'judet'           => sanitize_text_field( wp_unslash( $_POST['judetC'] ?? '' ) ),
            'localitate'      => sanitize_text_field( wp_unslash( $_POST['localitateC'] ?? '' ) ),
            'strada'          => sanitize_text_field( wp_unslash( $_POST['stradaC'] ?? '' ) ),
            'numar'           => sanitize_text_field( wp_unslash( $_POST['nrC'] ?? '' ) ),
            'bloc'            => sanitize_text_field( wp_unslash( $_POST['blocC'] ?? '' ) ),
            'scara'           => sanitize_text_field( wp_unslash( $_POST['scaraC'] ?? '' ) ),
            'ap'              => sanitize_text_field( wp_unslash( $_POST['apC'] ?? '' ) ),
            'cod_postal'      => sanitize_text_field( wp_unslash( $_POST['codPostalC'] ?? '' ) ),
            'telefon'         => $telC,
            'fax'             => sanitize_text_field( wp_unslash( $_POST['faxC'] ?? '' ) ),
            'email'           => $emailC,
            'suma_max'        => $sumaMax,
            'suma_anterioara' => $sumaAnt,
            'suma_ramasa'     => $sumaRest,
            'beneficiari'     => $bnf_for_pdf,
            // Imputernicit
            'imp_denumire'    => sanitize_text_field( wp_unslash( $_POST['denR'] ?? '' ) ),
            'imp_cif'         => sanitize_text_field( wp_unslash( $_POST['cifR'] ?? '' ) ),
            'imp_strada'      => sanitize_text_field( wp_unslash( $_POST['stradaR'] ?? '' ) ),
            'imp_numar'       => sanitize_text_field( wp_unslash( $_POST['nrR'] ?? '' ) ),
            'imp_bloc'        => sanitize_text_field( wp_unslash( $_POST['blocR'] ?? '' ) ),
            'imp_scara'       => sanitize_text_field( wp_unslash( $_POST['scaraR'] ?? '' ) ),
            'imp_etaj'        => sanitize_text_field( wp_unslash( $_POST['etajR'] ?? '' ) ),
            'imp_ap'          => sanitize_text_field( wp_unslash( $_POST['apR'] ?? '' ) ),
            'imp_judet'       => sanitize_text_field( wp_unslash( $_POST['judetR'] ?? '' ) ),
            'imp_localitate'  => sanitize_text_field( wp_unslash( $_POST['localitateR'] ?? '' ) ),
            'imp_cod_postal'  => sanitize_text_field( wp_unslash( $_POST['codPostalR'] ?? '' ) ),
            'imp_telefon'     => sanitize_text_field( wp_unslash( $_POST['telR'] ?? '' ) ),
            'imp_email'       => sanitize_text_field( wp_unslash( $_POST['emailR'] ?? '' ) ),
        );

        $pdf_path = OVPSPO_PDF177::generate( $pdf_data, $id );

        // ── Salveaza caile XML si PDF in DB ──
        if ( $id && ( $xml_path || $pdf_path ) ) {
            $wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                $table,
                array(
                    'xml_path' => $xml_path ?: '',
                    'pdf_path' => $pdf_path ?: '',
                ),
                array('id' => $id)
            );
        }

        // ── Trimite email cu XML + PDF ──
        OVPSPO_Email177::send_user_xml( array(
            'cif'        => $cif,
            'denC'       => $denC,
            'emailC'     => $emailC,
            'an'         => $an,
            'sumaMax'    => $sumaMax,
            'beneficiari'=> $beneficiari,
        ), $xml_path, $pdf_path );
        OVPSPO_Email177::send_admin( array(
            'cif'     => $cif,
            'denumire'=> $denC,
            'email'   => $emailC,
            'an'      => $an,
            'suma_max'=> $sumaMax,
            'bnf_denumire' => $beneficiari[0]['denB'] ?? '',
            'bnf_cif'      => $beneficiari[0]['cuiB'] ?? '',
            'bnf_iban'     => $beneficiari[0]['ibanB'] ?? '',
            'bnf_suma'     => $beneficiari[0]['sumaB'] ?? 0,
            'tip_beneficiar' => $beneficiari[0]['tipB'] ?? 1,
        ), $xml_path ? array($xml_path) : array() );

        // Trimite XML direct pentru download
        wp_send_json_success( array(
            'message'  => '✅ Formularul D177 a fost generat cu succes!<br>Fișierul XML a fost trimis pe email. Descarcă-l și încarcă-l în SPV cu semnătura electronică calificată.',
            'xml'      => base64_encode($xml),
            'filename' => $filename,
        ));
    }

    private static function generate_xml( $data, $beneficiari ) {
        $xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' . "\n";
        $xml .= '<D177 xmlns="mfp:anaf:dgti:d177:declaratie:v1"' . "\n";
        $xml .= '    d_rec="' . intval($data['d_rec']) . '"' . "\n";
        $xml .= '    d_rec_notif="' . intval($data['d_rec_notif']) . '"' . "\n";
        if ( ! empty($data['index']) ) {
            $xml .= '    index="' . self::xe($data['index']) . '"' . "\n";
        }
        $xml .= '    an="' . intval($data['an']) . '"' . "\n";
        $xml .= '    luna="' . intval($data['luna']) . '"' . "\n";
        $xml .= '    dataInceput="' . self::xe($data['dataInceput']) . '"' . "\n";
        $xml .= '    dataSfarsit="' . self::xe($data['dataSfarsit']) . '"' . "\n";
        $xml .= '    totalPlata_A="0"' . "\n";
        $xml .= '    cif="' . self::xe($data['cif']) . '"' . "\n";
        $xml .= '    denC="' . self::xe($data['denC']) . '"' . "\n";
        $xml .= '    sumaMax="' . intval($data['sumaMax']) . '"' . "\n";
        $xml .= '    sumaAnt="' . intval($data['sumaAnt']) . '"' . "\n";
        $xml .= '    sumaRest="' . intval($data['sumaRest']) . '"' . "\n";
        if ( ! empty($data['adresaC']) ) $xml .= '    adresaC="' . self::xe($data['adresaC']) . '"' . "\n";
        if ( ! empty($data['telC']) )    $xml .= '    telC="' . self::xe($data['telC']) . '"' . "\n";
        if ( ! empty($data['emailC']) )  $xml .= '    emailC="' . self::xe($data['emailC']) . '"' . "\n";
        if ( ! empty($data['denR']) )    $xml .= '    denR="' . self::xe($data['denR']) . '"' . "\n";
        if ( ! empty($data['cifR']) )    $xml .= '    cifR="' . self::xe($data['cifR']) . '"' . "\n";
        if ( ! empty($data['adresaR']) ) $xml .= '    adresaR="' . self::xe($data['adresaR']) . '"' . "\n";
        if ( ! empty($data['telR']) )    $xml .= '    telR="' . self::xe($data['telR']) . '"' . "\n";
        if ( ! empty($data['emailR']) )  $xml .= '    emailR="' . self::xe($data['emailR']) . '"' . "\n";
        $xml .= '>' . "\n";

        foreach ( $beneficiari as $bnf ) {
            $xml .= '    <beneficiar' . "\n";
            $xml .= '        acord="' . intval($bnf['acord']) . '"' . "\n";
            $xml .= '        tipB="' . intval($bnf['tipB']) . '"' . "\n";
            $xml .= '        cuiB="' . self::xe($bnf['cuiB']) . '"' . "\n";
            $xml .= '        denB="' . self::xe($bnf['denB']) . '"' . "\n";
            if ( ! empty($bnf['adresaB']) )   $xml .= '        adresaB="' . self::xe($bnf['adresaB']) . '"' . "\n";
            if ( ! empty($bnf['contractB']) )  $xml .= '        contractB="' . self::xe($bnf['contractB']) . '"' . "\n";
            if ( ! empty($bnf['telB']) )       $xml .= '        telB="' . self::xe($bnf['telB']) . '"' . "\n";
            if ( ! empty($bnf['emailB']) )     $xml .= '        emailB="' . self::xe($bnf['emailB']) . '"' . "\n";
            $xml .= '        ibanB="' . self::xe($bnf['ibanB']) . '"' . "\n";
            $xml .= '        sumaB="' . intval($bnf['sumaB']) . '"' . "\n";
            $xml .= '    />' . "\n";
        }

        $xml .= '</D177>';
        return $xml;
    }

    private static function xe( $str ) {
        return htmlspecialchars( (string)$str, ENT_XML1 | ENT_QUOTES, 'UTF-8' );
    }

    private static function build_address( $strada, $info, $localitate, $judet, $sector, $codPostal ) {
        $parts = array_filter( array(
            trim($strada),
            trim($info),
            trim($localitate),
            $sector ? 'Sector ' . trim($sector) : '',
            trim($judet),
            trim($codPostal),
        ));
        return implode(', ', $parts);
    }

    private static function format_date( $date ) {
        // Transforma din YYYY-MM-DD in dd.mm.yyyy
        if ( preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $date, $m) ) {
            return $m[3] . '.' . $m[2] . '.' . $m[1];
        }
        return $date;
    }
}
} // end class_exists
