<?php

namespace Modules\Contracts\Controllers;

use App\Controllers\BaseController;
use App\Models\CompanyModel;
use App\Models\ContractEmployeeModel;
use App\Models\ContractLineModel;
use App\Models\ContractMilestoneModel;
use App\Models\ContractModel;
use App\Models\EmployeeModel;
use Modules\Contracts\Services\ContractService;

class ContractController extends BaseController
{
    protected ContractModel $contracts;
    protected CompanyModel $companies;
    protected EmployeeModel $employees;
    protected ContractLineModel $lines;
    protected ContractMilestoneModel $milestones;
    protected ContractEmployeeModel $assignments;
    protected ContractService $service;

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

    public function index()
    {
        $search    = trim((string) $this->request->getGet('q'));
        $status    = $this->request->getGet('status') ?: null;
        $type      = $this->request->getGet('contract_type') ?: null;
        $companyId = $this->request->getGet('company_id') ?: null;

        $rows = $this->contracts
            ->scopeForList(
                $search ?: null,
                $status,
                $type,
                $companyId ? (int) $companyId : null
            )
            ->orderBy('contracts.id', 'DESC')
            ->paginate(20);

        return view('Modules\Contracts\Views\contracts\index', array_merge($this->baseViewData(), [
            'title'     => 'Contracts',
            'contracts' => $rows,
            'pager'     => $this->contracts->pager,
            'companies' => $this->companies->getActive(trim((string) $this->request->getGet('company_q')) ?: null, 200),
            'filters'   => compact('search', 'status', 'type', 'companyId'),
        ]));
    }

    public function createForm()
    {
        $preselectCompanyId = (int) ($this->request->getGet('company_id') ?? 0);
        $company = $preselectCompanyId ? $this->companies->find($preselectCompanyId) : null;

        $companySearch  = trim((string) $this->request->getGet('company_q'));
        $employeeSearch = trim((string) $this->request->getGet('employee_q'));

        return view('Modules\Contracts\Views\contracts\create', array_merge($this->baseViewData(), [
            'title'             => 'New Contract',
            'companies'         => $this->companies->scopeForList($companySearch !== '' ? $companySearch : null, 'active')
                ->whereIn('customer_type', ['product', 'service', 'project'])
                ->orderBy('name', 'ASC')
                ->limit(200)
                ->findAll(),
            'employees'         => $employeeSearch !== '' ? $this->employees->searchActive($employeeSearch, 50) : [],
            'employeeSearch'    => $employeeSearch,
            'preselectCompanyId'=> $preselectCompanyId,
            'preselectType'     => $company['customer_type'] ?? '',
            'contract'          => [],
            'lines'             => [],
            'milestones'        => [],
            'assignments'       => [],
        ]));
    }

    public function store()
    {
        $result = $this->service->create($this->request->getPost(), (int) $this->session->get('user_id'));
        if (! $result['success']) {
            return redirect()->back()->withInput()->with('errors', $result['errors']);
        }

        return redirect()->to('/contracts/contracts/' . $result['id'])->with('success', 'Contract created.');
    }

    public function show(int $id)
    {
        $contract = $this->contracts->find($id);
        if (! $contract) {
        return redirect()->to('/contracts/active')->with('error', 'Contract not found.');
    }

    $company = $this->companies->find($contract['company_id']);

    return view('Modules\Contracts\Views\contracts\show', array_merge($this->baseViewData(), [
        'title'       => $contract['number'],
        'contract'    => $contract,
        'company'     => $company,
        'lines'       => $this->lines->getForContract($id),
        'milestones'  => $this->milestones->getForContract($id),
        'assignments' => $this->assignments->getForContract($id),
    ]));
}

public function editForm(int $id)
{
    $contract = $this->contracts->find($id);
    if (! $contract) {
        return redirect()->to('/contracts/active')->with('error', 'Contract not found.');
    }

    $assignments = $this->assignments->getForContract($id);
    $assignedIds = array_map(static fn (array $row): int => (int) $row['employee_id'], $assignments);
    $employeeSearch = trim((string) $this->request->getGet('employee_q'));
    $employees = $this->employees->getByIds($assignedIds);
    if ($employeeSearch !== '') {
        $found = $this->employees->searchActive($employeeSearch, 50);
        $known = array_flip($assignedIds);
        foreach ($found as $row) {
            if (! isset($known[(int) $row['id']])) {
                $employees[] = $row;
            }
        }
    }

    return view('Modules\Contracts\Views\contracts\edit', array_merge($this->baseViewData(), [
        'title'          => 'Edit Contract',
        'contract'       => $contract,
        'companies'      => $this->companies->scopeForList(trim((string) $this->request->getGet('company_q')) ?: null, 'active')
            ->whereIn('customer_type', ['product', 'service', 'project'])
            ->orderBy('name', 'ASC')
            ->limit(200)
            ->findAll(),
        'employees'      => $employees,
        'employeeSearch' => $employeeSearch,
        'lines'          => $this->lines->getForContract($id),
        'milestones'     => $this->milestones->getForContract($id),
        'assignments'    => $assignments,
    ]));
}

public function update(int $id)
{
    $result = $this->service->update($id, $this->request->getPost(), (int) $this->session->get('user_id'));
    if (! $result['success']) {
        return redirect()->back()->withInput()->with('errors', $result['errors'] ?? ['error' => $result['error'] ?? 'Update failed.']);
    }

    return redirect()->to('/contracts/contracts/' . $id)->with('success', 'Contract updated.');
}

public function destroy(int $id)
{
    $result = $this->service->delete($id, (int) $this->session->get('user_id'));
    if (! $result['success']) {
        return redirect()->to('/contracts/active')->with('error', $result['error']);
    }

    return redirect()->to('/contracts/active')->with('success', 'Contract deleted.');
}
}
