<?php

namespace App\Livewire\Messaging;

use App\Domain\Notification\Services\NotificationService;
use App\Domain\Participant\Enums\MembershipType;
use App\Domain\Participant\Enums\ParticipantStatus;
use App\Domain\Participant\Models\Participant;
use App\Domain\Shared\Traits\UsesBranchScope;
use App\Domain\Training\Models\TrainingGroup;
use Illuminate\Support\Facades\Log;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Layout('layouts.app')]
#[Title('رسائل جماعية')]
class BulkMessage extends Component
{
    use UsesBranchScope;

    public string $selectionMode = 'group'; // group, status, membership, custom
    public string $selectedGroup = '';
    public string $selectedStatus = '';
    public string $selectedMembership = '';
    public array $selectedParticipants = [];
    public string $messageBody = '';
    public bool $sendSms = true;
    public bool $sendEmail = false;
    public bool $showPreview = false;
    public bool $isSending = false;

    public int $recipientCount = 0;
    public int $sentCount = 0;
    public int $failedCount = 0;
    public bool $sendComplete = false;

    public function mount(): void
    {
        $this->authorize('notifications.manage');
    }

    public function rules(): array
    {
        return [
            'messageBody' => 'required|string|max:640',
            'selectionMode' => 'required|in:group,status,membership,custom',
            'selectedGroup' => 'required_if:selectionMode,group',
            'selectedStatus' => 'required_if:selectionMode,status',
            'selectedMembership' => 'required_if:selectionMode,membership',
            'selectedParticipants' => 'required_if:selectionMode,custom|array',
        ];
    }

    public function messages(): array
    {
        return [
            'messageBody.required' => __('نص الرسالة مطلوب'),
            'messageBody.max' => __('نص الرسالة يجب أن لا يتجاوز 640 حرف'),
            'selectedGroup.required_if' => __('يجب اختيار مجموعة'),
            'selectedStatus.required_if' => __('يجب اختيار حالة'),
            'selectedMembership.required_if' => __('يجب اختيار نوع العضوية'),
            'selectedParticipants.required_if' => __('يجب اختيار مشتركين'),
        ];
    }

    public function updatedSelectionMode(): void
    {
        $this->resetPreview();
    }

    public function updatedSelectedGroup(): void
    {
        $this->resetPreview();
    }

    public function updatedSelectedStatus(): void
    {
        $this->resetPreview();
    }

    public function updatedSelectedMembership(): void
    {
        $this->resetPreview();
    }

    public function updatedSelectedParticipants(): void
    {
        $this->resetPreview();
    }

    public function preview(): void
    {
        $this->recipientCount = $this->getRecipientsQuery()->count();
        $this->showPreview = true;
    }

    public function send(NotificationService $notificationService): void
    {
        $this->validate();

        if ($this->recipientCount === 0) {
            session()->flash('error', __('لا يوجد مستلمين للرسالة'));
            return;
        }

        $this->isSending = true;
        $this->sentCount = 0;
        $this->failedCount = 0;

        $academyId = (int) app('current_academy')?->id;
        $participants = $this->getRecipientsQuery()
            ->with('person')
            ->get();

        foreach ($participants as $participant) {
            $person = $participant->person;
            if (!$person) {
                $this->failedCount++;
                continue;
            }

            $phone = $this->sendSms ? $person->phone : null;
            $email = $this->sendEmail ? $person->email : null;

            if (!$phone && !$email) {
                $this->failedCount++;
                continue;
            }

            try {
                $notificationService->send(
                    eventType: 'bulk_message',
                    recipientType: 'participant',
                    recipientId: $participant->id,
                    academyId: $academyId,
                    variables: [
                        'message' => $this->messageBody,
                        'participant_name' => $person->name_ar ?? $person->name ?? '',
                    ],
                    recipientEmail: $email,
                    recipientPhone: $phone,
                );
                $this->sentCount++;
            } catch (\Throwable $e) {
                Log::warning("Bulk message failed for participant {$participant->id}: " . $e->getMessage());
                $this->failedCount++;
            }
        }

        $this->isSending = false;
        $this->sendComplete = true;

        if ($this->failedCount === 0) {
            session()->flash('success', __('تم إرسال الرسالة بنجاح إلى :count مستلم', ['count' => $this->sentCount]));
        } else {
            session()->flash('warning', __('تم الإرسال: :sent ناجح، :failed فشل', [
                'sent' => $this->sentCount,
                'failed' => $this->failedCount,
            ]));
        }
    }

    public function resetForm(): void
    {
        $this->reset([
            'messageBody', 'selectedGroup', 'selectedStatus',
            'selectedMembership', 'selectedParticipants',
            'showPreview', 'sendComplete', 'sentCount', 'failedCount', 'recipientCount',
        ]);
        $this->selectionMode = 'group';
        $this->sendSms = true;
        $this->sendEmail = false;
    }

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

        $groups = TrainingGroup::query()
            ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
            ->whereIn('status', ['active', 'forming', 'full'])
            ->orderBy('name_ar')
            ->get(['id', 'name_ar', 'name', 'current_count']);

        $allParticipants = Participant::query()
            ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
            ->with('person:id,name_ar,name')
            ->whereIn('status', [
                ParticipantStatus::Active->value,
                ParticipantStatus::Registered->value,
            ])
            ->orderByRaw("(SELECT name_ar FROM people WHERE people.id = participants.person_id) ASC")
            ->get(['id', 'person_id']);

        return view('livewire.messaging.bulk-message', [
            'groups' => $groups,
            'statuses' => ParticipantStatus::cases(),
            'membershipTypes' => MembershipType::cases(),
            'allParticipants' => $allParticipants,
        ]);
    }

    private function getRecipientsQuery()
    {
        $branchId = $this->getActiveBranchId();

        $query = Participant::query()
            ->when($branchId, fn ($q) => $q->where('branch_id', $branchId));

        return match ($this->selectionMode) {
            'group' => $query->whereHas('enrollments', function ($q) {
                $q->where('training_group_id', $this->selectedGroup)
                    ->where('status', 'active');
            }),
            'status' => $query->where('status', $this->selectedStatus),
            'membership' => $query->where('membership_type', $this->selectedMembership),
            'custom' => $query->whereIn('id', $this->selectedParticipants),
        };
    }

    private function resetPreview(): void
    {
        $this->showPreview = false;
        $this->recipientCount = 0;
        $this->sendComplete = false;
    }
}
