<?php
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

add_action( 'admin_init', 'elementsell_handle_invoice_export_request' );

/**
 * @return array<string, string>
 */
function elementsell_get_invoice_export_period_options() {
    return [
        'last_month' => 'Minulý měsíc',
        'this_month' => 'Tento měsíc',
        'this_year'  => 'Tento rok',
        'all'        => 'Vše',
    ];
}

/**
 * @param string $period
 * @return array{start: string, end: string}|null
 */
function elementsell_get_invoice_export_period_bounds( $period ) {
    $period = sanitize_key( (string) $period );
    $now    = new DateTimeImmutable( 'now', wp_timezone() );

    switch ( $period ) {
        case 'this_month':
            $start = $now->modify( 'first day of this month' );
            $end   = $now->modify( 'last day of this month' );
            break;
        case 'last_month':
            $start = $now->modify( 'first day of previous month' );
            $end   = $now->modify( 'last day of previous month' );
            break;
        case 'this_year':
            $start = $now->setDate( (int) $now->format( 'Y' ), 1, 1 );
            $end   = $now->setDate( (int) $now->format( 'Y' ), 12, 31 );
            break;
        case 'all':
            return null;
        default:
            $start = $now->modify( 'first day of previous month' );
            $end   = $now->modify( 'last day of previous month' );
            break;
    }

    return [
        'start' => $start->format( 'Y-m-d' ),
        'end'   => $end->format( 'Y-m-d' ),
    ];
}

/**
 * @param string $period
 * @return object[]
 */
function elementsell_get_invoices_for_export( $period = 'last_month' ) {
    global $wpdb;

    $invoices_table = elementsell_get_invoices_table_name();
    $orders_table   = $wpdb->prefix . 'elementsell_orders';
    $bounds         = elementsell_get_invoice_export_period_bounds( $period );

    $sql = "
        SELECT i.*
        FROM {$invoices_table} i
        INNER JOIN {$orders_table} o ON o.id = i.order_id
        WHERE i.type != 'demo'
          AND i.status = 'paid'
    ";

    $params = [];

    if ( $bounds ) {
        $sql     .= ' AND i.issue_date >= %s AND i.issue_date <= %s';
        $params[] = $bounds['start'];
        $params[] = $bounds['end'];
    }

    $sql .= ' ORDER BY i.issue_date ASC, i.id ASC';

    if ( $params ) {
        return (array) $wpdb->get_results( $wpdb->prepare( $sql, ...$params ) );
    }

    return (array) $wpdb->get_results( $sql );
}

/**
 * @return void
 */
function elementsell_handle_invoice_export_request() {
    if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) {
        return;
    }

    if ( empty( $_GET['elementsell_export_invoices'] ) ) {
        return;
    }

    check_admin_referer( 'elementsell_export_invoices' );

    $format = sanitize_key( wp_unslash( $_GET['elementsell_export_invoices'] ) );
    $period = isset( $_GET['period'] ) ? sanitize_key( wp_unslash( $_GET['period'] ) ) : 'last_month';

    if ( $format === 'csv' ) {
        elementsell_export_invoices_csv( $period );
        exit;
    }

    if ( $format === 'pdf' ) {
        elementsell_export_invoices_pdf_zip( $period );
        exit;
    }
}

/**
 * @param object $invoice
 * @return array{base: float, vat: float, total: float}
 */
function elementsell_calculate_invoice_vat_amounts( $invoice ) {
    $total    = (float) $invoice->price;
    $vat_rate = (float) $invoice->vat_rate;
    $base     = $total;
    $vat      = 0.0;

    if ( $vat_rate > 0 ) {
        $base = $total / ( 1 + ( $vat_rate / 100 ) );
        $vat  = $total - $base;
    }

    return [
        'base'  => round( $base, 2 ),
        'vat'   => round( $vat, 2 ),
        'total' => round( $total, 2 ),
    ];
}

/**
 * @param string $period
 * @return void
 */
function elementsell_export_invoices_csv( $period = 'last_month' ) {
    $invoices = elementsell_get_invoices_for_export( $period );
    $filename = 'elementsell-faktury-' . sanitize_file_name( $period ) . '-' . gmdate( 'Y-m-d' ) . '.csv';

    nocache_headers();
    header( 'Content-Type: text/csv; charset=utf-8' );
    header( 'Content-Disposition: attachment; filename=' . $filename );

    $output = fopen( 'php://output', 'w' );

    if ( false === $output ) {
        wp_die( esc_html__( 'Export se nepodařil.', 'platebni-formular' ) );
    }

    fwrite( $output, "\xEF\xBB\xBF" );

    fputcsv(
        $output,
        [
            'Číslo faktury',
            'Datum vystavení',
            'Datum úhrady',
            'Jméno',
            'Příjmení',
            'Firma',
            'Email',
            'Telefon',
            'Adresa',
            'IČO',
            'DIČ',
            'Produkt',
            'Základ DPH',
            'DPH %',
            'DPH',
            'Celkem',
            'Měna',
        ],
        ';'
    );

    foreach ( $invoices as $invoice ) {
        $order = elementsell_get_order( (int) $invoice->order_id );

        if ( ! $order ) {
            continue;
        }

        $amounts = elementsell_calculate_invoice_vat_amounts( $invoice );

        fputcsv(
            $output,
            [
                $invoice->invoice_number,
                $invoice->issue_date ? mysql2date( 'Y-m-d', $invoice->issue_date, false ) : '',
                $invoice->paid_date ? mysql2date( 'Y-m-d', $invoice->paid_date, false ) : '',
                $order->first_name,
                $order->surname,
                elementsell_get_order_field( $order->id, 'company' ),
                $order->email,
                $order->phone,
                elementsell_get_order_field( $order->id, 'address' ),
                elementsell_get_order_field( $order->id, 'ico' ),
                elementsell_get_order_field( $order->id, 'dic' ),
                $invoice->product_name,
                number_format( $amounts['base'], 2, '.', '' ),
                number_format( (float) $invoice->vat_rate, 2, '.', '' ),
                number_format( $amounts['vat'], 2, '.', '' ),
                number_format( $amounts['total'], 2, '.', '' ),
                $order->currency ?: 'CZK',
            ],
            ';'
        );
    }

    fclose( $output );
}

/**
 * @param string $period
 * @return void
 */
function elementsell_export_invoices_pdf_zip( $period = 'last_month' ) {
    $invoices = elementsell_get_invoices_for_export( $period );

    if ( empty( $invoices ) ) {
        wp_die( esc_html__( 'Za zvolené období nejsou žádné uhrazené faktury.', 'platebni-formular' ) );
    }

    if ( ! class_exists( 'ZipArchive' ) ) {
        wp_die( esc_html__( 'Na serveru není dostupný ZipArchive.', 'platebni-formular' ) );
    }

    $zip      = new ZipArchive();
    $tmp_file = wp_tempnam( 'elementsell-invoices-' . $period );

    if ( ! $tmp_file || $zip->open( $tmp_file, ZipArchive::OVERWRITE ) !== true ) {
        wp_die( esc_html__( 'Export PDF se nepodařil.', 'platebni-formular' ) );
    }

    $added = 0;

    foreach ( $invoices as $invoice ) {
        $pdf_path = '';

        if ( ! empty( $invoice->pdf_path ) && file_exists( $invoice->pdf_path ) ) {
            $pdf_path = $invoice->pdf_path;
        } elseif ( function_exists( 'elementsell_generate_invoice_pdf_file' ) ) {
            $pdf_path = (string) elementsell_generate_invoice_pdf_file( (int) $invoice->id );
        }

        if ( $pdf_path && file_exists( $pdf_path ) ) {
            $zip->addFile( $pdf_path, basename( $pdf_path ) );
            ++$added;
        }
    }

    $zip->close();

    if ( $added === 0 ) {
        @unlink( $tmp_file );
        wp_die( esc_html__( 'Nepodařilo se připravit žádné PDF faktury.', 'platebni-formular' ) );
    }

    $filename = 'elementsell-faktury-' . sanitize_file_name( $period ) . '-' . gmdate( 'Y-m-d' ) . '.zip';

    nocache_headers();
    header( 'Content-Type: application/zip' );
    header( 'Content-Disposition: attachment; filename=' . $filename );
    header( 'Content-Length: ' . filesize( $tmp_file ) );

    readfile( $tmp_file );
    @unlink( $tmp_file );
    exit;
}

/**
 * @return void
 */
function elementsell_render_invoice_export_hint() {
    if ( ! current_user_can( 'manage_options' ) ) {
        return;
    }

    $periods = elementsell_get_invoice_export_period_options();
    ?>
    <details class="elementsell-accounting-export">
        <summary>Pro účetní</summary>
        <form method="get" action="<?php echo esc_url( admin_url( 'admin.php' ) ); ?>">
            <?php wp_nonce_field( 'elementsell_export_invoices' ); ?>
            <input type="hidden" name="page" value="elementsell">
            <label class="screen-reader-text" for="elementsell-export-period">Období</label>
            <select id="elementsell-export-period" name="period">
                <?php foreach ( $periods as $value => $label ) : ?>
                    <option value="<?php echo esc_attr( $value ); ?>"<?php selected( $value, 'last_month' ); ?>>
                        <?php echo esc_html( $label ); ?>
                    </option>
                <?php endforeach; ?>
            </select>
            <button type="submit" class="button button-small" name="elementsell_export_invoices" value="csv">CSV</button>
            <button type="submit" class="button button-small" name="elementsell_export_invoices" value="pdf">PDF</button>
        </form>
    </details>
    <?php
}
