<?php

/**
 * هذا الملف يقوم بإصلاح القيود المحاسبية الموجودة وربطها بالعملاء بشكل صحيح
 * باستخدام معرف العميل (ID) بدلاً من رقم العميل
 */

require_once __DIR__ . '/vendor/autoload.php';

use Illuminate\Support\Facades\Log;

// تهيئة Laravel
$app = require_once __DIR__ . '/bootstrap/app.php';
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();

echo "بدء فحص وإصلاح القيود المحاسبية وربطها بالعملاء بشكل صحيح...\n";

// الحصول على جميع القيود المحاسبية المرحلة
$entries = \App\Models\JournalEntry::where('is_posted', true)->get();

echo "تم العثور على " . $entries->count() . " قيد محاسبي مرحل.\n";

$fixed = 0;
$skipped = 0;
$errors = 0;

foreach ($entries as $entry) {
    echo "\nمعالجة القيد المحاسبي رقم: " . $entry->id . " - رقم القيد: " . $entry->entry_number . "\n";

    try {
        // البحث عن عناصر حساب العميل في هذا القيد المحاسبي
        $customerAccountItems = \App\Models\JournalEntryItem::where('journal_entry_id', $entry->id)
            ->whereHas('account', function ($query) {
                $query->where('account_type', 'asset')
                    ->where(function ($q) {
                        $q->where('sub_type', 'accounts_receivable')
                            ->orWhere('sub_type', 'customer_receivable');
                    });
            })
            ->get();

        if ($customerAccountItems->isEmpty()) {
            echo "  - لا توجد عناصر حساب عميل في هذا القيد المحاسبي. تم تخطيه.\n";
            $skipped++;
            continue;
        }

        echo "  - تم العثور على " . $customerAccountItems->count() . " عنصر حساب عميل.\n";

        // حذف أي سجلات موجودة لهذا القيد المحاسبي
        $deleted = \App\Models\CustomerStatement::where('reference_type', 'App\Models\JournalEntry')
            ->where('reference_id', $entry->id)
            ->delete();

        echo "  - تم حذف " . $deleted . " سجل كشف حساب موجود.\n";

        // لكل عنصر حساب عميل، نحاول استخراج معرف العميل وإنشاء كشف حساب
        $statementsCreated = 0;

        foreach ($customerAccountItems as $item) {
            // الحصول على حساب العميل
            $customerAccount = \App\Models\ChartOfAccount::find($item->account_id);
            if (!$customerAccount) {
                echo "  - حساب العميل غير موجود: " . $item->account_id . ". تم تخطيه.\n";
                continue;
            }

            echo "  - معالجة حساب: " . $customerAccount->name . " (" . $customerAccount->account_code . ")\n";

            // استخراج معرف العميل
            $customerId = null;

            // 1. أولاً، نحاول استخراج معرف العميل من اسم الحساب باستخدام التعبير النمطي
            if (preg_match('/عميل رقم(\d+)/', $customerAccount->name, $matches)) {
                // البحث عن العميل باستخدام الرقم المستخرج
                $customerNumber = intval($matches[1]);
                echo "  - استخراج رقم العميل من اسم الحساب: " . $customerNumber . "\n";

                // البحث عن العميل باستخدام رقم العميل
                // البحث عن العميل باستخدام الاسم الذي يحتوي على رقم العميل
                $customer = \App\Models\Customer::where('company_id', $entry->company_id)
                    ->where('name', 'like', '%' . $customerNumber . '%')
                    ->first();

                if ($customer) {
                    $customerId = $customer->id;
                    echo "  - تم العثور على العميل برقم العميل: " . $customerNumber . " -> معرف العميل: " . $customerId . "\n";
                }
            }

            // 2. إذا لم نجد العميل، نحاول استخراج معرف العميل من رمز الحساب
            if (!$customerId && strpos($customerAccount->account_code, 'AR-') === 0) {
                $extractedId = intval(substr($customerAccount->account_code, 3));
                echo "  - استخراج معرف من رمز الحساب: " . $extractedId . "\n";

                // التحقق مما إذا كان المعرف المستخرج هو معرف العميل أو رقم العميل
                $customerById = \App\Models\Customer::find($extractedId);
                if ($customerById) {
                    $customerId = $customerById->id;
                    echo "  - تم العثور على العميل بمعرف العميل المستخرج من رمز الحساب: " . $customerId . "\n";
                } else {
                    // البحث عن العميل باستخدام رقم العميل
                    // البحث عن العميل باستخدام الاسم الذي يحتوي على الرقم المستخرج
                    $customerByNumber = \App\Models\Customer::where('company_id', $entry->company_id)
                        ->where('name', 'like', '%' . $extractedId . '%')
                        ->first();

                    if ($customerByNumber) {
                        $customerId = $customerByNumber->id;
                        echo "  - تم العثور على العميل برقم العميل المستخرج من رمز الحساب: " . $customerId . "\n";
                    }
                }
            }

            // 3. إذا لم نجد العميل، نحاول البحث عن العميل باستخدام اسم الحساب
            if (!$customerId) {
                // استخراج اسم العميل من اسم الحساب
                $customerName = str_replace('ذمم العميل: ', '', $customerAccount->name);
                $customerName = str_replace('Customer Receivable: ', '', $customerName);
                echo "  - البحث عن العميل باستخدام الاسم: " . $customerName . "\n";

                $customer = \App\Models\Customer::where('company_id', $entry->company_id)
                    ->where(function ($query) use ($customerName) {
                        $query->where('name', 'like', '%' . $customerName . '%')
                            ->orWhere('name_en', 'like', '%' . $customerName . '%');
                    })
                    ->first();

                if ($customer) {
                    $customerId = $customer->id;
                    echo "  - تم العثور على العميل بالاسم: " . $customerName . " -> " . $customerId . "\n";
                } else {
                    // البحث عن العميل بمقارنة جميع العملاء مع اسم الحساب
                    $allCustomers = \App\Models\Customer::where('company_id', $entry->company_id)->get();
                    foreach ($allCustomers as $potentialCustomer) {
                        if (
                            stripos($customerAccount->name, $potentialCustomer->name) !== false ||
                            (isset($potentialCustomer->name_en) && stripos($customerAccount->name, $potentialCustomer->name_en) !== false)
                        ) {
                            $customerId = $potentialCustomer->id;
                            echo "  - تم العثور على العميل بمقارنة الاسم: " . $customerAccount->name . " -> " . $customerId . "\n";
                            break;
                        }
                    }
                }
            }

            // إذا لم نتمكن من العثور على العميل، نتخطى هذا العنصر
            if (!$customerId) {
                echo "  - لم يتم العثور على العميل للحساب: " . $customerAccount->name . " (" . $customerAccount->account_code . "). تم تخطيه.\n";
                continue;
            }

            // الحصول على آخر رصيد لهذا العميل
            $lastStatement = \App\Models\CustomerStatement::where('customer_id', $customerId)
                ->orderBy('id', 'desc')
                ->first();

            $currentBalance = $lastStatement ? $lastStatement->balance : 0;

            // حساب الرصيد الجديد
            $debitAmount = $item->debit;
            $creditAmount = $item->credit;
            $netAmount = $creditAmount - $debitAmount;
            $newBalance = $currentBalance - $netAmount;

            // الحصول على معلومات المرجع بناءً على مرجع القيد المحاسبي
            $referenceType = $entry->reference_type;
            $referenceId = $entry->reference_id;
            $description = $entry->description;

            // إذا كان المرجع فاتورة، نحصل على مزيد من التفاصيل
            if ($referenceType == 'App\Models\Invoice' && $referenceId) {
                $invoice = \App\Models\Invoice::find($referenceId);
                if ($invoice) {
                    $description = 'فاتورة رقم ' . $invoice->invoice_number . ' (قيد محاسبي: ' . $entry->entry_number . ')';
                }
            }
            // إذا كان المرجع دفعة، نحصل على مزيد من التفاصيل
            else if ($referenceType == 'App\Models\Payment' && $referenceId) {
                $payment = \App\Models\Payment::find($referenceId);
                if ($payment && $payment->invoice) {
                    $description = 'دفعة للفاتورة رقم ' . $payment->invoice->invoice_number . ' (قيد محاسبي: ' . $entry->entry_number . ')';
                }
            }

            // إنشاء سجل كشف الحساب
            $statement = \App\Models\CustomerStatement::create([
                'company_id' => $entry->company_id,
                'customer_id' => $customerId,
                'branch_id' => null, // ليس لدينا معلومات الفرع من القيد المحاسبي
                'transaction_date' => $entry->entry_date,
                'reference_number' => $entry->entry_number,
                'reference_type' => 'App\Models\JournalEntry',
                'reference_id' => $entry->id,
                'description' => $description,
                'debit' => $debitAmount,
                'credit' => $creditAmount,
                'balance' => $newBalance
            ]);

            echo "  - تم إنشاء كشف حساب للعميل: " . $customerId . " للقيد المحاسبي: " . $entry->id . "\n";
            $statementsCreated++;
        }

        if ($statementsCreated > 0) {
            echo "  - تم إنشاء " . $statementsCreated . " كشف حساب للعملاء.\n";
            $fixed++;
        } else {
            echo "  - لم يتم إنشاء أي كشف حساب للعملاء.\n";
            $skipped++;
        }
    } catch (\Exception $e) {
        echo "  - حدث خطأ أثناء معالجة القيد المحاسبي: " . $e->getMessage() . "\n";
        $errors++;
    }
}

echo "\nاكتملت العملية!\n";
echo "تم إصلاح " . $fixed . " قيد محاسبي.\n";
echo "تم تخطي " . $skipped . " قيد محاسبي.\n";
echo "حدث خطأ في " . $errors . " قيد محاسبي.\n";
