<?php
namespace ComptaFlowUK\Services;

defined('ABSPATH') || exit;

class JournalExporter
{
    /**
     * Generate and download the Chronological Journal
     * Sorted by entry date then creation time
     */
    public static function export(int $user_id, string $start_date, string $end_date): void
    {
        global $wpdb;
        $journal_table = $wpdb->prefix . 'cfuk_journal_entries';
        
        // Retrieve with date + creation time sorting
        $entries = $wpdb->get_results($wpdb->prepare(
            "SELECT * FROM $journal_table 
             WHERE created_by = %d 
             AND date_ecriture BETWEEN %s AND %s
             ORDER BY date_ecriture ASC, created_at ASC, id ASC",
            $user_id, $start_date, $end_date
        ));
        
        if (empty($entries)) {
            wp_die(esc_html__('No entries found for this period.', 'comptaflow-uk-by-meetempo'));
        }
        
        // Generate CSV
        $content = self::generateJournalContent($entries);
        
        // Download headers
        $filename = 'Journal_' . gmdate('Ymd') . '_' . str_replace('-', '', $start_date) . '_' . str_replace('-', '', $end_date) . '.csv';
        
        header('Content-Type: text/csv; charset=UTF-8');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Pragma: no-cache');
        header('Expires: 0');
        
        echo "\xEF\xBB\xBF"; // BOM UTF-8
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSV output, not HTML
        echo $content;
        exit;
    }
    
    /**
     * Generate journal CSV content
     */
    private static function generateJournalContent(array $entries): string
    {
        $lines = [];
        
        // Header
        $lines[] = 'Date;Time;Transaction ID;Ref;Account;Label;Debit;Credit;Source';
        
        $total_debit = 0;
        $total_credit = 0;
        
        foreach ($entries as $entry) {
            $debit = (float)$entry->debit;
            $credit = (float)$entry->credit;
            
            $total_debit += $debit;
            $total_credit += $credit;
            
            // Formatted date
            $date = date_i18n('d/m/Y', strtotime($entry->date_ecriture));
            
            // Creation time (for precise chronological sorting)
            $heure = gmdate('H:i:s', strtotime($entry->created_at));
            
            // Account label
            $account_label = self::getAccountLabel($entry->compte_num);
            
            $lines[] = implode(';', [
                $date,
                $heure,
                $entry->transaction_id ?: 'N/A',
                $entry->piece_ref ?: 'N/A',
                $entry->compte_num . ' - ' . $account_label,
                self::cleanText($entry->libelle ?: ''),
                number_format($debit, 2, '.', ','),
                number_format($credit, 2, '.', ','),
                self::getSourceLabel($entry->source)
            ]);
        }
        
        // Totals
        $lines[] = '';
        $lines[] = implode(';', [
            'TOTALS',
            '',
            '',
            '',
            '',
            '',
            number_format($total_debit, 2, '.', ','),
            number_format($total_credit, 2, '.', ','),
            ''
        ]);
        
        return implode("\n", $lines);
    }
    
    /**
     * Account labels via ChartOfAccounts
     */
    private static function getAccountLabel(string $account_num): string
    {
        require_once COMPTAFLOW_UK_PLUGIN_DIR . 'src/Services/ChartOfAccounts.php';
        
        // Exact search
        $account = \ComptaFlowUK\Services\ChartOfAccounts::getAccount($account_num);
        if ($account) {
            return $account['label'];
        }
        
        // Search by prefix
        for ($len = strlen($account_num) - 1; $len >= 2; $len--) {
            $prefix = substr($account_num, 0, $len);
            $account = \ComptaFlowUK\Services\ChartOfAccounts::getAccount($prefix);
            if ($account) {
                return $account['label'];
            }
        }
        
        return 'Account ' . $account_num;
    }
    
    /**
     * Entry source labels
     */
    private static function getSourceLabel(?string $source): string
    {
        if (!$source) {
            return '';
        }
        
        $labels = [
            'EXPENSE' => 'Purchase',
            'SALE' => 'Sale',
            'PAYROLL' => 'Payroll',
            'VAT_DECLARATION' => 'VAT Declaration',
            'VAT_MANUAL_PAYMENT' => 'Manual VAT Payment',
            'VAT_ADVANCE' => 'VAT Advance',
            'FINANCIAL' => 'Financial Operation',
            'FINANCIAL_PAYMENT' => 'Financial Settlement',
            'IMMOBILIZATION' => 'Fixed Asset',
            'BANK_RECO' => 'Bank Reconciliation',
            'BANK_RECO_UNDO' => 'Reconciliation Reversal',
            'MANUAL_OD' => 'Manual Entry',
        ];
        
        return $labels[$source] ?? $source;
    }
    
    /**
     * Clean text for CSV
     */
    private static function cleanText(string $text): string
    {
        $text = str_replace([';', "\n", "\r", "\t"], ' ', $text);
        $text = preg_replace('/\s+/', ' ', $text);
        return trim($text);
    }
}
