<?php
// get_trial_balance.php

header('Content-Type: application/json; charset=utf-8');

try {
    // 1. الاتصال بقاعدة البيانات
    require_once 'db_config.php';

    // استقبال تواريخ الفلترة من الطلب (أو تعيين قيم افتراضية)
    $start_date = $_GET['start_date'] ?? date('Y-01-01');
    $end_date = $_GET['end_date'] ?? date('Y-12-31');
    $comparative = isset($_GET['comparative']) && $_GET['comparative'] === 'true';
    
    // فلتر المشاريع
    $project_filter = [];
    if (!empty($_GET['projects'])) {
        $project_filter = explode(',', $_GET['projects']);
    }

    // 2. جلب شجرة الحسابات الأساسية وتمريرها وفك الـ JSON للتعامل معها
    $stmt = $db->query("SELECT * FROM accounts");
    $accounts = [];
    
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $data = json_decode($row['data'], true);
        $id = $data['id'] ?? $row['id'];
        
        // هيكلة بيانات الحساب استعداداً للتجميع
        $accounts[$id] = [
            'id' => $id,
            'parent_id' => $data['parent_id'] ?? null,
            'name' => $data['name'] ?? 'بدون اسم',
            'code' => $data['code'] ?? '',
            // نهيئ الافتتاحي الديناميكي بنفس الافتتاحي الأصلي مبدئياً
            'dyn_open_debit' => isset($data['open_debit']) ? (float)$data['open_debit'] : 0.0,
            'dyn_open_credit' => isset($data['open_credit']) ? (float)$data['open_credit'] : 0.0,
            // حركات الفترة المحددة تبدأ بصفر
            'period_debit' => 0.0,
            'period_credit' => 0.0,
            'is_parent' => false,
            'level' => 0,
            'period_years' => []
        ];
    }

    // تحديد الحسابات الرئيسية (الآباء)
    foreach ($accounts as $acc) {
        if ($acc['parent_id'] && isset($accounts[$acc['parent_id']])) {
            $accounts[$acc['parent_id']]['is_parent'] = true;
        }
    }

    // ترتيب الحسابات بحسب الكود لكي تتطابق مع شجرة الحسابات
    uasort($accounts, function($a, $b) {
        return strcmp($a['code'] ?? '', $b['code'] ?? '');
    });

    // 3. الاستعلام التجميعي من جدول القيود بناءً على التواريخ
    // بما أن القيود محفوظة بصيغة JSON، يتم قراءتها وتجميعها برمجياً لضمان التوافق المطلق
    $stmt_mov = $db->query("SELECT * FROM journal_entries");
    while ($row = $stmt_mov->fetch(PDO::FETCH_ASSOC)) {
        $je = json_decode($row['data'], true);
        
        // التأكد من صحة القيد ووجود سطور وتاريخ
        if (!$je || !isset($je['date']) || !isset($je['rows'])) continue;
        
        $entry_date = substr($je['date'], 0, 10);
        
        // صب نتائج الحركات المباشرة في الحسابات المرتبطة بها (الأبناء غالباً)
        foreach ($je['rows'] as $r) {
            if (!isset($r['account_id'])) continue;
            
            // تطبيق فلتر المشاريع إذا كان محدداً
            if (!empty($project_filter)) {
                $row_proj = isset($r['project_id']) ? (string)$r['project_id'] : '';
                if (empty($row_proj)) {
                    $row_proj = isset($je['project_id']) ? (string)$je['project_id'] : '';
                }
                if (!in_array($row_proj, $project_filter)) {
                    continue; // تجاهل هذا السطر إذا لم يكن يتبع لأي من المشاريع المحددة
                }
            }
            
            $acc_id = $r['account_id'];
            if (isset($accounts[$acc_id])) {
                $debit = (float)($r['debit'] ?? 0);
                $credit = (float)($r['credit'] ?? 0);
                
                // حركات ما قبل Start_Date تضاف على الافتتاحي الأصلي لتكوين الافتتاحي الديناميكي.
                if ($entry_date < $start_date) {
                    $accounts[$acc_id]['dyn_open_debit'] += $debit;
                    $accounts[$acc_id]['dyn_open_credit'] += $credit;
                } 
                // حركات ما بين Start_Date و End_Date تشكل حركة الفترة (المدة).
                else if ($entry_date >= $start_date && $entry_date <= $end_date) {
                    $accounts[$acc_id]['period_debit'] += $debit;
                    $accounts[$acc_id]['period_credit'] += $credit;
                    
                    if ($comparative) {
                        $year = substr($entry_date, 0, 4);
                        if (!isset($accounts[$acc_id]['period_years'][$year])) {
                            $accounts[$acc_id]['period_years'][$year] = ['debit' => 0, 'credit' => 0];
                        }
                        $accounts[$acc_id]['period_years'][$year]['debit'] += $debit;
                        $accounts[$acc_id]['period_years'][$year]['credit'] += $credit;
                    }
                }
            }
        }
    }

    /**
     * 4. دالة التجميع التصاعدي الشجري (Roll-up Logic) العودية
     * تمر على الحسابات وتجمع قيم الأبناء في الآباء مع تحديد مستوى الإزاحة (Level).
     */
    function calculateRollup(&$accounts, $parentId = null, $level = 0, $comparative = false) {
        $totals = [
            'dyn_open_debit' => 0, 'dyn_open_credit' => 0,
            'period_debit' => 0,   'period_credit' => 0,
            'period_years' => []
        ];
        
        $tree_result = [];

        foreach ($accounts as $id => $acc) {
            // نبحث عن الأبناء المباشرين لهذا الأب
            if ($acc['parent_id'] == $parentId) {
                
                $accounts[$id]['level'] = $level;
                
                // استدعاء عودي (Recursive) لجلب قيم أحفاد هذا الحساب
                $child_result = calculateRollup($accounts, $id, $level + 1, $comparative);
                $child_totals = $child_result['totals'];
                
                // إذا كان حساباً رئيسياً، نضيف مجاميع فروعه إلى أرصدته
                // هذا يضمن اتزان الميزان وعرض الآباء كمجاميع دقيقة لفروعها بالملي.
                if ($accounts[$id]['is_parent']) {
                    $accounts[$id]['dyn_open_debit']  += $child_totals['dyn_open_debit'];
                    $accounts[$id]['dyn_open_credit'] += $child_totals['dyn_open_credit'];
                    $accounts[$id]['period_debit']    += $child_totals['period_debit'];
                    $accounts[$id]['period_credit']   += $child_totals['period_credit'];
                    
                    if ($comparative) {
                        foreach ($child_totals['period_years'] as $yr => $vals) {
                            if (!isset($accounts[$id]['period_years'][$yr])) {
                                $accounts[$id]['period_years'][$yr] = ['debit' => 0, 'credit' => 0];
                            }
                            $accounts[$id]['period_years'][$yr]['debit'] += $vals['debit'];
                            $accounts[$id]['period_years'][$yr]['credit'] += $vals['credit'];
                        }
                    }
                }
                
                // الترتيب: الأب أولاً، ثم أبناؤه تحته مباشرة
                $tree_result[] = $accounts[$id];
                $tree_result = array_merge($tree_result, $child_result['tree']);
                
                // رفع المجاميع للأعلى لكي يستلمها الأب الأكبر
                $totals['dyn_open_debit']  += $accounts[$id]['dyn_open_debit'];
                $totals['dyn_open_credit'] += $accounts[$id]['dyn_open_credit'];
                $totals['period_debit']    += $accounts[$id]['period_debit'];
                $totals['period_credit']   += $accounts[$id]['period_credit'];
                
                if ($comparative) {
                    foreach ($accounts[$id]['period_years'] as $yr => $vals) {
                        if (!isset($totals['period_years'][$yr])) {
                            $totals['period_years'][$yr] = ['debit' => 0, 'credit' => 0];
                        }
                        $totals['period_years'][$yr]['debit'] += $vals['debit'];
                        $totals['period_years'][$yr]['credit'] += $vals['credit'];
                    }
                }
            }
        }
        
        return [
            'totals' => $totals,
            'tree'   => $tree_result
        ];
    }

    // تشغيل التجميع بدءاً من الجذور (الحسابات التي ليس لها parent_id)
    $rollup_result = calculateRollup($accounts, null, 0, $comparative);

    // 5. إرجاع النتيجة النهائية النظيفة
    echo json_encode([
        'status' => 'success',
        'data' => $rollup_result['tree']
    ]);

} catch (Exception $e) {
    echo json_encode([
        'status' => 'error',
        'message' => $e->getMessage()
    ]);
}
