<?php
// Fichier : src/Services/JournalEntryGenerator.php
// Version 5.0 - Ajout generatePayrollEntries() pour connexion Hub Paie

namespace ComptaFlowPro\Services;

use ComptaFlowPro\Services\ChartOfAccounts;

defined('ABSPATH') || exit;

class JournalEntryGenerator {
    
    /**
     * Génère les écritures pour les opérations financières
     */
    public static function generateFinancialEntries(array $financialData, int $transaction_id): void {
        global $wpdb;
        $p = $wpdb->prefix . 'cfp_';
        
        $date = $financialData['date_txn'];
        $amount = floatval($financialData['amount_ttc']);
        $libelle = $financialData['label'];
        $user_id = $financialData['created_by'] ?? get_current_user_id();
        $payment_status = $financialData['payment_status'] ?? 'PAID';
        
        $base_data = [
            'transaction_id' => $transaction_id,
            'date_ecriture' => $date,
            'journal_code' => 'OD',
            'piece_ref' => $financialData['piece_ref'] ?? null,
            'created_by' => $user_id,
            'source' => 'FINANCIAL',
        ];

        $entry_lines = [];
        
        switch ($financialData['type']) {
            case 'CAPITAL_IN_KIND':
                $meta = json_decode($financialData['meta_json'] ?? '{}', true);
                $asset_account = $meta['asset_account'] ?? '2183';
                $entry_lines = [
                    ['compte_num' => $asset_account, 'libelle' => 'Apport en nature - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                    ['compte_num' => '101', 'libelle' => 'Augmentation capital par apport en nature', 'debit' => 0, 'credit' => $amount]
                ];
                break;

            case 'CAPITAL_INCREASE':
            case 'CAPITAL_CASH_INJECTION':
                if ($payment_status === 'PAID') {
                    $entry_lines = [
                        ['compte_num' => '512', 'libelle' => $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '101', 'libelle' => 'Augmentation de capital social', 'debit' => 0, 'credit' => $amount]
                    ];
                } else {
                    $entry_lines = [
                        ['compte_num' => '4562', 'libelle' => 'Capital appelé, non versé', 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '101', 'libelle' => 'Capital social', 'debit' => 0, 'credit' => $amount]
                    ];
                }
                break;

            case 'CAPITAL_CONTRIBUTION':
                if ($payment_status === 'PAID') {
                    $entry_lines = [
                        ['compte_num' => '512', 'libelle' => 'Apport en compte courant', 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '455', 'libelle' => $libelle, 'debit' => 0, 'credit' => $amount]
                    ];
                } else {
                    $entry_lines = [
                        ['compte_num' => '467', 'libelle' => 'Apport promis - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '455', 'libelle' => 'Compte courant associé', 'debit' => 0, 'credit' => $amount]
                    ];
                }
                break;

            case 'OWNER_DRAWING':
                if ($payment_status === 'PAID') {
                    $entry_lines = [
                        ['compte_num' => '455', 'libelle' => $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '512', 'libelle' => 'Remboursement de compte courant', 'debit' => 0, 'credit' => $amount]
                    ];
                } else {
                    $entry_lines = [
                        ['compte_num' => '455', 'libelle' => 'Retrait compte courant - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '401', 'libelle' => 'Dette envers associé', 'debit' => 0, 'credit' => $amount]
                    ];
                }
                break;

            case 'CC_TO_CAPITAL':
                if ($payment_status === 'PAID') {
                    $entry_lines = [
                        ['compte_num' => '455', 'libelle' => 'Conversion CC en capital - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '101', 'libelle' => 'Augmentation capital par conversion CC', 'debit' => 0, 'credit' => $amount]
                    ];
                } else {
                    $entry_lines = [
                        ['compte_num' => '455', 'libelle' => 'CC à convertir - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '4562', 'libelle' => 'Capital à formaliser', 'debit' => 0, 'credit' => $amount]
                    ];
                }
                break;

            case 'CC_INTEREST':
                if ($payment_status === 'PAID') {
                    $entry_lines = [
                        ['compte_num' => '6615', 'libelle' => 'Intérêts compte courant - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '455', 'libelle' => 'Crédit compte courant associé', 'debit' => 0, 'credit' => $amount]
                    ];
                } else {
                    $entry_lines = [
                        ['compte_num' => '6615', 'libelle' => 'Intérêts courus - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '4558', 'libelle' => 'Intérêts courus à inscrire', 'debit' => 0, 'credit' => $amount]
                    ];
                }
                break;

            case 'DIVIDEND_TO_CC':
                if ($payment_status === 'PAID') {
                    $entry_lines = [
                        ['compte_num' => '457', 'libelle' => 'Dividendes votés - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '455', 'libelle' => 'Crédit compte courant associé', 'debit' => 0, 'credit' => $amount]
                    ];
                } else {
                    $entry_lines = [
                        ['compte_num' => '457', 'libelle' => 'Dividendes à affecter - ' . $libelle, 'debit' => 0, 'credit' => $amount]
                    ];
                }
                break;
            
            case 'LOAN_RECEIVED':
                if ($payment_status === 'PAID') {
                    $entry_lines = [
                        ['compte_num' => '512', 'libelle' => 'Réception des fonds de l\'emprunt', 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '164', 'libelle' => $libelle, 'debit' => 0, 'credit' => $amount]
                    ];
                } else {
                    $entry_lines = [
                        ['compte_num' => '467', 'libelle' => 'Créance sur banque - Emprunt en attente', 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '164', 'libelle' => 'Emprunt contracté - ' . $libelle, 'debit' => 0, 'credit' => $amount]
                    ];
                }
                break;
                
            case 'LOAN_REPAYMENT':
                if ($payment_status === 'PAID') {
                    $entry_lines = [
                        ['compte_num' => '164', 'libelle' => 'Remboursement emprunt - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '512', 'libelle' => 'Virement remboursement emprunt', 'debit' => 0, 'credit' => $amount]
                    ];
                } else {
                    $entry_lines = [
                        ['compte_num' => '164', 'libelle' => 'Remboursement emprunt dû - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '1688', 'libelle' => 'Dette de remboursement à régler', 'debit' => 0, 'credit' => $amount]
                    ];
                }
                break;
                
            case 'INTEREST_PAYMENT':
                if ($payment_status === 'PAID') {
                    $entry_lines = [
                        ['compte_num' => '661', 'libelle' => 'Intérêts d\'emprunt - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '512', 'libelle' => 'Paiement intérêts', 'debit' => 0, 'credit' => $amount]
                    ];
                } else {
                    $entry_lines = [
                        ['compte_num' => '661', 'libelle' => 'Intérêts courus - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '1688', 'libelle' => 'Intérêts courus à payer', 'debit' => 0, 'credit' => $amount]
                    ];
                }
                break;
            
            case 'VAT_PAYMENT':
                if ($payment_status === 'PAID') {
                    $entry_lines = [
                        ['compte_num' => '44551', 'libelle' => 'Paiement TVA due - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '512', 'libelle' => 'Virement TVA', 'debit' => 0, 'credit' => $amount]
                    ];
                } else {
                    $entry_lines = [
                        ['compte_num' => '44551', 'libelle' => 'TVA à payer - ' . $libelle, 'debit' => 0, 'credit' => $amount]
                    ];
                }
                break;
                
            case 'CORPORATE_TAX':
                if ($payment_status === 'PAID') {
                    $entry_lines = [
                        ['compte_num' => '444', 'libelle' => 'Paiement IS - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '512', 'libelle' => 'Virement impôt', 'debit' => 0, 'credit' => $amount]
                    ];
                } else {
                    $entry_lines = [
                        ['compte_num' => '444', 'libelle' => 'IS à payer - ' . $libelle, 'debit' => 0, 'credit' => $amount]
                    ];
                }
                break;
                
            case 'DIVIDEND_PAYMENT':
                if ($payment_status === 'PAID') {
                    $entry_lines = [
                        ['compte_num' => '457', 'libelle' => 'Distribution dividendes - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                        ['compte_num' => '512', 'libelle' => 'Virement dividendes', 'debit' => 0, 'credit' => $amount]
                    ];
                } else {
                    $entry_lines = [
                        ['compte_num' => '457', 'libelle' => 'Dividendes à payer - ' . $libelle, 'debit' => 0, 'credit' => $amount]
                    ];
                }
                break;
            
            case 'BANK_TRANSFER':
                $meta = json_decode($financialData['meta_json'] ?? '{}', true);
                $source_account = $meta['source_account'] ?? '512';
                $dest_account = $meta['dest_account'] ?? '512';
                $entry_lines = [
                    ['compte_num' => $dest_account, 'libelle' => 'Virement reçu - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                    ['compte_num' => $source_account, 'libelle' => 'Virement émis - ' . $libelle, 'debit' => 0, 'credit' => $amount]
                ];
                break;
                
            case 'CASH_DEPOSIT':
                $entry_lines = [
                    ['compte_num' => '512', 'libelle' => 'Dépôt espèces - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                    ['compte_num' => '530', 'libelle' => 'Sortie de caisse', 'debit' => 0, 'credit' => $amount]
                ];
                break;
                
            case 'CASH_WITHDRAWAL':
                $entry_lines = [
                    ['compte_num' => '530', 'libelle' => 'Retrait espèces - ' . $libelle, 'debit' => $amount, 'credit' => 0],
                    ['compte_num' => '512', 'libelle' => 'Retrait bancaire', 'debit' => 0, 'credit' => $amount]
                ];
                break;
            
            case 'BANK_FEES':
            case 'LEGAL_FEES':
            case 'ACCOUNTING_FEES':
                $amount_ht = floatval($financialData['amount_ht']);
                $amount_tva = floatval($financialData['amount_tva']);
                $charge_account = '627';
                if ($financialData['type'] === 'LEGAL_FEES' || $financialData['type'] === 'ACCOUNTING_FEES') {
                    $charge_account = '6226';
                }
                
                if ($payment_status === 'PAID') {
                    $entry_lines = [
                        ['compte_num' => $charge_account, 'libelle' => $libelle, 'debit' => $amount_ht, 'credit' => 0],
                        ['compte_num' => '44566', 'libelle' => 'TVA déductible', 'debit' => $amount_tva, 'credit' => 0],
                        ['compte_num' => '512', 'libelle' => 'Règlement', 'debit' => 0, 'credit' => $amount]
                    ];
                } else {
                    $entry_lines = [
                        ['compte_num' => $charge_account, 'libelle' => $libelle, 'debit' => $amount_ht, 'credit' => 0],
                        ['compte_num' => '44566', 'libelle' => 'TVA déductible', 'debit' => $amount_tva, 'credit' => 0],
                        ['compte_num' => '401', 'libelle' => 'Dette fournisseur', 'debit' => 0, 'credit' => $amount]
                    ];
                }
                break;
        }

        foreach ($entry_lines as $line) {
            $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
                'uuid' => wp_generate_uuid4(),
                'compte_num' => $line['compte_num'],
                'libelle' => $line['libelle'],
                'debit' => $line['debit'],
                'credit' => $line['credit'],
            ]));
        }
    }
    
    public static function generatePaymentEntry(array $transaction, int $transaction_id): void {
        global $wpdb;
        $p = $wpdb->prefix . 'cfp_';
        
        $date = date('Y-m-d');
        $amount = floatval($transaction['amount_ttc']);
        $type = $transaction['type'];
        $libelle = $transaction['label'];
        
        $base_data = [
            'transaction_id' => $transaction_id,
            'date_ecriture' => $date,
            'journal_code' => 'TR',
            'created_by' => get_current_user_id(),
            'source' => 'FINANCIAL_PAYMENT',
        ];
        
        $entry_lines = [];
        
        switch ($type) {
            case 'CAPITAL_INCREASE': 
            case 'CAPITAL_CASH_INJECTION':
                $entry_lines = [
                    ['compte_num' => '512', 'libelle' => 'Encaissement capital', 'debit' => $amount, 'credit' => 0], 
                    ['compte_num' => '4562', 'libelle' => 'Apurement capital appelé', 'debit' => 0, 'credit' => $amount]
                ];
                break;
                
            case 'CAPITAL_CONTRIBUTION':
                $entry_lines = [
                    ['compte_num' => '512', 'libelle' => 'Encaissement apport', 'debit' => $amount, 'credit' => 0], 
                    ['compte_num' => '467', 'libelle' => 'Apurement créance apport', 'debit' => 0, 'credit' => $amount]
                ];
                break;
                
            case 'OWNER_DRAWING':
                $entry_lines = [
                    ['compte_num' => '401', 'libelle' => 'Paiement retrait associé', 'debit' => $amount, 'credit' => 0], 
                    ['compte_num' => '512', 'libelle' => 'Virement retrait', 'debit' => 0, 'credit' => $amount]
                ];
                break;
                
            case 'CC_TO_CAPITAL':
                $entry_lines = [
                    ['compte_num' => '4562', 'libelle' => 'Capital formalisé', 'debit' => $amount, 'credit' => 0], 
                    ['compte_num' => '101', 'libelle' => 'Augmentation capital enregistrée', 'debit' => 0, 'credit' => $amount]
                ];
                break;
                
            case 'CC_INTEREST':
                $entry_lines = [
                    ['compte_num' => '4558', 'libelle' => 'Intérêts inscrits', 'debit' => $amount, 'credit' => 0], 
                    ['compte_num' => '455', 'libelle' => 'Crédit compte courant', 'debit' => 0, 'credit' => $amount]
                ];
                break;
                
            case 'DIVIDEND_TO_CC':
                $entry_lines = [
                    ['compte_num' => '457', 'libelle' => 'Dividendes affectés', 'debit' => $amount, 'credit' => 0], 
                    ['compte_num' => '455', 'libelle' => 'Crédit compte courant', 'debit' => 0, 'credit' => $amount]
                ];
                break;
                
            case 'LOAN_RECEIVED':
                $entry_lines = [
                    ['compte_num' => '512', 'libelle' => 'Réception emprunt', 'debit' => $amount, 'credit' => 0], 
                    ['compte_num' => '467', 'libelle' => 'Apurement créance banque', 'debit' => 0, 'credit' => $amount]
                ];
                break;
                
            case 'LOAN_REPAYMENT':
                $entry_lines = [
                    ['compte_num' => '1688', 'libelle' => 'Règlement remboursement', 'debit' => $amount, 'credit' => 0], 
                    ['compte_num' => '512', 'libelle' => 'Virement effectué', 'debit' => 0, 'credit' => $amount]
                ];
                break;
                
            case 'VAT_PAYMENT':
                $entry_lines = [
                    ['compte_num' => '44551', 'libelle' => 'Règlement TVA', 'debit' => $amount, 'credit' => 0], 
                    ['compte_num' => '512', 'libelle' => 'Virement effectué', 'debit' => 0, 'credit' => $amount]
                ];
                break;
                
            case 'CORPORATE_TAX':
                $entry_lines = [
                    ['compte_num' => '444', 'libelle' => 'Règlement IS', 'debit' => $amount, 'credit' => 0], 
                    ['compte_num' => '512', 'libelle' => 'Virement effectué', 'debit' => 0, 'credit' => $amount]
                ];
                break;
                
            case 'DIVIDEND_PAYMENT':
                $entry_lines = [
                    ['compte_num' => '457', 'libelle' => 'Règlement dividendes', 'debit' => $amount, 'credit' => 0], 
                    ['compte_num' => '512', 'libelle' => 'Virement effectué', 'debit' => 0, 'credit' => $amount]
                ];
                break;
                
            case 'INTEREST_PAYMENT':
                $entry_lines = [
                    ['compte_num' => '1688', 'libelle' => 'Paiement intérêts', 'debit' => $amount, 'credit' => 0], 
                    ['compte_num' => '512', 'libelle' => 'Virement intérêts', 'debit' => 0, 'credit' => $amount]
                ];
                break;
                
            case 'BANK_FEES': 
            case 'LEGAL_FEES': 
            case 'ACCOUNTING_FEES':
                $entry_lines = [
                    ['compte_num' => '401', 'libelle' => 'Règlement - ' . $libelle, 'debit' => $amount, 'credit' => 0], 
                    ['compte_num' => '512', 'libelle' => 'Paiement effectué', 'debit' => 0, 'credit' => $amount]
                ];
                break;
        }
        
        foreach ($entry_lines as $line) {
            $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
                'uuid' => wp_generate_uuid4(),
                'compte_num' => $line['compte_num'],
                'libelle' => $line['libelle'],
                'debit' => $line['debit'],
                'credit' => $line['credit'],
            ]));
        }
    }
    
    public static function generateSaleEntries(array $saleData, int $transaction_id): void {
        global $wpdb; 
        $p = $wpdb->prefix . 'cfp_';
        $date = $saleData['date_txn'];
        $partner = $saleData['partner_name'] ?: 'Client';
        $user_id = $saleData['created_by'] ?? get_current_user_id();
        
        $base_data = [
            'transaction_id' => $transaction_id, 
            'date_ecriture' => $date, 
            'journal_code' => 'VE', 
            'piece_ref' => $saleData['piece_ref'] ?? null, 
            'created_by' => $user_id, 
            'source' => 'SALE'
        ];
        
        $revenue_account = $saleData['account_code'] ?? '706';
        $revenue_label_desc = ChartOfAccounts::getAccount($revenue_account)['label'] ?? 'Prestation de service';
        
        $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
            'uuid' => wp_generate_uuid4(), 
            'compte_num' => $revenue_account, 
            'libelle' => sprintf('%s | %s | %s', $revenue_label_desc, date_i18n('d/m/Y', strtotime($date)), $partner), 
            'debit' => 0, 
            'credit' => $saleData['amount_ht']
        ]));
        
        if ($saleData['amount_tva'] > 0) {
            $vat_rate_formatted = number_format($saleData['vat_rate'], 2);
            $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
                'uuid' => wp_generate_uuid4(), 
                'compte_num' => '44571', 
                'libelle' => sprintf('TVA collectée (%s%%) | %s | %s', $vat_rate_formatted, date_i18n('d/m/Y', strtotime($date)), $partner), 
                'debit' => 0, 
                'credit' => $saleData['amount_tva']
            ]));
        }
        
        $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
            'uuid' => wp_generate_uuid4(), 
            'compte_num' => '411', 
            'partner_code' => '', 
            'libelle' => sprintf('Créance client | %s | %s', date_i18n('d/m/Y', strtotime($date)), $partner), 
            'debit' => $saleData['amount_ttc'], 
            'credit' => 0
        ]));
        
        if ($saleData['payment_status'] === 'PAID') {
            $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
                'uuid' => wp_generate_uuid4(), 
                'compte_num' => '411', 
                'partner_code' => '', 
                'libelle' => sprintf('Encaissement client | %s | %s', date_i18n('d/m/Y', strtotime($date)), $partner), 
                'debit' => 0, 
                'credit' => $saleData['amount_ttc']
            ]));
            
            $treasury_account = self::getTreasuryAccountForSale($saleData['payment_method']);
            $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
                'uuid' => wp_generate_uuid4(), 
                'compte_num' => $treasury_account, 
                'libelle' => sprintf('Encaissement client | %s | %s', date_i18n('d/m/Y', strtotime($date)), $partner), 
                'debit' => $saleData['amount_ttc'], 
                'credit' => 0
            ]));
        }
    }
    
    public static function generateExpenseEntries(array $expenseData, int $transaction_id): void {
        global $wpdb; 
        $p = $wpdb->prefix . 'cfp_';
        $date = $expenseData['date_txn'];
        $partner = $expenseData['partner_name'] ?: 'Fournisseur';
        $user_id = $expenseData['created_by'] ?? get_current_user_id();
        
        $base_data = [
            'transaction_id' => $transaction_id, 
            'date_ecriture' => $date, 
            'journal_code' => 'AC', 
            'piece_ref' => $expenseData['piece_ref'] ?? null, 
            'created_by' => $user_id, 
            'source' => 'EXPENSE'
        ];
        
        $charge_account = $expenseData['account_code'] ?? '6061';
        $charge_label_desc = ChartOfAccounts::getAccount($charge_account)['label'] ?? 'Charge diverse';
        
        $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
            'uuid' => wp_generate_uuid4(), 
            'compte_num' => $charge_account, 
            'libelle' => sprintf('%s | %s | %s', $charge_label_desc, date_i18n('d/m/Y', strtotime($date)), $partner), 
            'debit' => $expenseData['amount_ht'], 
            'credit' => 0
        ]));
        
        if ($expenseData['amount_tva'] > 0) {
            $vat_rate_formatted = number_format($expenseData['vat_rate'], 2);
            $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
                'uuid' => wp_generate_uuid4(), 
                'compte_num' => '44566', 
                'libelle' => sprintf('TVA déductible (%s%%) | %s | %s', $vat_rate_formatted, date_i18n('d/m/Y', strtotime($date)), $partner), 
                'debit' => $expenseData['amount_tva'], 
                'credit' => 0
            ]));
        }
        
        $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
            'uuid' => wp_generate_uuid4(), 
            'compte_num' => '401', 
            'partner_code' => '', 
            'libelle' => sprintf('Dette fournisseur | %s | %s', date_i18n('d/m/Y', strtotime($date)), $partner), 
            'debit' => 0, 
            'credit' => $expenseData['amount_ttc']
        ]));
        
        if ($expenseData['payment_status'] === 'PAID') {
            $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
                'uuid' => wp_generate_uuid4(), 
                'compte_num' => '401', 
                'partner_code' => '', 
                'libelle' => sprintf('Règlement fournisseur | %s | %s', date_i18n('d/m/Y', strtotime($date)), $partner), 
                'debit' => $expenseData['amount_ttc'], 
                'credit' => 0
            ]));
            
            $treasury_account = self::getTreasuryAccountForExpense($expenseData['payment_method']);
            $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
                'uuid' => wp_generate_uuid4(), 
                'compte_num' => $treasury_account, 
                'libelle' => sprintf('Règlement fournisseur | %s | %s', date_i18n('d/m/Y', strtotime($date)), $partner), 
                'debit' => 0, 
                'credit' => $expenseData['amount_ttc']
            ]));
        }
    }
    
    /**
     * NOUVELLE MÉTHODE - Génère les écritures de paie liées au Hub
     */
    public static function generatePayrollEntries(array $payrollData): void {
        global $wpdb;
        $p = $wpdb->prefix . 'cfp_';

        $base_data = [
            'transaction_id' => $payrollData['transaction_id'],
            'date_ecriture' => $payrollData['period_end'],
            'journal_code' => 'OD',
            'created_by' => get_current_user_id(),
            'source' => 'PAYROLL',
        ];

        $employee_name = $payrollData['employee_name'];

        // 1. Charge de salaire brut (641)
        $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
            'uuid' => wp_generate_uuid4(),
            'compte_num' => '641',
            'libelle' => "Salaire Brut - $employee_name",
            'debit' => $payrollData['gross_salary'],
            'credit' => 0,
        ]));

        // 2. Charges patronales (645)
        $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
            'uuid' => wp_generate_uuid4(),
            'compte_num' => '645',
            'libelle' => "Charges Patronales - $employee_name",
            'debit' => $payrollData['employer_contrib'],
            'credit' => 0,
        ]));

        // 3. Net à payer (421)
        $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
            'uuid' => wp_generate_uuid4(),
            'compte_num' => '421',
            'libelle' => "Net à Payer - $employee_name",
            'debit' => 0,
            'credit' => $payrollData['net_pay'],
        ]));

        // 4. Dettes sociales URSSAF (431)
        $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
            'uuid' => wp_generate_uuid4(),
            'compte_num' => '431',
            'libelle' => "Dettes Sociales (URSSAF) - $employee_name",
            'debit' => 0,
            'credit' => $payrollData['total_social_charges'],
        ]));

        // 5. Prélèvement à la source (4421)
        if ($payrollData['withholding_tax'] > 0) {
            $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
                'uuid' => wp_generate_uuid4(),
                'compte_num' => '4421',
                'libelle' => "Prélèvement à la Source - $employee_name",
                'debit' => 0,
                'credit' => $payrollData['withholding_tax'],
            ]));
        }

        // 6. Si le salaire est déjà payé, générer l'écriture de trésorerie
        if ($payrollData['is_paid']) {
            $base_data['journal_code'] = 'TR';
            $base_data['source'] = 'PAYROLL_PAYMENT';

            $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
                'uuid' => wp_generate_uuid4(),
                'compte_num' => '421',
                'libelle' => "Paiement Net - $employee_name",
                'debit' => $payrollData['net_pay'],
                'credit' => 0,
            ]));

            $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
                'uuid' => wp_generate_uuid4(),
                'compte_num' => '512',
                'libelle' => "Virement Salaire - $employee_name",
                'debit' => 0,
                'credit' => $payrollData['net_pay'],
            ]));
        }
    }
    
    /**
     * Genere les ecritures comptables pour une facture validee
     * Support multi-comptes : une ecriture par couple (compte, taux TVA)
     * Debit 411 (Clients) / Credit 7xx (Produits) + 44571 (TVA collectee)
     */
    public static function generateInvoiceEntries(array $invoiceData, int $transaction_id): void {
        global $wpdb;
        $p = $wpdb->prefix . 'cfp_';

        $date = $invoiceData['date_txn'];
        $partner = $invoiceData['partner_name'] ?: 'Client';
        $piece_ref = $invoiceData['piece_ref'] ?? '';
        $user_id = $invoiceData['created_by'] ?? get_current_user_id();

        $base_data = [
            'transaction_id' => $transaction_id,
            'date_ecriture' => $date,
            'journal_code' => 'VE',
            'piece_ref' => $piece_ref,
            'created_by' => $user_id,
            'source' => 'INVOICE',
        ];

        // Recuperer les lignes de la facture pour ecritures multi-comptes
        $invoice_id = $invoiceData['invoice_id'] ?? null;
        $lines = [];

        if ($invoice_id) {
            $lines = $wpdb->get_results($wpdb->prepare(
                "SELECT account_code, vat_rate, SUM(total_ht) as total_ht, SUM(total_tva) as total_tva
                 FROM {$p}invoice_lines
                 WHERE invoice_id = %d
                 GROUP BY account_code, vat_rate",
                $invoice_id
            ), ARRAY_A);
        }

        // Fallback mono-compte si pas de lignes detaillees
        if (empty($lines)) {
            $lines = [[
                'account_code' => $invoiceData['account_code'] ?? '706',
                'vat_rate' => $invoiceData['vat_rate'] ?? 20,
                'total_ht' => $invoiceData['amount_ht'],
                'total_tva' => $invoiceData['amount_tva'],
            ]];
        }

        // Generer une ecriture par couple (compte, taux TVA)
        foreach ($lines as $line) {
            $account_code = $line['account_code'] ?? '706';
            $vat_rate = floatval($line['vat_rate'] ?? 20);
            $total_ht = floatval($line['total_ht']);
            $total_tva = floatval($line['total_tva']);

            $account_info = ChartOfAccounts::getAccount($account_code);
            $account_label = $account_info['label'] ?? 'Produit';

            // Credit compte de produit (701, 706, 707, etc.)
            $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
                'uuid' => wp_generate_uuid4(),
                'compte_num' => $account_code,
                'libelle' => sprintf('%s | %s | %s', $account_label, $piece_ref, $partner),
                'debit' => 0,
                'credit' => $total_ht,
            ]));

            // Credit TVA collectee (si TVA > 0)
            if ($total_tva > 0) {
                $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
                    'uuid' => wp_generate_uuid4(),
                    'compte_num' => '44571',
                    'libelle' => sprintf('TVA collectee (%.2f%%) | %s | %s', $vat_rate, $piece_ref, $partner),
                    'debit' => 0,
                    'credit' => $total_tva,
                ]));
            }
        }

        // Debit compte client (411) - Montant total TTC
        $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
            'uuid' => wp_generate_uuid4(),
            'compte_num' => '411',
            'partner_code' => $invoiceData['partner_code'] ?? '',
            'libelle' => sprintf('Creance client | %s | %s', $piece_ref, $partner),
            'debit' => $invoiceData['amount_ttc'],
            'credit' => 0,
        ]));
    }

    /**
     * Genere les ecritures de paiement pour une facture encaissee
     * Debit 512 (Banque) / Credit 411 (Clients)
     */
    public static function generateInvoicePaymentEntries(array $paymentData, int $transaction_id): void {
        global $wpdb;
        $p = $wpdb->prefix . 'cfp_';

        $date = $paymentData['date_txn'];
        $partner = $paymentData['partner_name'] ?: 'Client';
        $piece_ref = $paymentData['piece_ref'] ?? '';
        $amount = floatval($paymentData['amount_ttc']);

        $base_data = [
            'transaction_id' => $transaction_id,
            'date_ecriture' => $date,
            'journal_code' => 'BQ',
            'piece_ref' => $piece_ref,
            'created_by' => get_current_user_id(),
            'source' => 'INVOICE_PAYMENT',
        ];

        $treasury_account = self::getTreasuryAccountForSale($paymentData['payment_method'] ?? 'VIREMENT');

        // Credit compte client (411) - Solde la creance
        $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
            'uuid' => wp_generate_uuid4(),
            'compte_num' => '411',
            'libelle' => sprintf('Encaissement client | %s | %s', $piece_ref, $partner),
            'debit' => 0,
            'credit' => $amount,
        ]));

        // Debit compte tresorerie (512 Banque, 530 Caisse, etc.)
        $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
            'uuid' => wp_generate_uuid4(),
            'compte_num' => $treasury_account,
            'libelle' => sprintf('Encaissement client | %s | %s', $piece_ref, $partner),
            'debit' => $amount,
            'credit' => 0,
        ]));
    }

    public static function generateFromArray(array $entry_data): bool {
        global $wpdb; 
        $p = $wpdb->prefix . 'cfp_';
        
        if (!isset($entry_data['lines']) || !is_array($entry_data['lines'])) { 
            return false; 
        }
        
        $base_data = [
            'date_ecriture' => $entry_data['date_ecriture'], 
            'journal_code' => $entry_data['journal_code'] ?? 'OD', 
            'piece_ref' => $entry_data['piece_ref'] ?? null, 
            'created_by' => get_current_user_id(), 
            'source' => $entry_data['source'] ?? 'MANUAL', 
            'ecriture_num' => $entry_data['ecriture_num'] ?? null
        ];
        
        foreach ($entry_data['lines'] as $line) {
            $wpdb->insert($p . 'journal_entries', array_merge($base_data, [
                'uuid' => wp_generate_uuid4(), 
                'compte_num' => $line['compte_num'], 
                'libelle' => $line['libelle'], 
                'debit' => $line['debit'] ?? 0, 
                'credit' => $line['credit'] ?? 0
            ]));
        }
        
        return true;
    }
    
    private static function getTreasuryAccountForSale(string $payment_method): string {
        $accounts = [
            'CB' => '512', 
            'VIREMENT' => '512', 
            'ESPECES' => '530', 
            'CHEQUE' => '512'
        ];
        return $accounts[$payment_method] ?? '512';
    }
    
    private static function getTreasuryAccountForExpense(string $payment_method): string {
        $accounts = [
            'CB' => '512', 
            'VIREMENT' => '512', 
            'ESPECES' => '530', 
            'CHEQUE' => '512'
        ];
        return $accounts[$payment_method] ?? '512';
    }
}