<?php

namespace App\Services;

use App\Actions\Leave\ApproveLeaveAction;
use App\Actions\Leave\RejectLeaveAction;
use App\Contracts\AuditLogServiceInterface;
use App\Contracts\LeaveRepositoryInterface;
use App\DTO\LeaveApplicationDTO;
use App\Models\LeaveApplication;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Auth;

class LeaveService
{
    public function __construct(
        protected LeaveRepositoryInterface $leaveRepository,
        protected ApproveLeaveAction $approveLeaveAction,
        protected RejectLeaveAction $rejectLeaveAction,
        protected AuditLogServiceInterface $auditLogService
    ) {}

    public function getPaginatedApplications(?string $status = null, ?string $type = null, string $search = '', int $perPage = 15): LengthAwarePaginator
    {
        $viewer = Auth::user();
        $scopedUserId = null;

        if ($viewer && !$viewer->isSuperAdmin() && !$viewer->isAdminTU() && !$viewer->hasPermissionTo('leave.approve')) {
            $scopedUserId = $viewer->id;
        }

        return $this->leaveRepository->getFilteredApplications($status, $type, $search, $perPage, $scopedUserId);
    }

    public function submitLeave(LeaveApplicationDTO $dto, ?UploadedFile $attachmentFile = null): LeaveApplication
    {
        $attachmentPath = null;
        if ($attachmentFile) {
            $attachmentPath = $attachmentFile->store('leaves', 'public');
        }

        $dtoWithFile = LeaveApplicationDTO::fromArray([
            'user_id' => $dto->userId,
            'type' => $dto->type,
            'start_date' => $dto->startDate,
            'end_date' => $dto->endDate,
            'reason' => $dto->reason,
            'attachment_path' => $attachmentPath,
        ]);

        $application = $this->leaveRepository->createApplication($dtoWithFile);
        $this->leaveRepository->addHistory($application->id, Auth::id(), 'submit', 'Mengajukan surat izin / sakit');

        $user = Auth::user();
        $this->auditLogService->log($user, 'LEAVE_SUBMITTED', "Mengajukan izin/sakit ({$application->type}) dari {$application->start_date} s/d {$application->end_date}");

        return $application;
    }

    public function approve(LeaveApplication $application, ?string $notes = null): bool
    {
        $approver = Auth::user();
        $approved = $this->approveLeaveAction->execute($application, $approver->id, $notes);

        if ($approved) {
            $this->auditLogService->log($approver, 'LEAVE_APPROVED', "Menyetujui pengajuan izin #{$application->id} (User ID: {$application->user_id})");
        }

        return $approved;
    }

    public function reject(LeaveApplication $application, string $reason): bool
    {
        $approver = Auth::user();
        $rejected = $this->rejectLeaveAction->execute($application, $approver->id, $reason);

        if ($rejected) {
            $this->auditLogService->log($approver, 'LEAVE_REJECTED', "Menolak pengajuan izin #{$application->id}. Alasan: {$reason}");
        }

        return $rejected;
    }
}
