<?php

namespace App\Services\AccountingIntegration;

use App\Models\InvoiceInstallment;
use App\Models\Payment;
use App\Models\AccountingEntry;
use App\Models\AccountingAccount;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class InstallmentAccountingService
{
    /**
     * إنشاء قيود محاسبية للقسط.
     *
     * @param InvoiceInstallment $installment
     * @return bool
     */
    public function createInstallmentEntries(InvoiceInstallment $installment)
    {
        try {
            DB::beginTransaction();

            $invoice = $installment->invoice;
            $companyId = $invoice->company_id;

            // الحصول على الحسابات المحاسبية
            $accountsReceivable = AccountingAccount::where('company_id', $companyId)
                ->where('code', 'accounts_receivable')
                ->first();

            $installmentsReceivable = AccountingAccount::where('company_id', $companyId)
                ->where('code', 'installments_receivable')
                ->first();

            if (!$accountsReceivable || !$installmentsReceivable) {
                throw new \Exception('الحسابات المحاسبية غير موجودة');
            }

            // إنشاء قيد محاسبي لتسجيل القسط
            $entry = new AccountingEntry([
                'company_id' => $companyId,
                'date' => Carbon::now(),
                'reference_type' => 'installment',
                'reference_id' => $installment->id,
                'description' => 'تسجيل قسط للفاتورة رقم ' . $invoice->invoice_number,
                'status' => 'posted',
                'created_by' => auth()->id() ?? 1,
            ]);

            $entry->save();

            // إضافة تفاصيل القيد المحاسبي
            $entry->details()->create([
                'account_id' => $installmentsReceivable->id,
                'debit' => $installment->amount,
                'credit' => 0,
                'description' => 'ذمم أقساط مستحقة - قسط للفاتورة رقم ' . $invoice->invoice_number,
            ]);

            $entry->details()->create([
                'account_id' => $accountsReceivable->id,
                'debit' => 0,
                'credit' => $installment->amount,
                'description' => 'ذمم مدينة - قسط للفاتورة رقم ' . $invoice->invoice_number,
            ]);

            DB::commit();
            return true;
        } catch (\Exception $e) {
            DB::rollBack();
            \Log::error('خطأ في إنشاء قيود محاسبية للقسط: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * إنشاء قيود محاسبية لدفعة القسط.
     *
     * @param Payment $payment
     * @param InvoiceInstallment $installment
     * @return bool
     */
    public function createPaymentEntries(Payment $payment, InvoiceInstallment $installment)
    {
        try {
            DB::beginTransaction();

            $invoice = $installment->invoice;
            $companyId = $invoice->company_id;

            // الحصول على الحسابات المحاسبية
            $cashAccount = AccountingAccount::where('company_id', $companyId)
                ->where('code', 'cash')
                ->first();

            $installmentsReceivable = AccountingAccount::where('company_id', $companyId)
                ->where('code', 'installments_receivable')
                ->first();

            if (!$cashAccount || !$installmentsReceivable) {
                throw new \Exception('الحسابات المحاسبية غير موجودة');
            }

            // إنشاء قيد محاسبي لتسجيل الدفعة
            $entry = new AccountingEntry([
                'company_id' => $companyId,
                'date' => $payment->payment_date,
                'reference_type' => 'payment',
                'reference_id' => $payment->id,
                'description' => 'دفعة قسط للفاتورة رقم ' . $invoice->invoice_number,
                'status' => 'posted',
                'created_by' => auth()->id() ?? 1,
            ]);

            $entry->save();

            // إضافة تفاصيل القيد المحاسبي
            $entry->details()->create([
                'account_id' => $cashAccount->id,
                'debit' => $payment->amount,
                'credit' => 0,
                'description' => 'نقد - دفعة قسط للفاتورة رقم ' . $invoice->invoice_number,
            ]);

            $entry->details()->create([
                'account_id' => $installmentsReceivable->id,
                'debit' => 0,
                'credit' => $payment->amount,
                'description' => 'ذمم أقساط مستحقة - دفعة قسط للفاتورة رقم ' . $invoice->invoice_number,
            ]);

            DB::commit();
            return true;
        } catch (\Exception $e) {
            DB::rollBack();
            \Log::error('خطأ في إنشاء قيود محاسبية لدفعة القسط: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * إنشاء قيود محاسبية لإلغاء القسط.
     *
     * @param InvoiceInstallment $installment
     * @return bool
     */
    public function createCancellationEntries(InvoiceInstallment $installment)
    {
        try {
            DB::beginTransaction();

            $invoice = $installment->invoice;
            $companyId = $invoice->company_id;

            // الحصول على الحسابات المحاسبية
            $accountsReceivable = AccountingAccount::where('company_id', $companyId)
                ->where('code', 'accounts_receivable')
                ->first();

            $installmentsReceivable = AccountingAccount::where('company_id', $companyId)
                ->where('code', 'installments_receivable')
                ->first();

            if (!$accountsReceivable || !$installmentsReceivable) {
                throw new \Exception('الحسابات المحاسبية غير موجودة');
            }

            // حساب المبلغ المتبقي للقسط
            $remainingAmount = $installment->amount - $installment->paid_amount;

            if ($remainingAmount <= 0) {
                DB::commit();
                return true;
            }

            // إنشاء قيد محاسبي لإلغاء القسط
            $entry = new AccountingEntry([
                'company_id' => $companyId,
                'date' => Carbon::now(),
                'reference_type' => 'installment_cancellation',
                'reference_id' => $installment->id,
                'description' => 'إلغاء قسط للفاتورة رقم ' . $invoice->invoice_number,
                'status' => 'posted',
                'created_by' => auth()->id() ?? 1,
            ]);

            $entry->save();

            // إضافة تفاصيل القيد المحاسبي
            $entry->details()->create([
                'account_id' => $accountsReceivable->id,
                'debit' => $remainingAmount,
                'credit' => 0,
                'description' => 'ذمم مدينة - إلغاء قسط للفاتورة رقم ' . $invoice->invoice_number,
            ]);

            $entry->details()->create([
                'account_id' => $installmentsReceivable->id,
                'debit' => 0,
                'credit' => $remainingAmount,
                'description' => 'ذمم أقساط مستحقة - إلغاء قسط للفاتورة رقم ' . $invoice->invoice_number,
            ]);

            DB::commit();
            return true;
        } catch (\Exception $e) {
            DB::rollBack();
            \Log::error('خطأ في إنشاء قيود محاسبية لإلغاء القسط: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * إنشاء تقرير محاسبي للأقساط.
     *
     * @param int $companyId
     * @param string $startDate
     * @param string $endDate
     * @return array
     */
    public function generateInstallmentsAccountingReport($companyId, $startDate, $endDate)
    {
        try {
            $startDate = Carbon::parse($startDate)->startOfDay();
            $endDate = Carbon::parse($endDate)->endOfDay();

            // الحصول على الحساب المحاسبي للأقساط
            $installmentsReceivable = AccountingAccount::where('company_id', $companyId)
                ->where('code', 'installments_receivable')
                ->first();

            if (!$installmentsReceivable) {
                throw new \Exception('حساب الأقساط المستحقة غير موجود');
            }

            // الحصول على القيود المحاسبية للأقساط
            $entries = AccountingEntry::where('company_id', $companyId)
                ->whereBetween('date', [$startDate, $endDate])
                ->whereIn('reference_type', ['installment', 'payment', 'installment_cancellation'])
                ->with(['details' => function ($query) use ($installmentsReceivable) {
                    $query->where('account_id', $installmentsReceivable->id);
                }])
                ->get();

            // تجميع البيانات
            $report = [
                'total_installments' => 0,
                'total_payments' => 0,
                'total_cancellations' => 0,
                'net_movement' => 0,
                'entries' => [],
            ];

            foreach ($entries as $entry) {
                $detail = $entry->details->first();
                if (!$detail) continue;

                $amount = $detail->debit - $detail->credit;

                $reportEntry = [
                    'id' => $entry->id,
                    'date' => $entry->date,
                    'reference_type' => $entry->reference_type,
                    'reference_id' => $entry->reference_id,
                    'description' => $entry->description,
                    'amount' => abs($amount),
                    'type' => $amount > 0 ? 'debit' : 'credit',
                ];

                $report['entries'][] = $reportEntry;

                if ($entry->reference_type === 'installment') {
                    $report['total_installments'] += $detail->debit;
                } elseif ($entry->reference_type === 'payment') {
                    $report['total_payments'] += $detail->credit;
                } elseif ($entry->reference_type === 'installment_cancellation') {
                    $report['total_cancellations'] += $detail->credit;
                }
            }

            $report['net_movement'] = $report['total_installments'] - $report['total_payments'] - $report['total_cancellations'];

            return [
                'success' => true,
                'data' => $report,
            ];
        } catch (\Exception $e) {
            \Log::error('خطأ في إنشاء تقرير محاسبي للأقساط: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'حدث خطأ أثناء إنشاء التقرير: ' . $e->getMessage(),
            ];
        }
    }
}
