<?php

namespace App\Services;

use App\Models\Customer;
use Illuminate\Database\Eloquent\Collection;
use Carbon\Carbon;

class CustomerProfileService
{
    public function getCustomersWithRentals($search = null, $status = null)
    {
        $query = Customer::with(['rentals', 'rating', 'paymentDelays', 'blacklistEntries']);

        if ($search) {
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('phone', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%");
            });
        }

        if ($status) {
            $query->where(function ($q) use ($status) {
                if ($status === 'active') {
                    $q->whereDoesntHave('blacklistEntries', function ($blacklist) {
                        $blacklist->where('status', 'active');
                    });
                } elseif ($status === 'defaulter') {
                    $q->where(function ($inner) {
                        $inner->whereHas('rating', function ($rating) {
                            $rating->where('status', 'critical')
                                   ->orWhere('risk_level', 'critical');
                        })
                        ->orWhereHas('paymentDelays', function ($delay) {
                            $delay->where('status', 'overdue');
                        });
                    });
                } elseif ($status === 'blacklisted') {
                    $q->whereHas('blacklistEntries', function ($blacklist) {
                        $blacklist->where('status', 'active');
                    });
                }
            });
        }

        return $query->orderBy('created_at', 'desc')->paginate(20);
    }

    public function getCustomerProfile(Customer $customer)
    {
        $customer->load(['rentals', 'rating', 'violations', 'paymentDelays', 'blacklistEntries']);

        return [
            'customer' => $customer,
            'rental_summary' => $this->getRentalSummary($customer),
            'payment_summary' => $this->getPaymentSummary($customer),
            'status_info' => $this->getStatusInfo($customer),
            'rating_info' => $this->getRatingInfo($customer),
        ];
    }

    public function getRentalSummary(Customer $customer)
    {
        $rentals = $customer->rentals()->get();

        return [
            'total_contracts' => $rentals->count(),
            'active_contracts' => $rentals->where('status', 'active')->count(),
            'completed_contracts' => $rentals->where('status', 'completed')->count(),
            'cancelled_contracts' => $rentals->where('status', 'cancelled')->count(),
            'total_rental_days' => $this->calculateTotalRentalDays($rentals),
            'first_rental_date' => $rentals->min('start_date'),
            'latest_rental_date' => $rentals->max('end_date'),
        ];
    }

    public function getPaymentSummary(Customer $customer)
    {
        $rentals = $customer->rentals()->get();
        $paymentDelays = $customer->paymentDelays()->get();

        $totalAmount = $rentals->sum('total_amount');
        $totalPaid = $rentals->sum('paid_amount');
        $totalRemaining = $rentals->sum('remaining_amount');
        $totalDelayAmount = $paymentDelays->sum('delayed_amount');
        $totalLateFees = $paymentDelays->sum('late_fee');

        return [
            'total_amount' => $totalAmount,
            'total_paid' => $totalPaid,
            'total_remaining' => $totalRemaining,
            'payment_percentage' => $totalAmount > 0 ? round(($totalPaid / $totalAmount) * 100, 2) : 0,
            'total_delays' => $paymentDelays->count(),
            'pending_delays' => $paymentDelays->where('status', 'overdue')->count(),
            'total_delay_amount' => $totalDelayAmount,
            'total_late_fees' => $totalLateFees,
            'overdue_amount' => $totalRemaining + $totalDelayAmount,
        ];
    }

    public function getStatusInfo(Customer $customer)
    {
        $blacklist = $customer->blacklistEntries()
            ->where('status', 'active')
            ->first();

        if ($blacklist) {
            return [
                'status' => 'blacklisted',
                'label' => app()->getLocale() == 'ar' ? 'محظور' : 'Blacklisted',
                'color' => 'danger',
                'icon' => '🚫',
                'reason' => $blacklist->reason,
                'description' => $blacklist->description,
                'since' => $blacklist->blacklisted_from,
                'until' => $blacklist->blacklisted_until,
            ];
        }

        $rating = $customer->rating;
        if (!$rating) {
            return [
                'status' => 'new',
                'label' => app()->getLocale() == 'ar' ? 'عميل جديد' : 'New Customer',
                'color' => 'info',
                'icon' => '🆕',
            ];
        }

        $statusMap = [
            'critical' => [
                'status' => 'critical',
                'label' => app()->getLocale() == 'ar' ? 'متعثر (حرج)' : 'Defaulter (Critical)',
                'color' => 'danger',
                'icon' => '⚠️',
            ],
            'high' => [
                'status' => 'warning',
                'label' => app()->getLocale() == 'ar' ? 'متعثر (مرتفع)' : 'Defaulter (High)',
                'color' => 'warning',
                'icon' => '⚡',
            ],
            'medium' => [
                'status' => 'medium',
                'label' => app()->getLocale() == 'ar' ? 'محدود الموثوقية' : 'Limited Trust',
                'color' => 'info',
                'icon' => '⚠️',
            ],
            'low' => [
                'status' => 'active',
                'label' => app()->getLocale() == 'ar' ? 'نشط' : 'Active',
                'color' => 'success',
                'icon' => '✅',
            ],
        ];

        return array_merge(
            $statusMap[$rating->risk_level] ?? $statusMap['low'],
            ['risk_level' => $rating->risk_level]
        );
    }

    public function getRatingInfo(Customer $customer)
    {
        $rating = $customer->rating;

        if (!$rating) {
            return [
                'average_rating' => 5.0,
                'violation_count' => 0,
                'late_payment_count' => 0,
                'rental_count' => 0,
                'risk_level' => 'low',
                'notes' => null,
            ];
        }

        return [
            'average_rating' => $rating->average_rating ?? 5.0,
            'violation_count' => $rating->violation_count,
            'late_payment_count' => $rating->late_payment_count,
            'rental_count' => $rating->rental_count,
            'risk_level' => $rating->risk_level,
            'notes' => $rating->notes,
            'last_violation_date' => $rating->last_violation_date,
            'last_late_payment_date' => $rating->last_late_payment_date,
        ];
    }

    public function getContractHistory(Customer $customer, $limit = 50)
    {
        return $customer->rentals()
            ->with('car', 'payments')
            ->orderBy('start_date', 'desc')
            ->limit($limit)
            ->get()
            ->map(function ($rental) {
                $carName = '—';
                if ($rental->car) {
                    $brand = $rental->car->brand ?? 'Unknown';
                    $model = $rental->car->car_model?->name ?? 'Unknown';
                    $carName = $brand . ' ' . $model;
                }
                
                return [
                    'id' => $rental->id,
                    'contract_number' => $rental->contract_number,
                    'car' => $carName,
                    'start_date' => $rental->start_date,
                    'end_date' => $rental->end_date,
                    'total_amount' => $rental->total_amount,
                    'paid_amount' => $rental->paid_amount,
                    'remaining_amount' => $rental->remaining_amount,
                    'status' => $rental->status,
                    'days' => $rental->start_date->diffInDays($rental->end_date),
                ];
            });
    }

    public function getViolationHistory(Customer $customer)
    {
        return $customer->violations()
            ->with('rental')
            ->orderBy('created_at', 'desc')
            ->get();
    }

    public function getPaymentDelayHistory(Customer $customer)
    {
        return $customer->paymentDelays()
            ->with('rental')
            ->orderBy('created_at', 'desc')
            ->get();
    }

    private function calculateTotalRentalDays($rentals)
    {
        return $rentals->sum(function ($rental) {
            if ($rental->start_date && $rental->end_date) {
                return $rental->start_date->diffInDays($rental->end_date);
            }
            return 0;
        });
    }
}
