<?php

declare(strict_types=1);

namespace App\Livewire\Admin\Communications;

use App\Mail\BulkEmailMail;
use App\Models\User;
use Illuminate\Support\Facades\Mail;
use Livewire\Attributes\Layout;
use Livewire\Component;

#[Layout('layouts.admin')]
final class SendEmail extends Component
{
    public string $recipientType = 'all';

    public array $selectedRoles = [];

    public array $selectedUsers = [];

    public string $subject = '';

    public string $message = '';

    public bool $sendTestEmail = false;

    public string $testEmail = '';

    public bool $showPreviewModal = false;

    public function mount(): void
    {
        $this->testEmail = auth()->user()->email;
    }

    public function openPreview(): void
    {
        $this->validate([
            'subject' => ['required', 'string', 'max:255'],
            'message' => ['required', 'string', 'min:10'],
        ]);

        $this->showPreviewModal = true;
    }

    public function closePreview(): void
    {
        $this->showPreviewModal = false;
    }

    protected function rules(): array
    {
        $rules = [
            'subject' => ['required', 'string', 'max:255'],
            'message' => ['required', 'string', 'min:10'],
        ];

        if ($this->recipientType === 'roles') {
            $rules['selectedRoles'] = ['required', 'array', 'min:1'];
        }

        if ($this->recipientType === 'specific') {
            $rules['selectedUsers'] = ['required', 'array', 'min:1'];
        }

        if ($this->sendTestEmail) {
            $rules['testEmail'] = ['required', 'email'];
        }

        return $rules;
    }

    public function sendTestMail(): void
    {
        $this->validate([
            'subject' => ['required', 'string', 'max:255'],
            'message' => ['required', 'string', 'min:10'],
            'testEmail' => ['required', 'email'],
        ]);

        Mail::to($this->testEmail)->send(
            new BulkEmailMail($this->subject, $this->message, 'Test User')
        );

        session()->flash('success', 'Test email sent to '.$this->testEmail);
    }

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

        $recipients = $this->getRecipients();

        if ($recipients->isEmpty()) {
            $this->addError('recipientType', 'No recipients found for the selected criteria.');

            return;
        }

        $count = 0;
        foreach ($recipients as $user) {
            Mail::to($user->email)->send(
                new BulkEmailMail($this->subject, $this->message, $user->name)
            );
            $count++;
        }

        session()->flash('success', "Email sent successfully to {$count} recipient(s).");

        $this->reset(['subject', 'message', 'recipientType', 'selectedRoles', 'selectedUsers']);
    }

    private function getRecipients()
    {
        $query = User::where('status', 'active')->whereNotNull('email_verified_at');

        return match ($this->recipientType) {
            'all' => $query->get(),
            'roles' => $query->whereHas('roles', function ($q) {
                $q->whereIn('name', $this->selectedRoles);
            })->get(),
            'specific' => User::whereIn('id', $this->selectedUsers)
                ->where('status', 'active')
                ->whereNotNull('email_verified_at')
                ->get(),
            default => collect(),
        };
    }

    public function getRecipientsCountProperty(): int
    {
        return $this->getRecipients()->count();
    }

    public function render()
    {
        $allUsers = User::where('status', 'active')
            ->whereNotNull('email_verified_at')
            ->orderBy('name')
            ->get(['id', 'name', 'email']);

        return view('livewire.admin.communications.send-email', [
            'allUsers' => $allUsers,
        ]);
    }
}
