<?php

namespace Leantime\Domain\Tickets\Controllers;

use Carbon\Carbon;
use Illuminate\Contracts\Container\BindingResolutionException;
use Leantime\Core\Controller\Controller;
use Leantime\Core\Controller\Frontcontroller;
use Leantime\Core\Support\FromFormat;
use Leantime\Domain\Comments\Services\Comments as CommentService;
use Leantime\Domain\Files\Services\Files as FileService;
use Leantime\Domain\Projects\Services\Projects as ProjectService;
use Leantime\Domain\Sprints\Services\Sprints as SprintService;
use Leantime\Domain\Tickets\Services\Tickets as TicketService;
use Leantime\Domain\Timesheets\Services\Timesheets as TimesheetService;
use Leantime\Domain\Users\Services\Users as UserService;
use Symfony\Component\HttpFoundation\Response;

class ShowTicket extends Controller
{
    private ProjectService $projectService;

    private TicketService $ticketService;

    private SprintService $sprintService;

    private FileService $fileService;

    private CommentService $commentService;

    private TimesheetService $timesheetService;

    private UserService $userService;

    public function init(
        ProjectService $projectService,
        TicketService $ticketService,
        SprintService $sprintService,
        FileService $fileService,
        CommentService $commentService,
        TimesheetService $timesheetService,
        UserService $userService
    ): void {
        $this->projectService = $projectService;
        $this->ticketService = $ticketService;
        $this->sprintService = $sprintService;
        $this->fileService = $fileService;
        $this->commentService = $commentService;
        $this->timesheetService = $timesheetService;
        $this->userService = $userService;

        if (session()->exists('lastPage') === false) {
            session(['lastPage' => BASE_URL.'/tickets/showKanban']);
        }
    }

    /**
     * @throws BindingResolutionException
     */
    public function get($params): Response
    {
        if (! isset($params['id'])) {
            return $this->tpl->displayPartial('errors.error400', responseCode: 400);
        }

        $id = (int) ($params['id']);
        $ticket = $this->ticketService->getTicket($id);

        if ($ticket === false) {
            return $this->tpl->display('errors.error500', responseCode: 500);
        }

        // Ensure this ticket belongs to the current project
        if (session('currentProject') != $ticket->projectId) {
            $this->projectService->changeCurrentSessionProject($ticket->projectId);

            return Frontcontroller::redirect(BASE_URL.'/tickets/showTicket/'.$id);
        }

        // Delete file
        if (isset($params['delFile']) === true) {
            if ($result = $this->fileService->deleteFile($params['delFile'])) {
                $this->tpl->setNotification($this->language->__('notifications.file_deleted'), 'success');

                return Frontcontroller::redirect(BASE_URL.'/tickets/showTicket/'.$id.'#files');
            }

            $this->tpl->setNotification($result['msg'], 'error');
        }

        // Delete comment
        if (isset($params['delComment']) === true) {
            $commentId = (int) ($params['delComment']);

            if ($this->commentService->deleteComment($commentId)) {
                $this->tpl->setNotification($this->language->__('notifications.comment_deleted'), 'success');
                $response = Frontcontroller::redirect(BASE_URL.'/tickets/showTicket/'.$id);
                $response->headers->set('HX-Trigger', 'ticketUpdate');

                return $response;
            }

            $this->tpl->setNotification($this->language->__('notifications.comment_deleted_error'), 'error');
        }
        // Delete Subtask
        if (isset($params['delSubtask']) === true) {

        }

        $this->tpl->assign('ticket', $ticket);
        $this->tpl->assign('ticketParents', $this->ticketService->getAllPossibleParents($ticket));
        $this->tpl->assign('statusLabels', $this->ticketService->getStatusLabels());
        $this->tpl->assign('ticketTypes', $this->ticketService->getTicketTypes());
        $this->tpl->assign('ticketTypeIcons', $this->ticketService->getTypeIcons());
        $this->tpl->assign('efforts', $this->ticketService->getEffortLabels());
        $this->tpl->assign('priorities', $this->ticketService->getPriorityLabels());

        $allProjectMilestones = $this->ticketService->getAllMilestones([
            'sprint' => '',
            'type' => 'milestone',
            'currentProject' => session('currentProject'),
        ]);
        $this->tpl->assign('milestones', $allProjectMilestones);
        $this->tpl->assign('sprints', $this->sprintService->getAllSprints(session('currentProject')));

        $this->tpl->assign('kind', $this->timesheetService->getLoggableHourTypes());
        $this->tpl->assign('ticketHours', $this->timesheetService->getLoggedHoursForTicketByDate($id));
        $this->tpl->assign('userHours', $this->timesheetService->getUsersTicketHours($id, session('userdata.id')));

        $this->tpl->assign('timesheetsAllHours', $this->timesheetService->getSumLoggedHoursForTicket($id));
        $this->tpl->assign('remainingHours', $this->timesheetService->getRemainingHours($ticket));

        $this->tpl->assign('userInfo', $this->userService->getUser(session('userdata.id')));
        $this->tpl->assign('users', $this->projectService->getUsersAssignedToProject($ticket->projectId));

        $projectData = $this->projectService->getProject($ticket->projectId);
        $this->tpl->assign('projectData', $projectData);

        $comments = $this->commentService->getComments('ticket', $id);

        $this->tpl->assign('numComments', count($comments));
        $this->tpl->assign('comments', $comments);

        $files = $this->fileService->getFilesByModule('ticket', $id);
        $this->tpl->assign('numFiles', count($files));
        $this->tpl->assign('files', $files);

        $this->tpl->assign('onTheClock', $this->timesheetService->isClocked(session('userdata.id')));

        $this->tpl->assign('timesheetValues', [
            'kind' => '',
            'date' => Carbon::now(session('usersettings.timezone'))->setTimezone('UTC'),
            'hours' => '',
            'description' => '',
        ]);

        // TODO: Refactor thumbnail generation in file manager
        $this->tpl->assign('imgExtensions', ['jpg', 'jpeg', 'png', 'gif', 'psd', 'bmp', 'tif', 'thm', 'yuv']);

        $allAssignedprojects = $this->projectService->getProjectsUserHasAccessTo(session('userdata.id'), 'open');
        $this->tpl->assign('allAssignedprojects', $allAssignedprojects);

        $response = $this->tpl->displayPartial('tickets.showTicketModal');
        $response->headers->set('HX-Trigger', 'ticketUpdate');

        return $response;
    }

    /**
     * @throws BindingResolutionException
     */
    public function post($params): Response
    {
        if (! isset($_GET['id'])) {
            return $this->tpl->display('errors.error400', responseCode: 400);
        }

        $tab = '';
        $id = (int) ($_GET['id']);
        $ticket = $this->ticketService->getTicket($id);

        if ($ticket === false) {
            return $this->tpl->display('errors.error500', responseCode: 500);
        }

        // Upload File
        if (isset($params['upload'])) {
            if ($this->fileService->upload($_FILES, 'ticket', $id, $ticket)) {
                $this->tpl->setNotification($this->language->__('notifications.file_upload_success'), 'success');
            } else {
                $this->tpl->setNotification($this->language->__('notifications.file_upload_error'), 'error');
            }

            $tab = '#files';
        }

        // Add or edit a comment
        if (isset($params['comment']) === true && isset($params['text']) && $params['text'] != '' && isset($params['edit-comment-helper']) && $params['edit-comment-helper'] !== '') {
            if ($this->commentService->editComment($_POST, (int) $params['edit-comment-helper'])) {
                $this->tpl->setNotification($this->language->__('notifications.comment_edited_success'), 'success');
            } else {
                $this->tpl->setNotification($this->language->__('notifications.comment_edit_error'), 'error');
            }
            $tab = '#comment';
        } elseif (isset($params['comment']) === true && isset($params['text']) && $params['text'] != '') {
            if ($this->commentService->addComment($_POST, 'ticket', $id, $ticket)) {
                $this->tpl->setNotification($this->language->__('notifications.comment_create_success'), 'success');
            } else {
                $this->tpl->setNotification($this->language->__('notifications.comment_create_error'), 'error');
            }

            $tab = '#comment';
        }

        // Log time
        if (isset($params['saveTimes']) === true) {

            try {
                $result = $this->timesheetService->logTime($id, $params);
                $this->tpl->setNotification($this->language->__('notifications.time_logged_success'), 'success');
            } catch (\Exception $e) {
                $this->tpl->setNotification($e->getMessage(), 'error');
            }

        }

        // Save Ticket
        if (isset($params['saveTicket']) === true || isset($params['saveAndCloseTicket']) === true) {
            //            $params['projectId'] = $ticket->projectId;
            $params['id'] = $id;

            // Prepare values, time comes in as 24hours from time input. Service expects time to be in local user format
            $params['timeToFinish'] = format(value: $params['timeToFinish'] ?? '', fromFormat: FromFormat::User24hTime)->userTime24toUserTime();
            $params['timeFrom'] = format(value: $params['timeFrom'] ?? '', fromFormat: FromFormat::User24hTime)->userTime24toUserTime();
            $params['timeTo'] = format(value: $params['timeTo'] ?? '', fromFormat: FromFormat::User24hTime)->userTime24toUserTime();

            $result = $this->ticketService->updateTicket($params);

            if ($result === true) {
                $this->tpl->setNotification($this->language->__('notifications.ticket_saved'), 'success');
            } else {
                $this->tpl->setNotification($this->language->__($result['msg']), 'error');
            }

            if (isset($params['saveAndCloseTicket']) === true && $params['saveAndCloseTicket'] == 1) {
                $response = Frontcontroller::redirect(BASE_URL.'/tickets/showTicket/'.$id.'?closeModal=1');
                $response->headers->set('HX-Trigger', 'ticketUpdate');

                return $response;
            }
        }

        $response = Frontcontroller::redirect(BASE_URL.'/tickets/showTicket/'.$id.''.$tab);
        $response->headers->set('HX-Trigger', 'ticketUpdate');

        return $response;
    }
}
