<?php

namespace App\Services\Notifications;

use App\Models\InvoiceInstallment;
use App\Models\User;
use App\Models\Customer;
use App\Notifications\InstallmentDueNotification;
use App\Notifications\InstallmentPaymentReceivedNotification;
use Illuminate\Support\Facades\Notification;
use Carbon\Carbon;

class InstallmentNotificationService
{
    /**
     * إرسال إشعار بقسط مستحق قريباً.
     *
     * @param InvoiceInstallment $installment
     * @param int $daysRemaining
     * @return array
     */
    public function sendUpcomingInstallmentNotification(InvoiceInstallment $installment, $daysRemaining)
    {
        try {
            $invoice = $installment->invoice;
            $customer = $invoice->customer;
            $companyId = $invoice->company_id;
            $recipients = [];

            // إرسال إشعار للعميل إذا كان لديه حساب مستخدم
            if ($customer->user_id) {
                $user = User::find($customer->user_id);
                if ($user) {
                    $user->notify(new InstallmentDueNotification($installment, $daysRemaining));
                    $recipients[] = [
                        'id' => $user->id,
                        'name' => $user->name,
                        'type' => 'customer',
                    ];
                }
            }

            // إرسال إشعار للمستخدمين المسؤولين عن متابعة الأقساط
            $admins = User::whereHas('roles', function ($query) {
                $query->whereIn('name', ['super_admin', 'admin', 'accountant']);
            })
                ->where('company_id', $companyId)
                ->get();

            Notification::send($admins, new InstallmentDueNotification($installment, $daysRemaining));

            foreach ($admins as $admin) {
                $recipients[] = [
                    'id' => $admin->id,
                    'name' => $admin->name,
                    'type' => 'admin',
                ];
            }

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

    /**
     * إرسال إشعار بقسط متأخر.
     *
     * @param InvoiceInstallment $installment
     * @param int $daysOverdue
     * @return array
     */
    public function sendOverdueInstallmentNotification(InvoiceInstallment $installment, $daysOverdue)
    {
        try {
            $invoice = $installment->invoice;
            $customer = $invoice->customer;
            $companyId = $invoice->company_id;
            $recipients = [];

            // إرسال إشعار للعميل إذا كان لديه حساب مستخدم
            if ($customer->user_id) {
                $user = User::find($customer->user_id);
                if ($user) {
                    $user->notify(new InstallmentDueNotification($installment, $daysOverdue * -1));
                    $recipients[] = [
                        'id' => $user->id,
                        'name' => $user->name,
                        'type' => 'customer',
                    ];
                }
            }

            // إرسال إشعار للمستخدمين المسؤولين عن متابعة الأقساط
            $admins = User::whereHas('roles', function ($query) {
                $query->whereIn('name', ['super_admin', 'admin', 'accountant']);
            })
                ->where('company_id', $companyId)
                ->get();

            Notification::send($admins, new InstallmentDueNotification($installment, $daysOverdue * -1));

            foreach ($admins as $admin) {
                $recipients[] = [
                    'id' => $admin->id,
                    'name' => $admin->name,
                    'type' => 'admin',
                ];
            }

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

    /**
     * إرسال إشعار باستلام دفعة قسط.
     *
     * @param InvoiceInstallment $installment
     * @param float $amount
     * @return array
     */
    public function sendPaymentReceivedNotification(InvoiceInstallment $installment, $amount)
    {
        try {
            $invoice = $installment->invoice;
            $customer = $invoice->customer;
            $companyId = $invoice->company_id;
            $recipients = [];

            // إرسال إشعار للعميل إذا كان لديه حساب مستخدم
            if ($customer->user_id) {
                $user = User::find($customer->user_id);
                if ($user) {
                    $user->notify(new InstallmentPaymentReceivedNotification($installment, $amount));
                    $recipients[] = [
                        'id' => $user->id,
                        'name' => $user->name,
                        'type' => 'customer',
                    ];
                }
            }

            // إرسال إشعار للمستخدمين المسؤولين عن متابعة الأقساط
            $admins = User::whereHas('roles', function ($query) {
                $query->whereIn('name', ['super_admin', 'admin', 'accountant']);
            })
                ->where('company_id', $companyId)
                ->get();

            Notification::send($admins, new InstallmentPaymentReceivedNotification($installment, $amount));

            foreach ($admins as $admin) {
                $recipients[] = [
                    'id' => $admin->id,
                    'name' => $admin->name,
                    'type' => 'admin',
                ];
            }

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

    /**
     * إرسال تذكيرات للأقساط المستحقة قريباً.
     *
     * @param int $companyId
     * @param int $days
     * @return array
     */
    public function sendUpcomingInstallmentsReminders($companyId, $days = 7)
    {
        try {
            $upcomingInstallments = InvoiceInstallment::where('status', 'pending')
                ->where('due_date', '>=', Carbon::now()->startOfDay())
                ->where('due_date', '<=', Carbon::now()->addDays($days)->endOfDay())
                ->whereHas('invoice', function ($query) use ($companyId) {
                    $query->where('company_id', $companyId);
                })
                ->with(['invoice', 'invoice.customer'])
                ->get();

            $sentCount = 0;
            $failedCount = 0;

            foreach ($upcomingInstallments as $installment) {
                $daysRemaining = Carbon::now()->startOfDay()->diffInDays($installment->due_date, false);
                $result = $this->sendUpcomingInstallmentNotification($installment, $daysRemaining);

                if ($result['success']) {
                    $sentCount++;
                } else {
                    $failedCount++;
                }
            }

            return [
                'success' => true,
                'message' => "تم إرسال {$sentCount} تذكير للأقساط المستحقة قريباً. فشل إرسال {$failedCount} تذكير.",
                'sent_count' => $sentCount,
                'failed_count' => $failedCount,
                'total_count' => $upcomingInstallments->count(),
            ];
        } catch (\Exception $e) {
            \Log::error('خطأ في إرسال تذكيرات الأقساط المستحقة: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'حدث خطأ أثناء إرسال التذكيرات: ' . $e->getMessage(),
            ];
        }
    }

    /**
     * إرسال تذكيرات للأقساط المتأخرة.
     *
     * @param int $companyId
     * @return array
     */
    public function sendOverdueInstallmentsReminders($companyId)
    {
        try {
            $overdueInstallments = InvoiceInstallment::where(function ($query) {
                $query->where('status', 'overdue')
                    ->orWhere(function ($q) {
                        $q->where('status', 'pending')
                            ->where('due_date', '<', Carbon::now()->startOfDay());
                    });
            })
                ->where('paid_amount', '<', \DB::raw('amount'))
                ->whereHas('invoice', function ($query) use ($companyId) {
                    $query->where('company_id', $companyId);
                })
                ->with(['invoice', 'invoice.customer'])
                ->get();

            $sentCount = 0;
            $failedCount = 0;

            foreach ($overdueInstallments as $installment) {
                $daysOverdue = Carbon::now()->startOfDay()->diffInDays($installment->due_date, false) * -1;
                $result = $this->sendOverdueInstallmentNotification($installment, $daysOverdue);

                if ($result['success']) {
                    $sentCount++;
                } else {
                    $failedCount++;
                }
            }

            return [
                'success' => true,
                'message' => "تم إرسال {$sentCount} تذكير للأقساط المتأخرة. فشل إرسال {$failedCount} تذكير.",
                'sent_count' => $sentCount,
                'failed_count' => $failedCount,
                'total_count' => $overdueInstallments->count(),
            ];
        } catch (\Exception $e) {
            \Log::error('خطأ في إرسال تذكيرات الأقساط المتأخرة: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'حدث خطأ أثناء إرسال التذكيرات: ' . $e->getMessage(),
            ];
        }
    }

    /**
     * إرسال تذكير لقسط مستحق قريباً محدد.
     *
     * @param InvoiceInstallment $installment
     * @return array
     */
    public function sendSingleUpcomingInstallmentReminder(InvoiceInstallment $installment)
    {
        try {
            // التحقق من أن القسط غير مدفوع بالكامل
            if ($installment->isPaid()) {
                return [
                    'success' => false,
                    'message' => 'لا يمكن إرسال تذكير لقسط مدفوع بالكامل',
                ];
            }

            $daysRemaining = Carbon::now()->startOfDay()->diffInDays($installment->due_date, false);
            $result = $this->sendUpcomingInstallmentNotification($installment, $daysRemaining);

            // تسجيل عملية إرسال التذكير
            \Log::info("تم إرسال تذكير للقسط المستحق قريباً #{$installment->id} للعميل {$installment->invoice->customer->name}");

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

    /**
     * إرسال تذكير لقسط متأخر محدد.
     *
     * @param InvoiceInstallment $installment
     * @return array
     */
    public function sendSingleOverdueInstallmentReminder(InvoiceInstallment $installment)
    {
        try {
            // التحقق من أن القسط غير مدفوع بالكامل
            if ($installment->isPaid()) {
                return [
                    'success' => false,
                    'message' => 'لا يمكن إرسال تذكير لقسط مدفوع بالكامل',
                ];
            }

            // التحقق من أن القسط متأخر
            if (!$installment->isOverdue()) {
                return [
                    'success' => false,
                    'message' => 'هذا القسط غير متأخر، يرجى استخدام تذكير الأقساط المستحقة قريباً',
                ];
            }

            $daysOverdue = Carbon::now()->startOfDay()->diffInDays($installment->due_date, false) * -1;
            $result = $this->sendOverdueInstallmentNotification($installment, $daysOverdue);

            // تسجيل عملية إرسال التذكير
            \Log::info("تم إرسال تذكير للقسط المتأخر #{$installment->id} للعميل {$installment->invoice->customer->name}");

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