<?php
namespace ComptaFlowPro\Services;

defined('ABSPATH') || exit;

class CompteResultatExporter
{
    /**
     * Generate and download the Income Statement
     * Revenue/Expenses summary according to French Chart of Accounts
     */
    public static function export(int $user_id, string $start_date, string $end_date): void
    {
        global $wpdb;
        $journal_table = $wpdb->prefix . 'cfp_journal_entries';
        
        // Retrieve management accounts (classes 6 and 7)
        $entries = $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
             AND (compte_num LIKE '6%%' OR compte_num LIKE '7%%')
             GROUP BY compte_num
             ORDER BY compte_num ASC",
            $user_id, $start_date, $end_date
        ));
        
        if (empty($entries)) {
            wp_die(esc_html__('No management entries found for this period.', 'comptaflow-by-meetempo'));
        }
        
        // Generate CSV
        $content = self::generateCompteResultatContent($entries, $start_date, $end_date);
        
        // Download headers
        $filename = 'IncomeStatement_' . 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
        echo $content;
        exit;
    }
    
    private static function generateCompteResultatContent(array $entries, string $start_date, string $end_date): string
    {
        $lines = [];
        
        // Header
        $lines[] = 'INCOME STATEMENT';
        $lines[] = 'Period from ' . gmdate('d/m/Y', strtotime($start_date)) . ' to ' . gmdate('d/m/Y', strtotime($end_date));
        $lines[] = '';
        
        // Separate expenses/revenue
        $charges = [];
        $produits = [];
        
        foreach ($entries as $entry) {
            $compte_num = $entry->compte_num;
            $debit = (float)$entry->total_debit;
            $credit = (float)$entry->total_credit;
            $solde = $debit - $credit;
            
            if (strpos($compte_num, '6') === 0) {
                $charges[] = ['compte' => $compte_num, 'montant' => $solde];
            } elseif (strpos($compte_num, '7') === 0) {
                $produits[] = ['compte' => $compte_num, 'montant' => -$solde];
            }
        }
        
        // Group
        $charges_grouped = self::groupCharges($charges);
        $produits_grouped = self::groupProduits($produits);
        
        // EXPENSES
        $lines[] = 'EXPENSES;Amount';
        $lines[] = '═════════════════════════════════════════════';
        
        $total_charges = 0;
        foreach ($charges_grouped as $category => $montant) {
            $total_charges += $montant;
            $lines[] = $category . ';' . number_format($montant, 2, ',', ' ') . ' €';
        }
        
        $lines[] = '';
        $lines[] = 'TOTAL EXPENSES;' . number_format($total_charges, 2, ',', ' ') . ' €';
        $lines[] = '';
        
        // REVENUE
        $lines[] = 'REVENUE;Amount';
        $lines[] = '═════════════════════════════════════════════';
        
        $total_produits = 0;
        foreach ($produits_grouped as $category => $montant) {
            $total_produits += $montant;
            $lines[] = $category . ';' . number_format($montant, 2, ',', ' ') . ' €';
        }
        
        $lines[] = '';
        $lines[] = 'TOTAL REVENUE;' . number_format($total_produits, 2, ',', ' ') . ' €';
        $lines[] = '';
        
        // RESULT
        $resultat = $total_produits - $total_charges;
        $lines[] = '═════════════════════════════════════════════';
        if ($resultat >= 0) {
            $lines[] = 'NET RESULT (Profit);' . number_format($resultat, 2, ',', ' ') . ' €';
        } else {
            $lines[] = 'NET RESULT (Loss);' . number_format($resultat, 2, ',', ' ') . ' €';
        }
        $lines[] = '═════════════════════════════════════════════';
        
        return implode("\n", $lines);
    }
    
    private static function groupCharges(array $charges): array
    {
        $grouped = [
            'Stocked purchases (601-602)' => 0,
            'Non-stocked purchases (606)' => 0,
            'Merchandise purchases (607)' => 0,
            'External services (61-62)' => 0,
            'Taxes and duties (63)' => 0,
            'Personnel costs (64)' => 0,
            'Other expenses (65)' => 0,
            'Financial charges (66)' => 0,
            'Depreciation (68)' => 0,
        ];
        
        foreach ($charges as $charge) {
            $compte = $charge['compte'];
            $montant = $charge['montant'];
            
            if (strpos($compte, '601') === 0 || strpos($compte, '602') === 0) {
                $grouped['Stocked purchases (601-602)'] += $montant;
            } elseif (strpos($compte, '606') === 0) {
                $grouped['Non-stocked purchases (606)'] += $montant;
            } elseif (strpos($compte, '607') === 0) {
                $grouped['Merchandise purchases (607)'] += $montant;
            } elseif (strpos($compte, '61') === 0 || strpos($compte, '62') === 0) {
                $grouped['External services (61-62)'] += $montant;
            } elseif (strpos($compte, '63') === 0) {
                $grouped['Taxes and duties (63)'] += $montant;
            } elseif (strpos($compte, '64') === 0) {
                $grouped['Personnel costs (64)'] += $montant;
            } elseif (strpos($compte, '65') === 0) {
                $grouped['Other expenses (65)'] += $montant;
            } elseif (strpos($compte, '66') === 0) {
                $grouped['Financial charges (66)'] += $montant;
            } elseif (strpos($compte, '68') === 0) {
                $grouped['Depreciation (68)'] += $montant;
            }
        }
        
        return array_filter($grouped, function($v) { return $v != 0; });
    }
    
    private static function groupProduits(array $produits): array
    {
        $grouped = [
            'Merchandise sales (707)' => 0,
            'Service revenue (706)' => 0,
            'Production sold (701-704)' => 0,
            'Commissions (7082)' => 0,
            'Grants (74)' => 0,
            'Other revenue (75-78)' => 0,
        ];
        
        foreach ($produits as $produit) {
            $compte = $produit['compte'];
            $montant = $produit['montant'];
            
            if (strpos($compte, '707') === 0) {
                $grouped['Merchandise sales (707)'] += $montant;
            } elseif (strpos($compte, '706') === 0) {
                $grouped['Service revenue (706)'] += $montant;
            } elseif (strpos($compte, '701') === 0 || strpos($compte, '704') === 0) {
                $grouped['Production sold (701-704)'] += $montant;
            } elseif (strpos($compte, '7082') === 0) {
                $grouped['Commissions (7082)'] += $montant;
            } elseif (strpos($compte, '74') === 0) {
                $grouped['Grants (74)'] += $montant;
            } elseif (strpos($compte, '75') === 0 || strpos($compte, '76') === 0 || strpos($compte, '78') === 0) {
                $grouped['Other revenue (75-78)'] += $montant;
            }
        }
        
        return array_filter($grouped, function($v) { return $v != 0; });
    }
}
