<?php

declare(strict_types=1);

namespace App\Livewire\Admin\Users;

use App\Models\User;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Layout;
use Livewire\Component;
use Livewire\WithPagination;

#[Layout('layouts.admin')]
final class Index extends Component
{
    use WithPagination;

    public string $search = '';

    public string $roleFilter = '';

    public string $statusFilter = '';

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

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

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

    #[Computed]
    public function users()
    {
        return User::with(['roles', 'properties', 'bookings', 'reviews'])
            ->whereDoesntHave('roles', function ($query) {
                $query->where('name', 'partner');
            })
            ->when($this->search, fn ($q) => $q->where(function ($q) {
                $q->where('first_name', 'like', "%{$this->search}%")
                    ->orWhere('last_name', 'like', "%{$this->search}%")
                    ->orWhere('email', 'like', "%{$this->search}%");
            }))
            ->when($this->roleFilter, fn ($q) => $q->role($this->roleFilter))
            ->when($this->statusFilter, fn ($q) => $q->where('status', $this->statusFilter))
            ->latest()
            ->paginate(12);
    }

    public function suspendUser(int $userId): void
    {
        $user = User::find($userId);

        if ($user) {
            $user->update([
                'status' => 'suspended',
            ]);

            activity()
                ->causedBy(auth()->user())
                ->performedOn($user)
                ->withProperties([
                    'user_id' => $user->id,
                    'email' => $user->email,
                ])
                ->log('user_suspended');

            session()->flash('success', 'User suspended successfully!');
        }
    }

    public function activateUser(int $userId): void
    {
        $user = User::find($userId);

        if ($user && $user->status === 'suspended') {
            $user->update([
                'status' => 'active',
            ]);

            activity()
                ->causedBy(auth()->user())
                ->performedOn($user)
                ->withProperties([
                    'user_id' => $user->id,
                    'email' => $user->email,
                ])
                ->log('user_activated');

            session()->flash('success', 'User activated successfully!');
        }
    }

    public function deleteUser(int $userId): void
    {
        $user = User::find($userId);

        if ($user && ! $user->hasRole('admin')) {
            activity()
                ->causedBy(auth()->user())
                ->performedOn($user)
                ->withProperties([
                    'user_id' => $user->id,
                    'email' => $user->email,
                ])
                ->log('user_deleted');

            $user->delete();

            session()->flash('success', 'User deleted successfully!');
        }
    }

    public function exportUsers(): StreamedResponse
    {
        $users = User::query()
            ->with('roles')
            ->whereDoesntHave('roles', fn ($query) => $query->where('name', 'partner'))
            ->latest()
            ->get();

        return response()->streamDownload(function () use ($users): void {
            $handle = fopen('php://output', 'w');
            fputcsv($handle, ['ID', 'Name', 'Email', 'Status', 'Roles', 'Created At']);

            foreach ($users as $user) {
                fputcsv($handle, [
                    $user->id,
                    $user->name,
                    $user->email,
                    $user->status,
                    $user->roles->pluck('name')->implode('|'),
                    $user->created_at?->toDateTimeString(),
                ]);
            }

            fclose($handle);
        }, 'users-export-'.now()->format('Ymd-His').'.csv');
    }

    public function render()
    {
        return view('livewire.admin.users.index');
    }
}
