<?php

namespace KirilKirkov\WpInvoices;

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

class Charts
{
    /**
     * Invoices charts
     */
    public static function charts_inv_page()
    {
        $Config = Config::class;

        $dates = self::get_dates();

        require plugin_dir_path( __FILE__ ) . '../../Views/Invoices/Charts.php';
    }

    public static function get_dates()
    {
        $from_date = new \DateTime('first day of january '. gmdate('Y'));
        $from_date = $from_date->format(Config::get_dates_format_type());
        $to_date = new \DateTime('last day of december '. gmdate('Y'));
        $to_date = $to_date->format(Config::get_dates_format_type());

        // No nonce verification needed here – just reading the from_date and to_date for filtering
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if(isset($_GET['from_date'])) {
            // No nonce verification needed here – just reading the from_date and to_date for filtering
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            $from_date = \DateTime::createFromFormat(Config::get_dates_format_type(), sanitize_text_field(wp_unslash($_GET['from_date'])));
            if($from_date) {
                $from_date = $from_date->format(Config::get_dates_format_type());
            }
        }

        // No nonce verification needed here – just reading the from_date and to_date for filtering
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if(isset($_GET['to_date'])) {
            // No nonce verification needed here – just reading the from_date and to_date for filtering
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            $to_date = \DateTime::createFromFormat(Config::get_dates_format_type(), sanitize_text_field(wp_unslash($_GET['to_date'])));
            if($to_date) {
                $to_date = $to_date->format(Config::get_dates_format_type());
            }
        }
         
        return [
            'from_date' => $from_date,
            'to_date' => $to_date,
        ];
    }

    private static function get_dates_where()
    {
        global $wpdb;

        $dates = self::get_dates();

        $where = [];
        if($dates['from_date']) {
            $from_date = \DateTime::createFromFormat(Config::get_dates_format_type(), $dates['from_date']);
            if($from_date) {
                $where[] = $wpdb->prepare( ' (created_at >= %s) ', $from_date->format('Y-m-d'));
            }
        }
        if($dates['to_date']) {
            $to_date = \DateTime::createFromFormat(Config::get_dates_format_type(), $dates['to_date']);
            if($to_date) {
                $where[] = $wpdb->prepare( ' (created_at <= %s) ', $to_date->format('Y-m-d'));
            }
        }
        
        if(!count($where)) {
            return '';
        }

        $where = ' WHERE '.join(' AND ', $where);

        return $where;
    }

    /**
     * JS Format:
     */
    // [
    //     ['invoice', 1],
    //     ['pro-forma', 0],
    //     ['debit-note', 0],
    //     ['credit-note', 0],
    // ]
    public static function get_issued_by_period()
    {
        global $wpdb;
        $w = new Invoices();

        $where = self::get_dates_where();
        
        $js = [];
        // No need cache, we need fresh data for the charts. $w->table_name is hardcoded table name. $where variable is already prepared and safe.
        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
        $r = $wpdb->get_results( "SELECT COUNT(id) as cnt, invoice_type FROM " . esc_sql($w->table_name) . " {$where} GROUP BY invoice_type", OBJECT );
        if(count($r)) {
            foreach($r as $rr) {
                $js[] = [esc_html(sanitize_text_field($rr->invoice_type)), $rr->cnt];
            }
        }

        return $js;
    }

    /**
     * JS Format
     */
    // ['Jan 2022', 'Feb 2022', 'Mar 2022', 'Apr 2022', 'May 2022', 'Jun 2022', 'Jul 2022', 'Aug 2022', 'Sep 2022', 'Oct 2022', 'Nov 2022', 'Dec 2022',]
    public static function get_issued_count_by_month_categories()
    {

        $js = [];
        for($i=1; $i <= 12; $i++) {
            $date = \DateTime::createFromFormat('m.Y', "{$i}." . gmdate('Y'));
            $m = $date->format('M');
            $months_names = Config::get_months();
            $m = $months_names[$m];
            $js[] = $m . ' ' . $date->format('Y');
        }
        return $js;
    }

    /**
     * JS Format:
     */
    // [
    //     {
    //         name: 'invoice',
    //         data: [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,]
    //     },
    //     {
    //         name: 'pro-forma',
    //         data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,]
    //     },
    //     {
    //         name: 'debit-note',
    //         data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,]
    //     },
    //     {
    //         name: 'credit-note',
    //         data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,]
    //     },
    // ]
    public static function get_count_by_month($amount = false)
    {
        global $wpdb;
        $w = new Invoices();

        $months = array();
        $invMonths = array();

        $months = [];
        for($i=1; $i <= 12; $i++) {
            $date = \DateTime::createFromFormat('m.Y', "{$i}." . gmdate('Y'));
            $m = $date->format('M');
            $months_names = Config::get_months();
            $m = $months_names[$m];
            $months[$m . ' ' . $date->format('Y')] = array('num' => 0, 'amount' => 0);
        }

        // give to all types of invoices all selected months.years and set issued to 0
        $invReadableTypes = Config::get_invoice_types();
        foreach ($invReadableTypes as $inType) {
            $invMonths[$inType] = $months;
        }

        $where = self::get_dates_where();

        // No need cache, we need fresh data for the charts. $w->table_name is hardcoded table name. $where variable is already prepared and safe.
        //phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
        $result = $wpdb->get_results( 'SELECT COUNT(id) AS cnt, invoice_type, SUM(final_total) as final_total, DATE_FORMAT(created_at, "%b %Y") AS date_created FROM '  . esc_sql($w->table_name) . " {$where} GROUP BY date_created, invoice_type", OBJECT );
        if(count($result)) {
            foreach ($result as $invoices) {
                if (array_key_exists($invReadableTypes[$invoices->invoice_type], $invMonths)) {
                    if (array_key_exists($invoices->date_created, $invMonths[$invReadableTypes[$invoices->invoice_type]])) {
                        $invMonths[$invReadableTypes[$invoices->invoice_type]][$invoices->date_created] = array(
                            'num' => (int) $invoices->cnt,
                            'amount' => $invoices->final_total
                        );
                    }
                }
            }
        }

        $js = [];

        // get my count
        if($amount === false) {

            foreach($invMonths as $t => $i) {
                $m = [];
                foreach($i as $ii) {
                    $m[] = $ii['num'];
                } 
                $js[] = ['name' => $t, 'data' => $m];
            }

        } else { // get by amount

            foreach($invMonths as $t => $i) {
                $a = [];
                foreach($i as $ii) {
                    $a[] = $ii['amount'];
                } 
                $js[] = ['name' => $t, 'data' => $a];
            }

        }

        return $js;
    }

    /**
     * Export invoices as csv
     */
    public static function handle_export_csv()
    {
        // No nonce verification needed here – just checking the download-csv and page for exporting. This does not perform any write/modification actions.
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if(!isset($_GET['download-csv']) || (!isset($_GET['page']) || $_GET['page'] !== Config::SUB_MENU_CHARTS_INVOICE_PAGE_SLUG)) {
            return;
        }

        global $wpdb;
        $w = new Invoices();

        // We need a fresh result directly from the database (not cached). Using $wpdb->get_results() with hardcoded table name – the standard and safe approach for this operation.
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $result = $wpdb->get_results( 'SELECT invoice_type, to_invoice_number, from_date, invoice_number,
        invoice_date, date_tax_event, due_date, has_maturity, maturity_date, cash_accounting, currency, 
        items_total, discount, discount_type, vat_percent, vat_sum, no_vat, no_vat_reason, 
        final_total, remarks, payment_method, tax_base, schiffer, compiled 
        FROM ' . esc_sql($w->table_name), OBJECT ); 

        $array_cols = [];
        foreach($result as &$res) {
            $array_cols[] = (array)$res;
            $res = null;
        }

        $filename = 'invoices.csv';

        header("Expires: 0");
        header("Content-Disposition: attachment; filename={$filename}");
        header("Pragma: no-cache");	
        header("Content-type: text/csv");
        header("Content-Type: application/force-download");
        
        $file = fopen('php://output', 'w');
        $i = 0;
        foreach ($array_cols as $cols) {
            if($i == 0) {
                $keys = array_keys($cols);
                fputcsv($file, $keys, ',', '"', '\\');
            }
            fputcsv($file, $cols, ',', '"', '\\');
            $i++;
        }

        exit();
    }
}