<?php

namespace App\Livewire\WhatsApp;

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 App\Domain\WhatsApp\Services\WhatsAppService;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Layout('layouts.app')]
#[Title('إرسال واتساب')]
class SendMessage extends Component
{
    use UsesBranchScope;

    public string $sendMode = 'single';
    public string $phone = '';
    public string $messageBody = '';
    public string $selectedGroup = '';
    public string $selectedStatus = '';
    public array $selectedParticipants = [];
    public bool $isSending = false;
    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:4096',
            'sendMode' => 'required|in:single,group,status,custom',
            'phone' => 'required_if:sendMode,single|nullable|string|max:20',
            'selectedGroup' => 'required_if:sendMode,group',
            'selectedStatus' => 'required_if:sendMode,status',
            'selectedParticipants' => 'required_if:sendMode,custom|array',
        ];
    }

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

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

        $whatsapp = app(WhatsAppService::class);

        if (!$whatsapp->isConfigured()) {
            session()->flash('error', 'خدمة الواتساب غير مفعلة. تأكد من إعداد WHATSAPP_PHONE_NUMBER_ID و WHATSAPP_ACCESS_TOKEN');
            return;
        }

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

        $academyId = (int) app('current_academy')?->id;

        if ($this->sendMode === 'single') {
            $msg = $whatsapp->sendText(
                to: $this->phone,
                body: $this->messageBody,
                academyId: $academyId,
                senderId: auth()->id(),
            );

            if ($msg->status->value === 'failed') {
                $this->failedCount = 1;
                session()->flash('error', 'فشل الإرسال: ' . ($msg->error_message ?? 'خطأ غير معروف'));
            } else {
                $this->sentCount = 1;
            }
        } else {
            $phones = $this->getRecipientPhones();

            if (empty($phones)) {
                session()->flash('error', 'لا يوجد أرقام واتساب للمستلمين المحددين');
                $this->isSending = false;
                return;
            }

            $results = $whatsapp->sendBulkText(
                recipients: $phones,
                body: $this->messageBody,
                academyId: $academyId,
                senderId: auth()->id(),
            );

            $this->sentCount = $results['sent'];
            $this->failedCount = $results['failed'];
        }

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

        if ($this->failedCount === 0 && $this->sentCount > 0) {
            session()->flash('success', "تم إرسال الرسالة بنجاح إلى {$this->sentCount} مستلم");
        } elseif ($this->sentCount > 0) {
            session()->flash('warning', "تم الإرسال: {$this->sentCount} ناجح، {$this->failedCount} فشل");
        }
    }

    public function resetForm(): void
    {
        $this->reset([
            'messageBody', 'phone', 'selectedGroup', 'selectedStatus',
            'selectedParticipants', 'sendComplete', 'sentCount', 'failedCount',
        ]);
        $this->sendMode = 'single';
    }

    public function getRecipientCount(): int
    {
        if ($this->sendMode === 'single') {
            return $this->phone ? 1 : 0;
        }

        return count($this->getRecipientPhones());
    }

    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,phone')
            ->whereIn('status', [
                ParticipantStatus::Active->value,
                ParticipantStatus::Registered->value,
            ])
            ->get(['id', 'person_id']);

        $whatsapp = app(WhatsAppService::class);

        return view('livewire.whatsapp.send-message', [
            'groups' => $groups,
            'statuses' => ParticipantStatus::cases(),
            'allParticipants' => $allParticipants,
            'isConfigured' => $whatsapp->isConfigured(),
        ]);
    }

    private function getRecipientPhones(): array
    {
        $branchId = $this->getActiveBranchId();

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

        $participants = match ($this->sendMode) {
            'group' => $query->whereHas('enrollments', function ($q) {
                $q->where('training_group_id', $this->selectedGroup)
                    ->where('status', 'active');
            })->get(),
            'status' => $query->where('status', $this->selectedStatus)->get(),
            'custom' => $query->whereIn('id', $this->selectedParticipants)->get(),
            default => collect(),
        };

        return $participants
            ->map(fn ($p) => $p->person?->phone)
            ->filter()
            ->unique()
            ->values()
            ->toArray();
    }
}
