<?php

namespace App\Modules\HR\Shifts\Listeners;

use App\Models\User;
use App\Modules\Admin\ActivityLog\DTOs\ActivityLogWriteData;
use App\Modules\Admin\ActivityLog\Services\ActivityLogService;
use App\Modules\HR\Shifts\Events\ShiftAssigned;
use App\Modules\HR\Shifts\Events\ShiftAssignmentEnded;
use App\Modules\HR\Shifts\Events\ShiftCreated;
use App\Modules\HR\Shifts\Events\ShiftDeactivated;
use App\Modules\HR\Shifts\Events\ShiftReactivated;
use App\Modules\HR\Shifts\Events\ShiftUpdated;
use App\Modules\HR\Shifts\Models\EmployeeShiftAssignment;
use App\Modules\HR\Shifts\Models\Shift;

class ShiftActivityLogListener
{
    public function __construct(
        private readonly ActivityLogService $activityLog,
    ) {}

    public function handleCreated(ShiftCreated $event): void
    {
        $this->logShift($event->shift, 'shift_created', __('activity_logs.actions.shift_created', ['name' => $event->shift->name]));
    }

    public function handleUpdated(ShiftUpdated $event): void
    {
        $this->logShift($event->shift, 'shift_updated', __('activity_logs.actions.shift_updated', ['name' => $event->shift->name]));
    }

    public function handleDeactivated(ShiftDeactivated $event): void
    {
        $this->logShift($event->shift, 'shift_deactivated', __('activity_logs.actions.shift_deactivated', ['name' => $event->shift->name]));
    }

    public function handleReactivated(ShiftReactivated $event): void
    {
        $this->logShift($event->shift, 'shift_reactivated', __('activity_logs.actions.shift_reactivated', ['name' => $event->shift->name]));
    }

    public function handleAssigned(ShiftAssigned $event): void
    {
        $a = $event->assignment->loadMissing(['employee', 'shift']);
        $this->logAssignment(
            $a,
            'shift_assigned',
            __('activity_logs.actions.shift_assigned', [
                'employee' => $a->employee?->full_name ?? '—',
                'shift' => $a->shift?->name ?? '—',
            ]),
            null,
        );
    }

    public function handleAssignmentEnded(ShiftAssignmentEnded $event): void
    {
        $a = $event->assignment->loadMissing(['employee', 'shift']);
        $this->logAssignment(
            $a,
            'shift_assignment_ended',
            __('activity_logs.actions.shift_assignment_ended', [
                'employee' => $a->employee?->full_name ?? '—',
                'shift' => $a->shift?->name ?? '—',
            ]),
            $event->actorUserId,
        );
    }

    private function logAssignment(
        EmployeeShiftAssignment $a,
        string $action,
        string $description,
        ?int $userId,
    ): void {
        $tenantId = (int) $a->tenant_id;
        if ($tenantId < 1) {
            return;
        }
        if ($userId === null) {
            $user = auth()->user();
            $userId = $user instanceof User ? $user->id : null;
        }
        $this->activityLog->log(new ActivityLogWriteData(
            tenantId: $tenantId,
            userId: $userId,
            module: 'hr',
            action: $action,
            entityType: EmployeeShiftAssignment::class,
            entityId: $a->id,
            description: $description,
        ));
    }

    private function logShift(Shift $shift, string $action, string $description): void
    {
        $tenantId = (int) $shift->tenant_id;
        if ($tenantId < 1) {
            return;
        }
        $user = auth()->user();
        $userId = $user instanceof User ? $user->id : null;
        $this->activityLog->log(new ActivityLogWriteData(
            tenantId: $tenantId,
            userId: $userId,
            module: 'hr',
            action: $action,
            entityType: Shift::class,
            entityId: $shift->id,
            description: $description,
        ));
    }
}
