<?php

namespace App\Controllers;

use App\Services\CategoryService;

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

        $categories = (new CategoryService())->listForUser($userId);

        return view('categories/index', [
            'title'      => 'Manage Categories',
            'activeNav'  => 'menu',
            'categories' => $categories,
            'name'       => old('name'),
            'errors'     => [],
            'editingId'  => (int) old('editing_id'),
        ]);
    }

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

        $result = (new CategoryService())->create($userId, (string) $this->request->getPost('name'));
        if (! ($result['ok'] ?? false)) {
            return $this->formError($result, null);
        }

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

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

        $result = (new CategoryService())->update($userId, $id, (string) $this->request->getPost('name'));
        if (! ($result['ok'] ?? false)) {
            return $this->formError($result, $id);
        }

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

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

        $result = (new CategoryService())->deleteEmpty($userId, $id);
        if (! ($result['ok'] ?? false)) {
            return redirect()->to('/categories')->with('error', $result['message']);
        }

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

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

        $target = (int) $this->request->getPost('target_category_id');
        $result = (new CategoryService())->moveAndDelete($userId, $id, $target);
        if (! ($result['ok'] ?? false)) {
            return redirect()->to('/categories')->with('error', $result['message']);
        }

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

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

        $result = (new CategoryService())->deleteWithTasks($userId, $id);
        if (! ($result['ok'] ?? false)) {
            return redirect()->to('/categories')->with('error', $result['message']);
        }

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

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

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

    /**
     * @param array{ok?: bool, message?: string, errors?: array<string, string>} $result
     */
    private function formError(array $result, ?int $editingId)
    {
        $userId     = (int) session()->get('user_id');
        $categories = (new CategoryService())->listForUser($userId);

        return view('categories/index', [
            'title'      => 'Manage Categories',
            'activeNav'  => 'menu',
            'categories' => $categories,
            'name'       => (string) $this->request->getPost('name'),
            'errors'     => $result['errors'] ?? ['name' => $result['message'] ?? CategoryService::MSG_FAIL],
            'editingId'  => $editingId,
        ]);
    }
}
