<?php

namespace App\Services;

use App\Models\Invoice;
use App\Models\License;
use App\Models\Product;
use App\Services\EmailService;
use Illuminate\Support\Facades\DB;

class InvoiceService
{
    protected EmailService $emailService;

    public function __construct(EmailService $emailService)
    {
        $this->emailService = $emailService;
    }

    /**
     * إنشاء فاتورة لترخيص جديد
     */
    public function createInitialInvoice(License $license, string $paymentStatus = 'paid', ?string $dueDate = null): Invoice
    {
        $product = $license->product;
        
        // تحديد تاريخ الاستحقاق
        $invoiceDueDate = $dueDate ? \Carbon\Carbon::parse($dueDate) : now();
        
        // تحديد تاريخ الدفع
        $paidAt = $paymentStatus === 'paid' ? now() : null;

        $invoice = Invoice::create([
            'user_id' => $license->user_id,
            'license_id' => $license->id,
            'product_id' => $product->id,
            'type' => 'initial',
            'amount' => $product->price,
            'currency' => 'USD',
            'status' => $paymentStatus,
            'due_date' => $invoiceDueDate,
            'paid_at' => $paidAt,
            'notes' => 'Initial license purchase - ' . ucfirst($paymentStatus),
        ]);

        // Send email notifications
        try {
            if ($license->user) {
                if ($paymentStatus === 'paid') {
                    $this->emailService->sendInvoicePaid($license->user, [
                        'invoice_number' => $invoice->id,
                        'invoice_amount' => $invoice->amount,
                        'payment_date' => $paidAt ? $paidAt->format('Y-m-d H:i:s') : now()->format('Y-m-d H:i:s'),
                        'payment_method' => 'Automatic',
                    ]);
                } else {
                    $this->emailService->sendInvoiceApproachingDue($license->user, [
                        'invoice_number' => $invoice->id,
                        'invoice_amount' => $invoice->amount,
                        'due_date' => $invoiceDueDate->format('Y-m-d'),
                        'days_remaining' => now()->diffInDays($invoiceDueDate),
                    ]);
                }
            }

            // Send admin notification
            $this->emailService->sendAdminInvoiceApproachingDue([
                'invoice_number' => $invoice->id,
                'invoice_amount' => $invoice->amount,
                'customer_name' => $license->user ? $license->user->name : 'Unknown User',
                'customer_email' => $license->user ? $license->user->email : 'No email provided',
                'due_date' => $invoiceDueDate->format('Y-m-d'),
                'days_remaining' => now()->diffInDays($invoiceDueDate),
            ]);
        } catch (\Exception $e) {
            // Silently handle email errors to not fail invoice creation
        }

        return $invoice;
    }

    /**
     * إنشاء فاتورة تجديد
     */
    public function createRenewalInvoice(License $license, array $options = []): Invoice
    {
        $product = $license->product;
        
        // تحديد سعر التجديد
        $renewalPrice = $options['amount'] ?? $product->renewal_price ?? $product->price ?? 0;
        
        // تحديد تاريخ الاستحقاق
        $dueDate = $options['due_date'] ?? now()->addDays(30);
        
        // تحديد تاريخ انتهاء جديد
        $newExpiryDate = $options['new_expiry_date'] ?? $this->calculateNewExpiryDate($license, $product);

        $invoice = Invoice::create([
            'user_id' => $license->user_id,
            'license_id' => $license->id,
            'product_id' => $product->id,
            'type' => 'renewal',
            'amount' => $renewalPrice,
            'currency' => 'USD',
            'status' => 'pending',
            'due_date' => $dueDate,
            'notes' => $options['description'] ?? "Renewal for {$product->name} - License {$license->license_key}",
            'metadata' => [
                'new_expiry_date' => $newExpiryDate,
                'renewal_period' => $product->renewal_period,
            ],
        ]);

        return $invoice;
    }

    /**
     * حساب تاريخ انتهاء جديد بناءً على فترة التجديد
     */
    protected function calculateNewExpiryDate(License $license, Product $product): \Carbon\Carbon
    {
        $currentExpiry = $license->license_expires_at ?? now();
        $renewalPeriod = $product->renewal_period;

        switch ($renewalPeriod) {
            case 'monthly':
                return $currentExpiry->copy()->addMonth();
            case 'quarterly':
                return $currentExpiry->copy()->addMonths(3);
            case 'semi-annual':
                return $currentExpiry->copy()->addMonths(6);
            case 'annual':
                return $currentExpiry->copy()->addYear();
            case 'three-years':
                return $currentExpiry->copy()->addYears(3);
            case 'lifetime':
                return $currentExpiry->copy()->addYears(100);
            default:
                // Default to product duration_days
                $durationDays = $product->duration_days ?? 365;
                return $currentExpiry->copy()->addDays($durationDays);
        }
    }

    /**
     * إنشاء فواتير التجديد للتراخيص التي ستنتهي قريباً
     */
    public function createRenewalInvoicesForExpiringLicenses()
    {
        $expiringLicenses = License::where('status', 'active')
            ->whereNotNull('license_expires_at')
            ->where('license_expires_at', '<=', now()->addDays(7))
            ->where('license_expires_at', '>', now())
            ->whereDoesntHave('invoices', function ($query) {
                $query->where('type', 'renewal')
                      ->where('status', 'pending')
                      ->where('due_date', '>', now());
            })
            ->with(['product', 'user'])
            ->get();

        $createdInvoices = [];

        foreach ($expiringLicenses as $license) {
            if ($license->product->auto_renewal) {
                $invoice = $this->createRenewalInvoice($license);
                $createdInvoices[] = $invoice;
            }
        }

        return $createdInvoices;
    }

    /**
     * تحديث حالة الفواتير المتأخرة وتعليق التراخيص المرتبطة
     */
    public function processOverdueInvoices()
    {
        $overdueInvoices = Invoice::where('status', 'pending')
            ->where('due_date', '<', now())
            ->with(['license'])
            ->get();

        $processedInvoices = [];

        foreach ($overdueInvoices as $invoice) {
            // تحديث حالة الفاتورة
            $invoice->markAsOverdue();

            // تعليق الترخيص
            if ($invoice->license) {
                $invoice->license->update(['status' => 'suspended']);
            }

            $processedInvoices[] = $invoice;
        }

        return $processedInvoices;
    }

    /**
     * دفع فاتورة
     */
    public function payInvoice(Invoice $invoice): bool
    {
        DB::transaction(function () use ($invoice) {
            $invoice->markAsPaid();

            // إعادة تفعيل الترخيص إذا كان معلقاً
            if ($invoice->license && $invoice->license->status === 'suspended') {
                $invoice->license->update(['status' => 'active']);
            }

            // تمديد تاريخ انتهاء الترخيص
            if ($invoice->type === 'renewal' && $invoice->license) {
                $newExpiryDate = $invoice->metadata['new_expiry_date'] ?? 
                    $this->calculateNewExpiryDate($invoice->license, $invoice->product);

                $invoice->license->update([
                    'license_expires_at' => $newExpiryDate,
                    'status' => 'active'
                ]);
            }

            // Send email notifications
            try {
                if ($invoice->user) {
                    $this->emailService->sendInvoicePaid($invoice->user, [
                        'invoice_number' => $invoice->id,
                        'invoice_amount' => $invoice->amount,
                        'payment_date' => now()->format('Y-m-d H:i:s'),
                        'payment_method' => 'Online Payment',
                    ]);
                }
            } catch (\Exception $e) {
                // Silently handle email errors
            }
        });

        return true;
    }

    /**
     * إلغاء فاتورة
     */
    public function cancelInvoice(Invoice $invoice): bool
    {
        $invoice->cancel();

        // Send email notifications
        try {
            if ($invoice->user) {
                $this->emailService->sendInvoiceCancelled($invoice->user, [
                    'invoice_number' => $invoice->id,
                    'invoice_amount' => $invoice->amount,
                    'cancellation_reason' => 'Invoice cancelled by system',
                ]);
            }

            // Send admin notification
            $this->emailService->sendAdminInvoiceCancelled([
                'invoice_number' => $invoice->id,
                'invoice_amount' => $invoice->amount,
                'customer_name' => $invoice->user ? $invoice->user->name : 'Unknown User',
                'customer_email' => $invoice->user ? $invoice->user->email : 'No email provided',
                'cancellation_reason' => 'Invoice cancelled by system',
            ]);
        } catch (\Exception $e) {
            // Silently handle email errors
        }

        return true;
    }

    /**
     * الحصول على الفواتير المستحقة قريباً
     */
    public function getInvoicesDueSoon($days = 7)
    {
        return Invoice::dueSoon($days)->with(['user', 'product', 'license'])->get();
    }

    /**
     * الحصول على الفواتير المتأخرة
     */
    public function getOverdueInvoices()
    {
        return Invoice::overdue()->with(['user', 'product', 'license'])->get();
    }

    /**
     * الحصول على إحصائيات الفواتير
     */
    public function getInvoiceStats()
    {
        return [
            'total' => Invoice::count(),
            'pending' => Invoice::pending()->count(),
            'paid' => Invoice::paid()->count(),
            'overdue' => Invoice::overdue()->count(),
            'cancelled' => Invoice::where('status', 'cancelled')->count(),
            'total_revenue' => Invoice::paid()->sum('amount'),
            'pending_revenue' => Invoice::pending()->sum('amount'),
        ];
    }
}