<?php

namespace App\Livewire\Leave;

use App\DTO\LeaveApplicationDTO;
use App\Models\LeaveApplication;
use App\Models\User;
use App\Services\LeaveService;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Component;
use Livewire\WithFileUploads;
use Livewire\WithPagination;

class LeaveApplicationIndex extends Component
{
    use WithPagination, WithFileUploads, AuthorizesRequests;

    public string $statusFilter = ''; // '', 'pending', 'approved', 'rejected'
    public string $typeFilter = ''; // '', 'izin', 'sakit'
    public string $search = '';
    public int $perPage = 10;

    // Modal state
    public bool $showCreateModal = false;
    public bool $showApprovalModal = false;

    // Form Submit
    public ?int $target_user_id = null;
    public string $type = 'izin';
    public string $start_date = '';
    public string $end_date = '';
    public string $reason = '';
    public $attachment;

    // Form Approval / Rejection
    public ?int $selectedLeaveId = null;
    public ?LeaveApplication $selectedLeave = null;
    public string $approval_notes = '';
    public string $rejection_reason = '';

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

    public function create(): void
    {
        $this->authorize('create', LeaveApplication::class);
        $this->resetSubmitForm();
        $this->target_user_id = auth()->id();
        $this->showCreateModal = true;
    }

    public function openApprovalModal(int $id): void
    {
        $leave = LeaveApplication::with(['user.role', 'histories.user'])->findOrFail($id);
        $this->authorize('approve', $leave);

        $this->selectedLeaveId = $leave->id;
        $this->selectedLeave = $leave;
        $this->approval_notes = '';
        $this->rejection_reason = '';
        $this->showApprovalModal = true;
    }

    public function save(LeaveService $leaveService): void
    {
        $this->authorize('create', LeaveApplication::class);

        $actor = auth()->user();
        if (!$actor->isSuperAdmin() && !$actor->isAdminTU()) {
            $this->target_user_id = $actor->id;
        }

        $this->validate([
            'target_user_id' => ['required', 'exists:users,id'],
            'type' => ['required', 'in:izin,sakit'],
            'start_date' => ['required', 'date'],
            'end_date' => ['required', 'date', 'after_or_equal:start_date'],
            'reason' => ['required', 'string', 'min:5'],
            'attachment' => ['nullable', 'file', 'mimes:jpg,jpeg,png,pdf', 'max:4096'],
        ], [
            'reason.required' => 'Alasan pengajuan wajib diisi.',
            'start_date.required' => 'Tanggal mulai wajib diisi.',
            'end_date.required' => 'Tanggal selesai wajib diisi.',
        ]);

        $dto = LeaveApplicationDTO::fromArray([
            'user_id' => $this->target_user_id,
            'type' => $this->type,
            'start_date' => $this->start_date,
            'end_date' => $this->end_date,
            'reason' => $this->reason,
        ]);

        $leaveService->submitLeave($dto, $this->attachment);

        session()->flash('toast', ['type' => 'success', 'message' => 'Pengajuan izin / sakit berhasil dikirim.']);
        $this->closeModal();
    }

    public function approve(LeaveService $leaveService): void
    {
        if ($this->selectedLeave) {
            $this->authorize('approve', $this->selectedLeave);

            $leaveService->approve($this->selectedLeave, $this->approval_notes !== '' ? $this->approval_notes : null);
            session()->flash('toast', ['type' => 'success', 'message' => 'Pengajuan izin berhasil disetujui dan status absensi diperbarui.']);
        }

        $this->closeModal();
    }

    public function reject(LeaveService $leaveService): void
    {
        $this->validate([
            'rejection_reason' => ['required', 'string', 'min:3'],
        ], [
            'rejection_reason.required' => 'Alasan penolakan wajib diisi.',
        ]);

        if ($this->selectedLeave) {
            $this->authorize('reject', $this->selectedLeave);

            $leaveService->reject($this->selectedLeave, $this->rejection_reason);
            session()->flash('toast', ['type' => 'info', 'message' => 'Pengajuan izin ditolak.']);
        }

        $this->closeModal();
    }

    public function closeModal(): void
    {
        $this->showCreateModal = false;
        $this->showApprovalModal = false;
        $this->resetSubmitForm();
    }

    private function resetSubmitForm(): void
    {
        $this->target_user_id = auth()->id();
        $this->type = 'izin';
        $this->start_date = '';
        $this->end_date = '';
        $this->reason = '';
        $this->attachment = null;
        $this->selectedLeaveId = null;
        $this->selectedLeave = null;
        $this->resetValidation();
    }

    public function render(LeaveService $leaveService)
    {
        $this->authorize('viewAny', LeaveApplication::class);

        $applications = $leaveService->getPaginatedApplications($this->statusFilter, $this->typeFilter, $this->search, $this->perPage);
        $users = User::where('is_active', true)->get();

        return view('livewire.leave.leave-application-index', [
            'applications' => $applications,
            'users' => $users,
        ])->layout('components.layouts.app');
    }
}
