<?php
namespace ComptaFlowUK\Services;

defined('ABSPATH') || exit;

class GeneralLedgerExporter
{
    /**
     * Generate and download the General Ledger
     * Movement details by account with cumulative balances
     */
    public static function export(int $user_id, string $start_date, string $end_date): void
    {
        global $wpdb;
        $journal_table = $wpdb->prefix . 'cfuk_journal_entries';
        
        // Retrieve sorted by account then date
        $entries = $wpdb->get_results($wpdb->prepare(
            "SELECT * FROM $journal_table 
             WHERE created_by = %d 
             AND date_ecriture BETWEEN %s AND %s
             ORDER BY compte_num ASC, date_ecriture ASC, created_at 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::generateLedgerContent($entries);
        
        // Download headers
        $filename = 'GeneralLedger_' . 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 General Ledger CSV content
     */
    private static function generateLedgerContent(array $entries): string
    {
        $lines = [];
        
        // Group by account
        $by_account = [];
        foreach ($entries as $entry) {
            $by_account[$entry->compte_num][] = $entry;
        }
        
        // Generate ledger account by account
        foreach ($by_account as $account_num => $account_entries) {
            $account_label = self::getAccountLabel($account_num);
            
            // Account header
            $lines[] = '';
            $lines[] = '═════════════════════════════════════════════════════';
            $lines[] = 'ACCOUNT ' . $account_num . ' - ' . strtoupper($account_label);
            $lines[] = '═════════════════════════════════════════════════════';
            $lines[] = 'Date;Ref;Label;Debit;Credit;Balance';
            
            // Account movements
            $balance = 0;
            $total_debit = 0;
            $total_credit = 0;
            
            foreach ($account_entries as $entry) {
                $debit = (float)$entry->debit;
                $credit = (float)$entry->credit;
                
                $balance += $debit - $credit;
                $total_debit += $debit;
                $total_credit += $credit;
                
                $date = date_i18n('d/m/Y', strtotime($entry->date_ecriture));
                
                $lines[] = implode(';', [
                    $date,
                    $entry->piece_ref ?: 'N/A',
                    self::cleanText($entry->libelle ?: ''),
                    number_format($debit, 2, '.', ','),
                    number_format($credit, 2, '.', ','),
                    number_format($balance, 2, '.', ',')
                ]);
            }
            
            // Account total
            $lines[] = '─────────────────────────────────────────────────────';
            $lines[] = implode(';', [
                'TOTAL',
                $account_num,
                '',
                number_format($total_debit, 2, '.', ','),
                number_format($total_credit, 2, '.', ','),
                number_format($balance, 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;
    }
    
    /**
     * 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);
    }
}
