<?php

namespace Modules\Operations\Controllers;

use App\Controllers\BaseController;
use App\Models\EmployeeModel;
use App\Models\OperationsTaskChecklistItemModel;
use App\Models\OperationsTaskModel;
use Modules\Operations\Services\OperationsTaskService;

class OperationsTaskController extends BaseController
{
    protected OperationsTaskModel $tasks;
    protected OperationsTaskChecklistItemModel $checklist;
    protected OperationsTaskService $service;
    protected EmployeeModel $employees;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->tasks     = new OperationsTaskModel();
        $this->checklist = new OperationsTaskChecklistItemModel();
        $this->service   = new OperationsTaskService();
        $this->employees = new EmployeeModel();
    }

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

        $entries = $this->tasks
            ->scopeForList($search ?: null, $status, $priority)
            ->orderBy('operations_tasks.due_date', 'ASC')
            ->orderBy('operations_tasks.id', 'DESC')
            ->paginate(25);

        return view('Modules\Operations\Views\tasks\index', array_merge($this->baseViewData(), [
            'title'   => 'Task Management',
            'entries' => $entries,
            'pager'   => $this->tasks->pager,
            'filters' => compact('search', 'status', 'priority'),
        ]));
    }

    public function createForm()
    {
        return view('Modules\Operations\Views\tasks\create', array_merge($this->baseViewData(), [
            'title'     => 'Create Task',
            'task'      => [],
            'employees' => $this->employees->scopeForList(null, 'active')->orderBy('full_name', 'ASC')->findAll(),
        ]));
    }

    public function store()
    {
        if (! $this->validate([
            'title'                 => 'required|min_length[2]|max_length[200]',
            'priority'              => 'permit_empty|in_list[low,normal,high,urgent]',
            'status'                => 'permit_empty|in_list[open,in_progress]',
            'due_date'              => 'permit_empty|valid_date',
            'assignee_employee_id'  => 'permit_empty|is_natural_no_zero',
        ])) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $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('/operations/tasks/' . $result['id'])
            ->with('success', 'Task created.');
    }

    public function show(int $id)
    {
        $task = $this->tasks->scopeForList()->where('operations_tasks.id', $id)->first();
        if (! $task) {
            return redirect()->to('/operations/tasks')->with('error', 'Task not found.');
        }

        return view('Modules\Operations\Views\tasks\show', array_merge($this->baseViewData(), [
            'title'     => $task['number'],
            'task'      => $task,
            'checklist' => $this->checklist->getForTask($id),
        ]));
    }

    public function editForm(int $id)
    {
        $task = $this->tasks->find($id);
        if (! $task) {
            return redirect()->to('/operations/tasks')->with('error', 'Task not found.');
        }

        if (! in_array($task['status'], OperationsTaskModel::OPEN_STATUSES, true)) {
            return redirect()->to('/operations/tasks/' . $id)
                ->with('error', 'Only open tasks can be edited.');
        }

        return view('Modules\Operations\Views\tasks\edit', array_merge($this->baseViewData(), [
            'title'     => 'Edit Task',
            'task'      => $task,
            'employees' => $this->employees->scopeForList(null, 'active')->orderBy('full_name', 'ASC')->findAll(),
        ]));
    }

    public function update(int $id)
    {
        if (! $this->validate([
            'title'                 => 'required|min_length[2]|max_length[200]',
            'priority'              => 'permit_empty|in_list[low,normal,high,urgent]',
            'status'                => 'permit_empty|in_list[open,in_progress]',
            'due_date'              => 'permit_empty|valid_date',
            'assignee_employee_id'  => 'permit_empty|is_natural_no_zero',
        ])) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $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']);
        }

        return redirect()->to('/operations/tasks/' . $id)->with('success', 'Task updated.');
    }

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

        return redirect()->to('/operations/tasks/' . $id)->with('success', 'Task completed.');
    }

    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/tasks/' . $id)->with('success', 'Task cancelled.');
    }

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

        return redirect()->to('/operations/tasks')->with('success', 'Task deleted.');
    }

    public function checklists()
    {
        $taskId = $this->request->getGet('task_id')
            ? (int) $this->request->getGet('task_id')
            : null;

        $task = $taskId ? $this->tasks->find($taskId) : null;
        if ($taskId && ! $task) {
            return redirect()->to('/operations/tasks/checklists')
                ->with('error', 'Task not found.');
        }

        return view('Modules\Operations\Views\tasks\checklists', array_merge($this->baseViewData(), [
            'title'    => 'Checklists',
            'openTasks'=> $this->tasks->getOpenForChecklist(),
            'task'     => $task,
            'items'    => $task ? $this->checklist->getForTask((int) $task['id']) : [],
            'taskId'   => $taskId,
        ]));
    }

    public function storeChecklistItem()
    {
        if (! $this->validate([
            'task_id' => 'required|is_natural_no_zero',
            'title'   => 'required|min_length[1]|max_length[255]',
        ])) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

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

        return redirect()->to('/operations/tasks/checklists?task_id=' . $taskId)
            ->with('success', 'Checklist item added.');
    }

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

        $redirect = $item
            ? '/operations/tasks/checklists?task_id=' . (int) $item['task_id']
            : '/operations/tasks/checklists';

        return redirect()->to($redirect)->with('success', 'Checklist item updated.');
    }

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

        $redirect = $item
            ? '/operations/tasks/checklists?task_id=' . (int) $item['task_id']
            : '/operations/tasks/checklists';

        return redirect()->to($redirect)->with('success', 'Checklist item removed.');
    }

    public function priorities()
    {
        $search = trim((string) $this->request->getGet('q'));
        $entries = $this->tasks->getByPriorityView($search ?: null);

        return view('Modules\Operations\Views\tasks\priorities', array_merge($this->baseViewData(), [
            'title'   => 'Priorities',
            'entries' => $entries,
            'filters' => ['search' => $search],
        ]));
    }

    public function deadlines()
    {
        $search = trim((string) $this->request->getGet('q'));
        $entries = $this->tasks->getDeadlinesView($search ?: null);
        $today = date('Y-m-d');

        return view('Modules\Operations\Views\tasks\deadlines', array_merge($this->baseViewData(), [
            'title'   => 'Deadlines',
            'entries' => $entries,
            'today'   => $today,
            'filters' => ['search' => $search],
        ]));
    }
}
