<?php

namespace Modules\Payroll\Services;

use App\Models\ActivityLogModel;
use App\Models\EmployeeModel;
use App\Models\EmployeeSalaryStructureModel;

class SalaryStructureService
{
    protected EmployeeSalaryStructureModel $structures;
    protected EmployeeModel $employees;
    protected ActivityLogModel $activity;

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

    public function create(array $input, ?int $actingUserId): array
    {
        $employeeId    = (int) ($input['employee_id'] ?? 0);
        $effectiveFrom = $input['effective_from'] ?? date('Y-m-d');

        $employee = $this->employees->find($employeeId);
        if (! $employee) {
            return ['success' => false, 'errors' => ['employee_id' => 'Employee not found.']];
        }

        $existing = $this->structures->getCurrentForEmployee($employeeId);
        if ($existing) {
            $dayBefore = date('Y-m-d', strtotime($effectiveFrom . ' -1 day'));
            $this->structures->closeOpenStructure($employeeId, $dayBefore);
        }

        $data = $this->mapInput($input, $employeeId, $actingUserId);
        $id   = $this->structures->insert($data);

        $this->activity->log(
            'payroll_salary',
            'created',
            $actingUserId,
            "Created salary structure #{$id} for employee #{$employeeId}",
            (string) $id
        );

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

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

        $data = $this->mapInput($input, (int) $structure['employee_id'], $actingUserId, false);
        $this->structures->update($id, $data);

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

        return ['success' => true];
    }

    protected function mapInput(array $input, int $employeeId, ?int $actingUserId, bool $isCreate = true): array
    {
        $data = [
            'employee_id'         => $employeeId,
            'effective_from'      => $input['effective_from'] ?? date('Y-m-d'),
            'effective_to'        => $input['effective_to'] ?? null,
            'basic_salary'        => round((float) ($input['basic_salary'] ?? 0), 3),
            'social_allowance'    => round((float) ($input['social_allowance'] ?? 0), 3),
            'housing_allowance'   => round((float) ($input['housing_allowance'] ?? 0), 3),
            'transport_allowance' => round((float) ($input['transport_allowance'] ?? 0), 3),
            'other_allowances'    => round((float) ($input['other_allowances'] ?? 0), 3),
            'payment_method'      => in_array($input['payment_method'] ?? 'bank', ['bank', 'cash'], true)
                ? $input['payment_method'] : 'bank',
            'notes'               => trim((string) ($input['notes'] ?? '')) ?: null,
            'updated_by'          => $actingUserId,
        ];

        if ($isCreate) {
            $data['created_by'] = $actingUserId;
        }

        return $data;
    }
}
