<?php

declare(strict_types=1);

namespace ApiModel\Action;

use ApiModel\Service\EmployeeService;
use ApiModel\Service\PayrollService;
use ApiModel\Service\LeaveService;
use ApiModel\Shared\Http\HttpUtil;
use ApiModel\Shared\Support\AuthContext;
use ApiModel\Shared\Support\CompanyContext;
use Psr\Http\Message\ServerRequestInterface;

final class HrAction
{
    public function __construct(
        private readonly EmployeeService $employeeService,
        private readonly PayrollService $payrollService,
        private readonly LeaveService $leaveService
    ) {}

    // ==========================================
    // DEPARTAMENTOS
    // ==========================================

    /** @return list<array<string, mixed>> */
    public function listDepartments(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->employeeService->listDepartments($ctx['company_id']);
    }

    /** @return array<string, mixed> */
    public function getDepartment(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->employeeService->getDepartment($ctx['company_id'], $id);
    }

    /** @return array<string, mixed> */
    public function createDepartment(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->employeeService->createDepartment($ctx['company_id'], HttpUtil::parseJson($request));
    }

    /** @return array<string, mixed> */
    public function updateDepartment(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->employeeService->updateDepartment($ctx['company_id'], $id, HttpUtil::parseJson($request));
    }

    /** @return array{ok: true} */
    public function deleteDepartment(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $this->employeeService->deleteDepartment($ctx['company_id'], $id);

        return ['ok' => true];
    }

    // ==========================================
    // EMPLEADOS
    // ==========================================

    /** @return list<array<string, mixed>> */
    public function listEmployees(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->employeeService->listEmployees($ctx['company_id']);
    }

    /** @return array<string, mixed> */
    public function getEmployee(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->employeeService->getEmployee($ctx['company_id'], $id);
    }

    /** @return array<string, mixed> */
    public function createEmployee(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->employeeService->createEmployee($ctx['company_id'], HttpUtil::parseJson($request));
    }

    /** @return array<string, mixed> */
    public function updateEmployee(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->employeeService->updateEmployee($ctx['company_id'], $id, HttpUtil::parseJson($request));
    }

    /** @return array{ok: true} */
    public function deleteEmployee(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $this->employeeService->deleteEmployee($ctx['company_id'], $id);

        return ['ok' => true];
    }

    // ==========================================
    // NÓMINAS
    // ==========================================

    /** @return list<array<string, mixed>> */
    public function listPayrolls(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->payrollService->listPayrolls($ctx['company_id']);
    }

    /** @return array<string, mixed> */
    public function getPayroll(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->payrollService->getPayroll($ctx['company_id'], $id);
    }

    /** @return array<string, mixed> */
    public function createPayroll(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->payrollService->createPayroll($ctx['company_id'], HttpUtil::parseJson($request));
    }

    /** @return array<string, mixed> */
    public function updatePayroll(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->payrollService->updatePayroll($ctx['company_id'], $id, HttpUtil::parseJson($request));
    }

    /** @return array{ok: true} */
    public function deletePayroll(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $this->payrollService->deletePayroll($ctx['company_id'], $id);

        return ['ok' => true];
    }

    /** @return array<string, mixed> */
    public function postPayroll(ServerRequestInterface $request, string $id): array
    {
        $u = AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->payrollService->postPayrollToAccounting(
            $ctx['company_id'],
            $ctx['branch_id'] ?? null,
            $u['userId'],
            $id,
            HttpUtil::parseJson($request)
        );
    }

    // ==========================================
    // VACACIONES / AUSENCIAS
    // ==========================================

    /** @return list<array<string, mixed>> */
    public function listLeaves(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->leaveService->listLeaves($ctx['company_id']);
    }

    /** @return array<string, mixed> */
    public function getLeave(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->leaveService->getLeave($ctx['company_id'], $id);
    }

    /** @return array<string, mixed> */
    public function createLeave(ServerRequestInterface $request): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->leaveService->createLeave($ctx['company_id'], HttpUtil::parseJson($request));
    }

    /** @return array<string, mixed> */
    public function updateLeave(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);

        return $this->leaveService->updateLeave($ctx['company_id'], $id, HttpUtil::parseJson($request));
    }

    /** @return array{ok: true} */
    public function deleteLeave(ServerRequestInterface $request, string $id): array
    {
        AuthContext::jwtUser($request);
        $ctx = CompanyContext::require($request);
        $this->leaveService->deleteLeave($ctx['company_id'], $id);

        return ['ok' => true];
    }
}
