<?php

namespace App\Controllers;

use App\Services\DashboardService;
use App\Services\NotificationService;
use CodeIgniter\Exceptions\PageNotFoundException;

class NotificationController extends BaseController
{
    public function index()
    {
        $userId = $this->userId();
        if ($userId === null) {
            return redirect()->to('/sign-in');
        }

        $notifications = new NotificationService();

        return view('notifications/index', [
            'title'         => 'Notifications',
            'activeNav'     => 'menu',
            'items'         => $notifications->listForUser($userId),
            'unreadCount'   => $notifications->unreadCount($userId),
            'emptyMessage'  => NotificationService::MSG_EMPTY,
        ]);
    }

    public function markRead(int $id)
    {
        $userId = $this->userId();
        if ($userId === null) {
            return redirect()->to('/sign-in');
        }

        $result = (new NotificationService())->markRead($userId, $id);
        if (! ($result['ok'] ?? false)) {
            return $this->notFound($result['message'] ?? NotificationService::MSG_NOT_FOUND);
        }

        if ($this->request->isAJAX()) {
            return $this->response->setJSON([
                'ok'      => true,
                'message' => $result['message'],
            ]);
        }

        return redirect()->to('/notifications')->with('success', $result['message']);
    }

    public function markAllRead()
    {
        $userId = $this->userId();
        if ($userId === null) {
            return redirect()->to('/sign-in');
        }

        (new NotificationService())->markAllRead($userId);

        if ($this->request->isAJAX()) {
            return $this->response->setJSON([
                'ok'      => true,
                'message' => NotificationService::MSG_ALL_READ,
            ]);
        }

        return redirect()->to('/notifications')->with('success', NotificationService::MSG_ALL_READ);
    }

    public function open(int $id)
    {
        $userId = $this->userId();
        if ($userId === null) {
            return redirect()->to('/sign-in');
        }

        $result = (new NotificationService())->open($userId, $id);
        if (! ($result['ok'] ?? false)) {
            return $this->notFound($result['message'] ?? NotificationService::MSG_NOT_FOUND);
        }

        session()->set(DashboardService::RETURN_KEY, 'notifications');

        $redirect = (string) ($result['redirect'] ?? '/notifications');
        if (preg_match('#^/tasks/[1-9][0-9]*/edit$#', $redirect) === 1) {
            return redirect()->to($redirect);
        }

        if (isset($result['flash'])) {
            return redirect()->to('/notifications')->with('error', (string) $result['flash']);
        }

        return redirect()->to('/notifications');
    }

    private function userId(): ?int
    {
        $id = (int) session()->get('user_id');

        return $id > 0 ? $id : null;
    }

    private function notFound(string $message)
    {
        if ($this->request->isAJAX()) {
            return $this->response->setStatusCode(404)->setJSON([
                'ok'    => false,
                'error' => $message,
            ]);
        }

        throw PageNotFoundException::forPageNotFound();
    }
}
