<?php

namespace App\Livewire\Admin\ManajemenAdmin;

use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rule;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;
use Livewire\WithPagination;

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

    // ── Filter & Search ──────────────────────────────────────────────────
    public string $search       = '';
    public string $filterRole   = ''; // '' | super_admin | admin
    public string $filterStatus = ''; // '' | active | inactive

    // ── Sorting ───────────────────────────────────────────────────────────
    public string $sortBy        = 'created_at'; // name | email | created_at | last_login_at
    public string $sortDirection = 'desc';

    // ── Modal: Tambah/Edit ────────────────────────────────────────────────
    public bool $showModal = false;
    public ?int $editingId = null;

    public string $name     = '';
    public string $email    = '';
    public string $password = '';
    public string $password_confirmation = '';
    public string $role     = 'admin';
    public bool   $is_active = true;

    // ── Modal: Reset Password ───────────────────────────────────────────────
    public bool $showResetModal = false;
    public ?int $resetId        = null;
    public string $resetPassword = '';
    public string $resetPasswordConfirmation = '';

    // ── Modal: Hapus ─────────────────────────────────────────────────────
    public bool $showDeleteModal = false;
    public ?int $deleteId        = null;

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

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

    protected function rules(): array
    {
        $passwordRule = $this->editingId
            ? ['nullable', 'string', 'min:8', 'confirmed']
            : ['required', 'string', 'min:8', 'confirmed'];

        return [
            'name'     => ['required', 'string', 'max:150'],
            'email'    => [
                'required', 'string', 'email', 'max:150',
                Rule::unique('users', 'email')->ignore($this->editingId),
            ],
            'password' => $passwordRule,
            'role'     => ['required', 'in:super_admin,admin'],
            'is_active' => ['boolean'],
        ];
    }

    protected $validationAttributes = [
        'password' => 'password',
    ];

    protected $messages = [
        'name.required'  => 'Nama wajib diisi.',
        'email.required' => 'Email wajib diisi.',
        'email.email'    => 'Format email tidak valid.',
        'email.unique'   => 'Email sudah digunakan oleh akun lain.',
        'password.required' => 'Password wajib diisi.',
        'password.min'       => 'Password minimal 8 karakter.',
        'password.confirmed' => 'Konfirmasi password tidak cocok.',
        'role.required' => 'Role wajib dipilih.',
    ];

    // ── Tambah/Edit ──────────────────────────────────────────────────────

    public function create(): void
    {
        abort_unless(Auth::user()->can('user.create'), 403);

        $this->resetForm();
        $this->showModal = true;
    }

    public function edit(int $id): void
    {
        abort_unless(Auth::user()->can('user.edit'), 403);

        $admin = User::role(['super_admin', 'admin'])->findOrFail($id);

        $this->editingId = $admin->id;
        $this->name       = $admin->name;
        $this->email       = $admin->email ?? '';
        $this->password    = '';
        $this->password_confirmation = '';
        $this->role        = $admin->getRoleNames()->first() ?? 'admin';
        $this->is_active    = $admin->is_active;
        $this->showModal   = true;
    }

    public function save(): void
    {
        $permission = $this->editingId ? 'user.edit' : 'user.create';
        abort_unless(Auth::user()->can($permission), 403);

        $data = $this->validate();

        // ── Proteksi: tidak boleh ubah role / nonaktifkan akun sendiri ──
        if ($this->editingId && (int) $this->editingId === (int) Auth::id()) {
            $currentRole = Auth::user()->getRoleNames()->first();

            if ($data['role'] !== $currentRole) {
                $this->addError('role', 'Anda tidak dapat mengubah role akun sendiri.');
                return;
            }

            if (! $data['is_active']) {
                $this->addError('is_active', 'Anda tidak dapat menonaktifkan akun sendiri.');
                return;
            }
        }

        $payload = [
            'name'      => $data['name'],
            'email'     => $data['email'],
            'is_active' => $data['is_active'],
        ];

        if (! empty($data['password'])) {
            $payload['password'] = Hash::make($data['password']);
        }

        if ($this->editingId) {
            $admin = User::findOrFail($this->editingId);
            $admin->update($payload);
            $admin->syncRoles([$data['role']]);
            $this->dispatch('notify', type: 'success', message: 'Admin berhasil diperbarui.');
        } else {
            $payload['password'] = Hash::make($data['password']);
            $admin = User::create($payload);
            $admin->assignRole($data['role']);
            $this->dispatch('notify', type: 'success', message: 'Admin berhasil ditambahkan.');
        }

        $this->showModal = false;
        $this->resetForm();
    }

    // ── Aktif / Nonaktif ─────────────────────────────────────────────────

    public function toggleActive(int $id): void
    {
        abort_unless(Auth::user()->can('user.edit'), 403);

        if ((int) $id === (int) Auth::id()) {
            $this->dispatch('notify', type: 'error', message: 'Anda tidak dapat menonaktifkan akun sendiri.');
            return;
        }

        $admin = User::role(['super_admin', 'admin'])->findOrFail($id);
        $admin->update(['is_active' => ! $admin->is_active]);

        $label = $admin->fresh()->is_active ? 'diaktifkan' : 'dinonaktifkan';
        $this->dispatch('notify', type: 'success', message: "Admin berhasil {$label}.");
    }

    // ── Reset Password ───────────────────────────────────────────────────

    public function openResetModal(int $id): void
    {
        abort_unless(Auth::user()->can('user.edit'), 403);

        $this->resetId                    = $id;
        $this->resetPassword              = '';
        $this->resetPasswordConfirmation  = '';
        $this->resetValidation();
        $this->showResetModal = true;
    }

    public function resetPasswordSubmit(): void
    {
        abort_unless(Auth::user()->can('user.edit'), 403);

        $this->validate([
            'resetPassword' => ['required', 'string', 'min:8', 'same:resetPasswordConfirmation'],
            'resetPasswordConfirmation' => ['required', 'string'],
        ], [
            'resetPassword.required' => 'Password baru wajib diisi.',
            'resetPassword.min'      => 'Password minimal 8 karakter.',
            'resetPassword.same'     => 'Konfirmasi password tidak cocok.',
        ]);

        $admin = User::role(['super_admin', 'admin'])->findOrFail($this->resetId);
        $admin->update(['password' => Hash::make($this->resetPassword)]);

        $this->showResetModal = false;
        $this->resetId         = null;
        $this->resetPassword   = '';
        $this->resetPasswordConfirmation = '';

        $this->dispatch('notify', type: 'success', message: 'Password admin berhasil direset.');
    }

    // ── Hapus ────────────────────────────────────────────────────────────

    public function confirmDelete(int $id): void
    {
        abort_unless(Auth::user()->can('user.delete'), 403);

        if ((int) $id === (int) Auth::id()) {
            $this->dispatch('notify', type: 'error', message: 'Anda tidak dapat menghapus akun sendiri.');
            return;
        }

        $this->deleteId        = $id;
        $this->showDeleteModal = true;
    }

    public function delete(): void
    {
        abort_unless(Auth::user()->can('user.delete'), 403);

        if ((int) $this->deleteId === (int) Auth::id()) {
            $this->dispatch('notify', type: 'error', message: 'Anda tidak dapat menghapus akun sendiri.');
            $this->showDeleteModal = false;
            return;
        }

        User::role(['super_admin', 'admin'])->findOrFail($this->deleteId)->delete();

        $this->showDeleteModal = false;
        $this->deleteId         = null;
        $this->dispatch('notify', type: 'success', message: 'Admin berhasil dihapus.');
    }

    private function resetForm(): void
    {
        $this->editingId = null;
        $this->name       = '';
        $this->email       = '';
        $this->password    = '';
        $this->password_confirmation = '';
        $this->role         = 'admin';
        $this->is_active     = true;
        $this->resetValidation();
    }

    public function render()
    {
        $admins = User::role(['super_admin', 'admin'])
            ->with('roles')
            ->when($this->search, fn ($q) =>
                $q->where(function ($q) {
                    $q->where('name', 'like', "%{$this->search}%")
                      ->orWhere('email', 'like', "%{$this->search}%");
                }))
            ->when($this->filterRole, fn ($q) =>
                $q->role($this->filterRole))
            ->when($this->filterStatus !== '', fn ($q) =>
                $q->where('is_active', $this->filterStatus === 'active'))
            ->orderBy($this->sortBy, $this->sortDirection)
            ->paginate(15);

        return view('livewire.admin.manajemen-admin.index', compact('admins'));
    }
}
