<?php

namespace Modules\Operations\Controllers;

use App\Controllers\BaseController;
use App\Models\OperationsApprovalRequestModel;
use Modules\Operations\Services\OperationsApprovalRequestService;

class OperationsApprovalRequestController extends BaseController
{
    protected OperationsApprovalRequestModel $requests;
    protected OperationsApprovalRequestService $service;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->requests = new OperationsApprovalRequestModel();
        $this->service  = new OperationsApprovalRequestService();
    }

    public function createForm()
    {
        $userId = (int) $this->session->get('user_id');

        return view('Modules\Operations\Views\approvals\request_create', array_merge($this->baseViewData(), [
            'title'     => 'New Approval Request',
            'approvers' => $this->service->activeApproverOptions($userId),
            'types'     => OperationsApprovalRequestModel::TYPES,
        ]));
    }

    public function store()
    {
        if (! $this->validate([
            'title'            => 'required|min_length[2]|max_length[200]',
            'request_type'     => 'required|in_list[expense,work,purchase,leave,general]',
            'approver_user_id' => 'required|is_natural_no_zero',
            'amount'           => 'permit_empty|decimal',
            'description'      => 'permit_empty|max_length[5000]',
        ])) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

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

        return redirect()->to('/operations/approvals/my-requests')
            ->with('success', 'Request sent to the selected approver.');
    }

    public function myRequests()
    {
        $userId = (int) $this->session->get('user_id');
        $search = trim((string) $this->request->getGet('q'));
        $status = $this->request->getGet('status') ?: null;

        return view('Modules\Operations\Views\approvals\my_requests', array_merge($this->baseViewData(), [
            'title'   => 'My Requests',
            'entries' => $this->requests->forRequester($userId, $search ?: null, $status),
            'filters' => compact('search', 'status'),
        ]));
    }

    public function inbox()
    {
        $userId = (int) $this->session->get('user_id');
        $search = trim((string) $this->request->getGet('q'));

        return view('Modules\Operations\Views\approvals\inbox', array_merge($this->baseViewData(), [
            'title'   => 'Requests for Me',
            'entries' => $this->requests->pendingForApprover($userId, $search ?: null),
            'filters' => ['search' => $search],
        ]));
    }

    public function show(int $id)
    {
        $entry = $this->requests->scopeForList()->where('operations_approval_requests.id', $id)->first();
        if (! $entry) {
            return redirect()->to('/operations/approvals/my-requests')->with('error', 'Request not found.');
        }

        $userId = (int) $this->session->get('user_id');
        $isRequester = (int) $entry['requester_user_id'] === $userId;
        $isApprover  = (int) $entry['approver_user_id'] === $userId;

        if (! $isRequester && ! $isApprover && ! $this->isAdministrator()) {
            return redirect()->to('/operations/approvals/my-requests')
                ->with('error', 'You do not have access to this request.');
        }

        return view('Modules\Operations\Views\approvals\request_show', array_merge($this->baseViewData(), [
            'title'       => $entry['number'],
            'entry'       => $entry,
            'isRequester' => $isRequester,
            'isApprover'  => $isApprover,
        ]));
    }

    public function approve(int $id)
    {
        $result = $this->service->approve($id, (int) $this->session->get('user_id'));
        if (! $result['success']) {
            return redirect()->back()->with('error', $result['error']);
        }

        return redirect()->to('/operations/approvals/inbox')->with('success', 'Request approved.');
    }

    public function reject(int $id)
    {
        $result = $this->service->reject(
            $id,
            (string) $this->request->getPost('rejection_reason'),
            (int) $this->session->get('user_id')
        );
        if (! $result['success']) {
            return redirect()->back()->with('error', $result['error']);
        }

        return redirect()->to('/operations/approvals/inbox')->with('success', 'Request rejected.');
    }

    public function cancel(int $id)
    {
        $result = $this->service->cancel($id, (int) $this->session->get('user_id'));
        if (! $result['success']) {
            return redirect()->back()->with('error', $result['error']);
        }

        return redirect()->to('/operations/approvals/my-requests')->with('success', 'Request cancelled.');
    }
}
