<?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 StaffSchedulingController extends BaseController
{
    protected SchedulingService $service;
    protected CompanyModel $companies;
    protected ContractModel $contracts;
    protected ContractEmployeeModel $assignments;

    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->companies   = new CompanyModel();
        $this->contracts   = new ContractModel();
        $this->assignments = new ContractEmployeeModel();
    }

    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);

        $companies = $this->service->activeCompanies($search ?: null);
        $contracts = [];
        $contract  = null;
        $staff     = [];

        if ($companyId > 0) {
            $company = $this->companies->find($companyId);
            if ($company) {
                $contracts = $this->service->contractsForCompany($companyId);
            } else {
                $companyId = 0;
            }
        }

        if ($contractId > 0) {
            $contract = $this->contracts->find($contractId);
            if (! $contract || ($companyId > 0 && (int) $contract['company_id'] !== $companyId)) {
                $contract   = null;
                $contractId = 0;
            } else {
                if ($companyId === 0) {
                    $companyId = (int) $contract['company_id'];
                    $contracts = $this->service->contractsForCompany($companyId);
                }
                $staff = $this->assignments->getForContract($contractId);
            }
        }

        return view('Modules\Scheduling\Views\staff\index', array_merge($this->baseViewData(), [
            'title'      => 'Staff Scheduling',
            'companies'  => $companies,
            'contracts'  => $contracts,
            'contract'   => $contract,
            'staff'      => $staff,
            'employees'  => $this->service->activeEmployees(),
            'filters'    => [
                'search'      => $search,
                'company_id'  => $companyId,
                'contract_id' => $contractId,
            ],
        ]));
    }

    public function assign()
    {
        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']);
        }

        $contractId = (int) $this->request->getPost('contract_id');
        $contract   = $this->contracts->find($contractId);
        $companyId  = (int) ($contract['company_id'] ?? 0);

        return redirect()->to('/scheduling/staff?company_id=' . $companyId . '&contract_id=' . $contractId)
            ->with('success', 'Employee scheduled to contract.');
    }

    public function remove(int $id)
    {
        $row = $this->assignments->find($id);
        $result = $this->service->removeAssignment($id);

        if (! $result['success']) {
            return redirect()->to('/scheduling/staff')->with('error', $result['errors']['id'] ?? 'Could not remove assignment.');
        }

        $contractId = (int) ($row['contract_id'] ?? 0);
        $contract   = $contractId ? $this->contracts->find($contractId) : null;
        $companyId  = (int) ($contract['company_id'] ?? 0);

        return redirect()->to('/scheduling/staff?company_id=' . $companyId . '&contract_id=' . $contractId)
            ->with('success', 'Employee removed from contract.');
    }
}
