<?php

namespace App\Livewire\Groups;

use App\Domain\Shared\Traits\UsesBranchScope;
use App\Domain\Training\Enums\GroupStatus;
use App\Domain\Training\Models\Activity;
use App\Domain\Training\Models\TrainingGroup;
use App\Domain\Training\Models\TrainingProgram;
use App\Domain\Training\Services\TrainingGroupService;
use App\Domain\Shared\Exceptions\DomainException;
use App\Livewire\Concerns\AppliesRoleScope;
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;

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

    protected string $scopePermission = 'groups.list';

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

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

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

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

    #[Url]
    public string $sortBy = 'created_at';

    #[Url]
    public string $sortDir = 'desc';

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

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

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

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

    public function sortColumn(string $column): void
    {
        if ($this->sortBy === $column) {
            $this->sortDir = $this->sortDir === 'asc' ? 'desc' : 'asc';
        } else {
            $this->sortBy = $column;
            $this->sortDir = 'asc';
        }
    }

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

    public function deleteGroup(string $uuid): void
    {
        $this->authorize('groups.delete');

        $group = TrainingGroup::where('uuid', $uuid)->firstOrFail();

        try {
            DB::transaction(function () use ($group) {
                // Sessions cascade-delete their attendance records automatically
                $group->sessions()->forceDelete();
                $group->schedules()->delete();
                $group->enrollments()->forceDelete();
                $group->waitlists()->delete();
                $group->forceDelete();
            });

            session()->flash('success', __('تم حذف المجموعة وجميع البيانات المرتبطة بها'));
        } catch (\Throwable $e) {
            session()->flash('error', __('فشل حذف المجموعة: ') . $e->getMessage());
        }
    }

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

        $query = TrainingGroup::query()
            ->with(['program', 'branch', 'headTrainer'])
            ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
            ->when($this->search, fn ($q) => $q->where(function ($sub) {
                $sub->where('name_ar', 'ilike', "%{$this->search}%")
                    ->orWhere('name', 'ilike', "%{$this->search}%")
                    ->orWhere('code', 'ilike', "%{$this->search}%");
            }))
            ->when($this->status, fn ($q) => $q->where('status', $this->status))
            ->when($this->activityFilter, fn ($q) => $q->whereHas('program', fn ($p) => $p->where('activity_id', $this->activityFilter)))
            ->when($this->programFilter, fn ($q) => $q->where('training_program_id', $this->programFilter))
            ->orderBy($this->sortBy, $this->sortDir);

        $this->applyRoleScope($query);

        $programs = TrainingProgram::query()
            ->when($this->activityFilter, fn ($q) => $q->where('activity_id', $this->activityFilter))
            ->orderBy('name_ar')
            ->get(['id', 'name_ar']);

        return view('livewire.groups.group-list', [
            'groups' => $query->paginate(15),
            'activities' => Activity::where('is_active', true)->orderBy('name_ar')->get(['id', 'name_ar']),
            'programs' => $programs,
            'statusOptions' => [
                'forming' => 'قيد التشكيل',
                'active' => 'نشطة',
                'full' => 'ممتلئة',
                'on_hold' => 'متوقفة',
                'completed' => 'مكتملة',
                'cancelled' => 'ملغاة',
            ],
        ]);
    }
}
