<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Services\SupportService;

class SupportController extends Controller
{
    private SupportService $support;

    public function __construct()
    {
        $this->support = new SupportService();
    }

    public function index(Request $request): string
    {
        require_auth();
        $user = current_user();

        $filters = [
            'status' => (string) $request->input('status', ''),
            'category' => (string) $request->input('category', ''),
            'search' => (string) $request->input('search', ''),
        ];

        return $this->view(($user['role'] ?? '') === 'admin' ? 'support/admin-index' : 'support/index', [
            'title' => 'Suporte',
            'tickets' => $this->support->ticketsForUser($user, $filters),
            'categories' => $this->support->categories(),
            'statuses' => $this->support->statuses(),
            'filters' => $filters,
        ]);
    }

    public function create(): string
    {
        require_auth();

        return $this->view('support/create', [
            'title' => 'Novo ticket',
            'categories' => $this->support->categories(),
        ]);
    }

    public function store(Request $request): void
    {
        $this->guardAuth($request);
        $result = $this->support->create($request->all(), current_user(), $_FILES['attachment'] ?? []);
        flash($result['ok'] ? 'success' : 'error', $result['ok'] ? 'Ticket criado com sucesso.' : $result['error']);

        if ($result['ok']) {
            app()->response()->redirect('/support/show?id=' . $result['ticket']['id']);
        }

        app()->response()->back();
    }

    public function show(Request $request): string
    {
        require_auth();
        $ticket = $this->support->find((int) $request->input('id'));
        $user = current_user();

        if (!$ticket || !$this->support->canView($ticket, $user)) {
            http_response_code(404);
            return 'Ticket nao encontrado.';
        }

        return $this->view('support/show', [
            'title' => $ticket['ticket_number'] ?? 'Ticket',
            'ticket' => $ticket,
            'categories' => $this->support->categories(),
            'statuses' => $this->support->statuses(),
            'isAdmin' => ($user['role'] ?? '') === 'admin',
        ]);
    }

    public function reply(Request $request): void
    {
        $this->guardAuth($request);
        $result = $this->support->reply((int) $request->post('ticket_id'), current_user(), (string) $request->post('message', ''), $_FILES['attachment'] ?? []);
        flash($result['ok'] ? 'success' : 'error', $result['ok'] ? 'Resposta enviada.' : $result['error']);
        app()->response()->back();
    }

    public function status(Request $request): void
    {
        require_role('admin');

        if (!verify_csrf((string) $request->post('_csrf_token', ''))) {
            flash('error', 'Sessao expirada. Tente novamente.');
            app()->response()->back();
        }

        $result = $this->support->changeStatus((int) $request->post('ticket_id'), (string) $request->post('status'), current_user());
        flash($result['ok'] ? 'success' : 'error', $result['ok'] ? 'Estado actualizado.' : $result['error']);
        app()->response()->back();
    }

    public function attachment(Request $request): void
    {
        require_auth();
        $ticket = $this->support->find((int) $request->input('ticket_id'));
        $index = (int) $request->input('reply', -1);
        $user = current_user();

        if (!$ticket || !$this->support->canView($ticket, $user)) {
            http_response_code(404);
            exit('Anexo nao encontrado.');
        }

        $attachment = $index >= 0 ? ($ticket['replies'][$index]['attachment'] ?? null) : ($ticket['attachment'] ?? null);

        if (!$attachment) {
            http_response_code(404);
            exit('Anexo nao encontrado.');
        }

        $path = $this->support->attachmentPath($attachment);

        if (!is_file($path)) {
            http_response_code(404);
            exit('Ficheiro nao encontrado.');
        }

        header('Content-Type: ' . $attachment['mime_type']);
        header('Content-Disposition: inline; filename="' . basename((string) $attachment['original_name']) . '"');
        header('Content-Length: ' . filesize($path));
        readfile($path);
        exit;
    }

    private function guardAuth(Request $request): void
    {
        require_auth();

        if (!verify_csrf((string) $request->post('_csrf_token', ''))) {
            flash('error', 'Sessao expirada. Tente novamente.');
            app()->response()->back();
        }
    }
}
