<?php

namespace App\Livewire\Programs;

use App\Domain\Shared\Traits\UsesBranchScope;
use App\Domain\Training\Enums\ProgramStatus;
use App\Domain\Training\Models\Activity;
use App\Domain\Training\Models\TrainingProgram;
use App\Domain\Training\Services\TrainingProgramService;
use App\Domain\Shared\Exceptions\DomainException;
use App\Livewire\Concerns\AppliesRoleScope;
use App\Livewire\Concerns\WithSorting;
use App\Models\User;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;

#[Layout('layouts.app')]
#[Title('البرامج التدريبية')]
class ProgramList extends Component
{
    use WithPagination, WithSorting, UsesBranchScope, AppliesRoleScope;

    protected string $scopePermission = 'programs.list';

    #[Url]
    public string $search = '';

    #[Url]
    public string $status = '';

    #[Url]
    public string $activityFilter = '';

    #[Url]
    public string $trainerFilter = '';


    public function updatedSearch(): void
    {
        $this->resetPage();
    }

    public function updatedStatus(): void
    {
        $this->resetPage();
    }

    public function updatedActivityFilter(): void
    {
        $this->trainerFilter = '';
        $this->resetPage();
    }

    public function updatedTrainerFilter(): void
    {
        $this->resetPage();
    }

    public function mount(): void
    {
        if (!request()->has('sortBy')) {
            $this->sortBy = 'name_ar';
        }
        if (!request()->has('sortDir')) {
            $this->sortDir = 'asc';
        }
    }

    public function changeStatus(string $uuid, string $newStatus, TrainingProgramService $service): void
    {
        try {
            $program = TrainingProgram::where('uuid', $uuid)->firstOrFail();
            $service->changeStatus($program, $newStatus);
            session()->flash('success', __('تم تحديث حالة البرنامج بنجاح'));
        } catch (DomainException $e) {
            session()->flash('error', $e->getMessage());
        }
    }

    public function delete(string $uuid, TrainingProgramService $service): void
    {
        try {
            $program = TrainingProgram::where('uuid', $uuid)->firstOrFail();
            $service->delete($program);
            session()->flash('success', __('تم حذف البرنامج بنجاح'));
        } catch (DomainException $e) {
            session()->flash('error', $e->getMessage());
        }
    }

    public function render()
    {
        $branchId = $this->getActiveBranchId();

        $query = TrainingProgram::query()
            ->with(['activity', 'branch'])
            ->withCount('groups')
            ->when($branchId, fn ($q) => $q->where(function ($sub) use ($branchId) {
                $sub->where('branch_id', $branchId)->orWhereNull('branch_id');
            }))
            ->when($this->search, fn ($q) => $q->where(function ($sub) {
                $sub->where('name_ar', 'ilike', "%{$this->search}%")
                    ->orWhere('name', 'ilike', "%{$this->search}%");
            }))
            ->when($this->status, fn ($q) => $q->where('status', $this->status))
            ->when($this->activityFilter, fn ($q) => $q->where('activity_id', $this->activityFilter))
            ->when($this->trainerFilter, fn ($q) => $q->where('default_trainer_id', $this->trainerFilter))
            ->orderBy($this->sortBy, $this->sortDir);

        $this->applyRoleScope($query);

        $trainers = User::query()
            ->select('id', 'name_ar', 'name')
            ->whereHas('roles', fn ($q) => $q->whereIn('slug', ['trainer', 'head_trainer']))
            ->when($this->activityFilter, fn ($q) => $q->whereIn('id',
                TrainingProgram::where('activity_id', $this->activityFilter)
                    ->whereNotNull('default_trainer_id')
                    ->pluck('default_trainer_id')
            ))
            ->orderBy('name_ar')
            ->get();

        return view('livewire.programs.program-list', [
            'programs' => $query->paginate(15),
            'activities' => Activity::where('is_active', true)->orderBy('name_ar')->get(['id', 'name_ar']),
            'trainers' => $trainers,
            'statusOptions' => [
                'draft' => 'مسودة',
                'active' => 'نشط',
                'full' => 'ممتلئ',
                'closed' => 'مغلق',
                'archived' => 'مؤرشف',
            ],
        ]);
    }
}
