<?php

declare(strict_types=1);

namespace Ekdos\Relay;

use Ekdos\N8n\CachePolicy;
use Ekdos\Support\Json;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

final readonly class InternalTasksController extends RelayController
{
    private const array RECIPIENTS = ['sascha', 'svenja'];

    private const array CATEGORIES = [
        'angebote',
        'steuerberater',
        'kundenruecksprache',
        'interne_bueroaufgaben',
        'heute_erledigen',
    ];

    public function index(Request $request, Response $response): Response
    {
        $reply = $this->cachedGet(CachePolicy::Tasks, $this->n8nUrl->internalTasks());

        if (!$reply->ok()) {
            return $this->upstreamError($response, $reply, 'Interne Aufgaben konnten nicht geladen werden.');
        }

        return $this->listResponse($response, $reply, 'tasks', 'tasks');
    }

    public function create(Request $request, Response $response): Response
    {
        $body = $this->body($request);
        $fields = self::validate($body);

        if (is_string($fields)) {
            return Json::error($response, $fields, 400);
        }

        $fields['erstellt_von'] = $this->session($request)->displayName;
        $reply = $this->n8n->post($this->n8nUrl->internalTasks(), $fields);

        if (!$reply->ok()) {
            return $this->upstreamError($response, $reply, 'Aufgabe konnte nicht gespeichert werden.');
        }

        $this->cache->invalidate(CachePolicy::Tasks[0]);

        return Json::passthrough($response, $reply->body, 201);
    }

    public function complete(Request $request, Response $response): Response
    {
        $id = self::text($this->body($request), 'id');

        if ($id === '') {
            return Json::error($response, 'Die Aufgabe fehlt.', 400);
        }

        $reply = $this->n8n->post($this->n8nUrl->internalTasks('/erledigt'), [
            'id' => $id,
            'erledigt_von' => $this->session($request)->displayName,
        ]);

        if (!$reply->ok()) {
            return $this->upstreamError($response, $reply, 'Aufgabe konnte nicht abgeschlossen werden.');
        }

        $this->cache->invalidate(CachePolicy::Tasks[0]);

        return Json::passthrough($response, $reply->body);
    }

    public function edit(Request $request, Response $response): Response
    {
        $body = $this->body($request);
        $id = self::text($body, 'id');
        $fields = self::validate($body);

        if ($id === '') {
            return Json::error($response, 'Die Aufgabe fehlt.', 400);
        }

        if (is_string($fields)) {
            return Json::error($response, 'Bitte Aufgabe, Empfänger und Kategorie vollständig angeben.', 400);
        }

        $reply = $this->n8n->post($this->n8nUrl->internalTasks('/bearbeiten'), ['id' => $id] + $fields);

        if (!$reply->ok()) {
            return $this->upstreamError($response, $reply, 'Aufgabe konnte nicht bearbeitet werden.');
        }

        $this->cache->invalidate(CachePolicy::Tasks[0]);

        return Json::passthrough($response, $reply->body);
    }

    /** Vormals: nur Sascha. */
    public function delete(Request $request, Response $response): Response
    {
        $id = self::text($this->body($request), 'id');

        if ($id === '') {
            return Json::error($response, 'Die Aufgabe fehlt.', 400);
        }

        $reply = $this->n8n->post($this->n8nUrl->internalTasks('/loeschen'), ['id' => $id]);

        if (!$reply->ok()) {
            return $this->upstreamError($response, $reply, 'Aufgabe konnte nicht gelöscht werden.');
        }

        $this->cache->invalidate(CachePolicy::Tasks[0]);

        return Json::passthrough($response, $reply->body);
    }

    /**
     * @return array<string, string>|string Felder oder die Fehlermeldung.
     */
    private static function validate(array $body): array|string
    {
        $task = self::text($body, 'aufgabe');
        $recipient = self::text($body, 'empfaenger');
        $category = self::text($body, 'kategorie');

        if ($task === '') {
            return 'Bitte Aufgabe eingeben.';
        }

        if (!in_array($recipient, self::RECIPIENTS, true) || !in_array($category, self::CATEGORIES, true)) {
            return 'Bitte Empfänger und Kategorie auswählen.';
        }

        return [
            'aufgabe' => $task,
            'empfaenger' => $recipient,
            'kategorie' => $category,
            'kunden_id' => self::text($body, 'kunden_id'),
        ];
    }
}
