<?php
namespace ComptaFlowUK\Services;

defined('ABSPATH') || exit;

class BalanceExporter
{
    /**
     * Generate and download the Balance Sheet
     * Format: Account | Label | Debit | Credit | Balance
     */
    public static function export(int $user_id, string $start_date, string $end_date): void
    {
        global $wpdb;
        $journal_table = $wpdb->prefix . 'cfuk_journal_entries';
        
        // Aggregate by account
        $balances = $wpdb->get_results($wpdb->prepare(
            "SELECT 
                compte_num,
                SUM(debit) as total_debit,
                SUM(credit) as total_credit
             FROM $journal_table 
             WHERE created_by = %d 
             AND date_ecriture BETWEEN %s AND %s
             GROUP BY compte_num
             ORDER BY compte_num ASC",
            $user_id, $start_date, $end_date
        ));
        
        if (empty($balances)) {
            wp_die(esc_html__('No entries found for this period.', 'comptaflow-uk-by-meetempo'));
        }
        
        // Generate CSV
        $content = self::generateBalanceContent($balances);
        
        // Download headers
        $filename = 'Balance_' . 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 for Excel
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSV output, not HTML
        echo $content;
        exit;
    }
    
    /**
     * Generate balance CSV content
     */
    private static function generateBalanceContent(array $balances): string
    {
        $lines = [];
        
        // Header
        $lines[] = 'Account;Label;Debit;Credit;Balance';
        
        $total_debit = 0;
        $total_credit = 0;
        
        foreach ($balances as $row) {
            $debit = (float)$row->total_debit;
            $credit = (float)$row->total_credit;
            $net = $debit - $credit;
            
            $total_debit += $debit;
            $total_credit += $credit;
            
            $label = self::getAccountLabel($row->compte_num);
            
            $lines[] = implode(';', [
                $row->compte_num,
                $label,
                number_format($debit, 2, '.', ','),
                number_format($credit, 2, '.', ','),
                number_format($net, 2, '.', ',')
            ]);
        }
        
        // Totals
        $lines[] = '';
        $lines[] = implode(';', [
            'TOTALS',
            '',
            number_format($total_debit, 2, '.', ','),
            number_format($total_credit, 2, '.', ','),
            number_format($total_debit - $total_credit, 2, '.', ',')
        ]);
        
        // Balance check
        if (round($total_debit, 2) !== round($total_credit, 2)) {
            $lines[] = '';
            $lines[] = 'WARNING: Unbalanced!';
            $lines[] = 'Difference: ' . number_format(abs($total_debit - $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 (e.g., 6061 → search 606 then 60)
        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'];
            }
        }
        
        // Fallback
        return 'Account ' . $account_num;
    }
}
