<?php

namespace Modules\Transport\Services;

use App\Models\ActivityLogModel;
use App\Models\EmployeeModel;
use App\Models\TransportDriverModel;

class DriverService
{
    protected TransportDriverModel $drivers;
    protected EmployeeModel $employees;
    protected ActivityLogModel $activity;

    public function __construct()
    {
        $this->drivers   = new TransportDriverModel();
        $this->employees = new EmployeeModel();
        $this->activity  = new ActivityLogModel();
    }

    public function create(array $input, ?int $actingUserId): array
    {
        $employeeId = $this->resolveEmployeeId($input['employee_id'] ?? null);
        if ($employeeId === false) {
            return ['success' => false, 'errors' => ['employee_id' => 'Select an active employee.']];
        }
        if ($this->drivers->isEmployeeTaken($employeeId)) {
            return ['success' => false, 'errors' => ['employee_id' => 'This employee is already registered as a driver.']];
        }

        $license = trim((string) ($input['license_number'] ?? ''));
        if ($license === '') {
            return ['success' => false, 'errors' => ['license_number' => 'License number is required.']];
        }

        $data = $this->mapInput($input, $actingUserId);
        $data['number']       = $this->drivers->nextNumber();
        $data['employee_id']  = $employeeId;
        $data['license_number'] = $license;
        $data['created_by']   = $actingUserId;
        $data['updated_by']   = $actingUserId;

        if (! $this->drivers->insert($data, true)) {
            return ['success' => false, 'errors' => $this->drivers->errors()];
        }

        $id = (int) $this->drivers->getInsertID();
        $this->activity->log('transport_drivers', 'created', $actingUserId, "Created driver #{$id} ({$data['number']})", (string) $id);

        return ['success' => true, 'id' => $id];
    }

    public function update(int $id, array $input, ?int $actingUserId): array
    {
        $driver = $this->drivers->find($id);
        if (! $driver) {
            return ['success' => false, 'errors' => ['id' => 'Driver not found.']];
        }

        $employeeId = $this->resolveEmployeeId($input['employee_id'] ?? null);
        if ($employeeId === false) {
            return ['success' => false, 'errors' => ['employee_id' => 'Select an active employee.']];
        }
        if ($this->drivers->isEmployeeTaken($employeeId, $id)) {
            return ['success' => false, 'errors' => ['employee_id' => 'This employee is already registered as a driver.']];
        }

        $license = trim((string) ($input['license_number'] ?? ''));
        if ($license === '') {
            return ['success' => false, 'errors' => ['license_number' => 'License number is required.']];
        }

        $data = $this->mapInput($input, $actingUserId);
        $data['employee_id']      = $employeeId;
        $data['license_number']   = $license;
        $data['updated_by']       = $actingUserId;

        if (! $this->drivers->update($id, $data)) {
            return ['success' => false, 'errors' => $this->drivers->errors()];
        }

        $this->activity->log('transport_drivers', 'updated', $actingUserId, "Updated driver #{$id}", (string) $id);

        return ['success' => true];
    }

    public function delete(int $id, ?int $actingUserId): array
    {
        if (! $this->drivers->find($id)) {
            return ['success' => false, 'error' => 'Driver not found.'];
        }

        $this->drivers->delete($id);
        $this->activity->log('transport_drivers', 'deleted', $actingUserId, "Deleted driver #{$id}", (string) $id);

        return ['success' => true];
    }

    protected function mapInput(array $input, ?int $actingUserId): array
    {
        $status = (string) ($input['status'] ?? 'active');
        if (! in_array($status, TransportDriverModel::STATUSES, true)) {
            $status = 'active';
        }

        $expiry = trim((string) ($input['license_expiry'] ?? ''));

        return [
            'license_class'   => trim((string) ($input['license_class'] ?? '')) ?: null,
            'license_expiry'  => $expiry !== '' ? $expiry : null,
            'phone'           => trim((string) ($input['phone'] ?? '')) ?: null,
            'status'          => $status,
            'notes'           => trim((string) ($input['notes'] ?? '')) ?: null,
        ];
    }

    protected function resolveEmployeeId($value): int|false
    {
        if ($value === null || $value === '') {
            return false;
        }
        $id = (int) $value;
        $emp = $this->employees->find($id);

        return ($emp && ($emp['status'] ?? '') === 'active') ? $id : false;
    }
}
