<?php

namespace Modules\Scheduling\Controllers;

use App\Controllers\BaseController;
use App\Models\CompanyModel;
use App\Models\ContractEmployeeModel;
use App\Models\ContractModel;
use Modules\Scheduling\Services\SchedulingService;

class AssignmentController extends BaseController
{
    protected SchedulingService $service;
    protected ContractEmployeeModel $assignments;
    protected CompanyModel $companies;
    protected ContractModel $contracts;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->service     = new SchedulingService();
        $this->assignments = new ContractEmployeeModel();
        $this->companies   = new CompanyModel();
        $this->contracts   = new ContractModel();
    }

    public function index()
    {
        $search     = trim((string) $this->request->getGet('q'));
        $companyId  = (int) ($this->request->getGet('company_id') ?: 0);
        $contractId = (int) ($this->request->getGet('contract_id') ?: 0);
        $employeeId = (int) ($this->request->getGet('employee_id') ?: 0);

        $rows = $this->assignments
            ->scopeForScheduling(
                $search ?: null,
                $companyId ?: null,
                $contractId ?: null,
                $employeeId ?: null
            )
            ->orderBy('companies.name', 'ASC')
            ->orderBy('contracts.number', 'ASC')
            ->orderBy('employees.full_name', 'ASC')
            ->findAll();

        $assignableContracts = $this->contracts
            ->select('contracts.id, contracts.number, contracts.title, contracts.company_id, contracts.status, companies.name AS company_name')
            ->join('companies', 'companies.id = contracts.company_id', 'left')
            ->whereIn('contracts.status', ['active', 'draft'])
            ->orderBy('companies.name', 'ASC')
            ->orderBy('contracts.number', 'ASC')
            ->findAll();

        return view('Modules\Scheduling\Views\assignments\index', array_merge($this->baseViewData(), [
            'title'               => 'Assignments',
            'assignments'         => $rows,
            'companies'           => $this->service->activeCompanies(),
            'assignableContracts' => $assignableContracts,
            'employees'           => $this->service->activeEmployees(),
            'filters'             => [
                'search'      => $search,
                'company_id'  => $companyId,
                'contract_id' => $contractId,
                'employee_id' => $employeeId,
            ],
        ]));
    }

    public function store()
    {
        if (! $this->validate([
            'contract_id'      => 'required|is_natural_no_zero',
            'employee_id'      => 'required|is_natural_no_zero',
            'role_on_contract' => 'permit_empty|max_length[100]',
            'hours_allocated'  => 'permit_empty|decimal',
        ])) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $hours  = $this->request->getPost('hours_allocated');
        $result = $this->service->assignEmployeeToContract(
            (int) $this->request->getPost('contract_id'),
            (int) $this->request->getPost('employee_id'),
            (string) $this->request->getPost('role_on_contract'),
            $hours !== null && $hours !== '' ? (float) $hours : null
        );

        if (! $result['success']) {
            return redirect()->back()->withInput()->with('errors', $result['errors']);
        }

        return redirect()->to('/scheduling/assignments')->with('success', 'Employee assigned to contract.');
    }

    public function remove(int $id)
    {
        $result = $this->service->removeAssignment($id);
        if (! $result['success']) {
            return redirect()->to('/scheduling/assignments')->with('error', $result['errors']['id'] ?? 'Could not remove.');
        }

        return redirect()->to('/scheduling/assignments')->with('success', 'Assignment removed.');
    }
}
