<?php

namespace App\Livewire;

use App\Domain\Attendance\Enums\AttendanceStatus;
use App\Domain\Attendance\Models\AttendanceRecord;
use App\Domain\Financial\Enums\InvoiceStatus;
use App\Domain\Financial\Models\Invoice;
use App\Domain\Financial\Models\Payment;
use App\Domain\Identity\Models\Person;
use App\Domain\Inventory\Models\Product;
use App\Domain\Participant\Models\Participant;
use App\Domain\POS\Models\POSTransaction;
use App\Domain\Shared\Traits\UsesBranchScope;
use App\Domain\Training\Models\Enrollment;
use App\Domain\Training\Models\TrainingGroup;
use App\Domain\Training\Models\TrainingSession;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Layout('layouts.app')]
#[Title('لوحة التحكم')]
class Dashboard extends Component
{
    use UsesBranchScope;

    public function render()
    {
        $today = now()->toDateString();
        $thisMonth = now()->startOfMonth()->toDateString();
        $branchId = $this->getActiveBranchId();

        $stats = [
            'active_participants' => Participant::where('status', 'active')
                ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))->count(),
            'active_enrollments' => Enrollment::where('status', 'active')
                ->when($branchId, fn ($q) => $q->whereHas('group', fn ($g) => $g->where('branch_id', $branchId)))->count(),
            'active_groups' => TrainingGroup::whereIn('status', ['active', 'full'])
                ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))->count(),
            'today_sessions' => TrainingSession::where('session_date', $today)
                ->when($branchId, fn ($q) => $q->whereHas('group', fn ($g) => $g->where('branch_id', $branchId)))->count(),
        ];

        $financial = [
            'revenue_this_month' => Payment::where('status', 'confirmed')
                ->whereDate('created_at', '>=', $thisMonth)
                ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))->sum('amount'),
            'outstanding_invoices' => Invoice::whereIn('status', [
                InvoiceStatus::Sent, InvoiceStatus::PartiallyPaid, InvoiceStatus::Overdue,
            ])->when($branchId, fn ($q) => $q->whereHasMorph('billable', [Participant::class], fn ($p) => $p->where('branch_id', $branchId)))->sum('due_amount'),
            'pos_today' => POSTransaction::whereDate('processed_at', $today)
                ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))->sum('total_amount'),
            'pos_today_count' => POSTransaction::whereDate('processed_at', $today)
                ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))->count(),
        ];

        $todaySessions = TrainingSession::where('session_date', $today)
            ->when($branchId, fn ($q) => $q->whereHas('group', fn ($g) => $g->where('branch_id', $branchId)))
            ->pluck('id');

        $attendance = [
            'expected' => AttendanceRecord::whereIn('training_session_id', $todaySessions)->count(),
            'present' => AttendanceRecord::whereIn('training_session_id', $todaySessions)
                ->whereIn('status', [AttendanceStatus::Present, AttendanceStatus::Late])->count(),
            'absent' => AttendanceRecord::whereIn('training_session_id', $todaySessions)
                ->whereIn('status', [AttendanceStatus::Absent, AttendanceStatus::NoShow])->count(),
        ];
        $attendance['rate'] = $attendance['expected'] > 0
            ? round(($attendance['present'] / $attendance['expected']) * 100, 0)
            : 0;

        $lowStockCount = Product::where('track_inventory', true)
            ->where('is_active', true)
            ->whereNotNull('min_stock_level')
            ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
            ->whereHas('inventoryLevels', function ($q) {
                $q->whereRaw('quantity_on_hand < (SELECT min_stock_level FROM products WHERE products.id = inventory_levels.product_id)');
            })->count();

        $nearFullGroups = TrainingGroup::where('status', 'active')
            ->whereRaw('current_count >= max_capacity * 0.9')
            ->where('max_capacity', '>', 0)
            ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
            ->count();

        $recentEnrollments = Enrollment::where('status', 'active')
            ->where('created_at', '>=', now()->subDays(7))
            ->when($branchId, fn ($q) => $q->whereHas('group', fn ($g) => $g->where('branch_id', $branchId)))
            ->count();

        $overdueInvoices = Invoice::where('status', InvoiceStatus::Overdue)
            ->when($branchId, fn ($q) => $q->whereHasMorph('billable', [Participant::class], fn ($p) => $p->where('branch_id', $branchId)))
            ->with('billable')
            ->orderBy('due_date')
            ->limit(5)
            ->get();

        $todaySchedule = TrainingSession::where('session_date', $today)
            ->when($branchId, fn ($q) => $q->whereHas('group', fn ($g) => $g->where('branch_id', $branchId)))
            ->with(['group.program', 'group.branch'])
            ->orderBy('start_time')
            ->get();

        $upcomingBirthdays = Person::whereRaw("EXTRACT(MONTH FROM date_of_birth) = ? AND EXTRACT(DAY FROM date_of_birth) >= ?", [
                now()->month, now()->day,
            ])
            ->orWhereRaw("EXTRACT(MONTH FROM date_of_birth) = ? AND EXTRACT(DAY FROM date_of_birth) < ?", [
                now()->addMonth()->month, now()->day,
            ])
            ->whereHas('participant', function ($q) use ($branchId) {
                $q->where('status', 'active')
                    ->when($branchId, fn ($pq) => $pq->where('branch_id', $branchId));
            })
            ->orderByRaw("EXTRACT(MONTH FROM date_of_birth), EXTRACT(DAY FROM date_of_birth)")
            ->limit(5)
            ->get();

        $recentPayments = Payment::where('status', 'confirmed')
            ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
            ->with('creator')
            ->orderByDesc('created_at')
            ->limit(5)
            ->get();

        return view('livewire.dashboard', [
            'stats' => $stats,
            'financial' => $financial,
            'attendance' => $attendance,
            'lowStockCount' => $lowStockCount,
            'nearFullGroups' => $nearFullGroups,
            'recentEnrollments' => $recentEnrollments,
            'overdueInvoices' => $overdueInvoices,
            'todaySchedule' => $todaySchedule,
            'upcomingBirthdays' => $upcomingBirthdays,
            'recentPayments' => $recentPayments,
        ]);
    }
}
