<?php

declare(strict_types=1);

class ApiOcorrenciaController extends Controller
{
    public function store(): void
    {
        ApiAuth::requireToken();

        $payload = Request::json();

        foreach (['categoria_id', 'descricao', 'latitude', 'longitude'] as $field) {
            if (!isset($payload[$field]) || $payload[$field] === '' || $payload[$field] === null) {
                ApiResponse::error('Campo obrigatório: ' . $field, [], 422);
            }
        }

        $db = Database::getConnection();
        $protocolo = gerarProtocolo($db);

        $dados = [
            'protocolo' => $protocolo,
            'categoria_id' => (int)$payload['categoria_id'],
            'descricao' => trim((string)$payload['descricao']),
            'latitude' => (string)$payload['latitude'],
            'longitude' => (string)$payload['longitude'],
            'endereco_referencia' => trim((string)($payload['endereco_referencia'] ?? '')),
            'cidadao_nome' => trim((string)($payload['cidadao_nome'] ?? '')),
            'cidadao_telefone' => trim((string)($payload['cidadao_telefone'] ?? '')),
            'cidadao_email' => trim((string)($payload['cidadao_email'] ?? '')),
            'anonima' => (int)($payload['anonima'] ?? 0),
            'imagem' => null,
        ];

        $model = new Ocorrencia();
        $id = $model->criar($dados);

        ApiResponse::success([
            'id' => $id,
            'protocolo' => $protocolo,
            'status' => 'ABERTA'
        ], 'Ocorrência registrada com sucesso.', 201);
    }

    public function showByProtocol(): void
    {
        ApiAuth::requireToken();

        $protocolo = trim((string)($_GET['protocolo'] ?? ''));
        if ($protocolo === '') {
            ApiResponse::error('Protocolo não informado.', [], 422);
        }

        $model = new Ocorrencia();
        $item = $model->buscarPorProtocolo($protocolo);

        if (!$item) {
            ApiResponse::error('Ocorrência não encontrada.', [], 404);
        }

        ApiResponse::success($this->serializeOcorrencia($item), 'Ocorrência localizada.');
    }

    public function listByPhone(): void
    {
        ApiAuth::requireToken();

        $telefone = trim((string)($_GET['telefone'] ?? ''));
        if ($telefone === '') {
            ApiResponse::error('Telefone não informado.', [], 422);
        }

        $model = new Ocorrencia();
        $items = $model->listarPorTelefone($telefone);

        ApiResponse::success($items, 'Ocorrências localizadas.');
    }

    public function uploadImage(): void
    {
        ApiAuth::requireToken();

        $protocolo = trim((string)($_POST['protocolo'] ?? ''));
        if ($protocolo === '') {
            ApiResponse::error('Protocolo não informado.', [], 422);
        }

        if (empty($_FILES['imagem']['name'])) {
            ApiResponse::error('Imagem não enviada.', [], 422);
        }

        try {
            $nome = uploadImagem($_FILES['imagem']);

            $model = new Ocorrencia();
            $ok = $model->definirImagemPorProtocolo($protocolo, (string)$nome);

            if (!$ok) {
                ApiResponse::error('Ocorrência não encontrada para o protocolo informado.', [], 404);
            }

            ApiResponse::success([
                'protocolo' => $protocolo,
                'imagem' => $nome
            ], 'Imagem anexada com sucesso.');
        } catch (Throwable $e) {
            ApiResponse::error($e->getMessage(), [], 422);
        }
    }

    public function updateStatus(): void
    {
        ApiAuth::requireToken();

        $payload = Request::json();
        $protocolo = trim((string)($payload['protocolo'] ?? ''));
        $status = trim((string)($payload['status'] ?? ''));
        $observacao = trim((string)($payload['observacao'] ?? 'Atualização via API.'));

        if ($protocolo === '' || $status === '') {
            ApiResponse::error('Protocolo e status são obrigatórios.', [], 422);
        }

        $permitidos = ['RECEBIDA', 'EM_ANALISE', 'ENCAMINHADA', 'EM_ATENDIMENTO', 'CONCLUIDA', 'NAO_PROCEDE', 'DUPLICADA'];

        if (!in_array($status, $permitidos, true)) {
            ApiResponse::error('Status inválido.', [], 422);
        }

        $model = new Ocorrencia();
        $item = $model->buscarPorProtocolo($protocolo);

        if (!$item) {
            ApiResponse::error('Ocorrência não encontrada.', [], 404);
        }

        $model->atualizarStatusComObservacao((int)$item['id'], $status, null, $observacao);

        $atualizada = $model->buscarPorProtocolo($protocolo);
        ApiResponse::success($this->serializeOcorrencia($atualizada), 'Status atualizado com sucesso.');
    }

    private function serializeOcorrencia(array $item): array
    {
        return [
            'id' => (int)$item['id'],
            'protocolo' => $item['protocolo'],
            'categoria' => $item['categoria_nome'] ?? null,
            'status' => $item['status'],
            'descricao' => $item['descricao'],
            'latitude' => $item['latitude'],
            'longitude' => $item['longitude'],
            'endereco_referencia' => $item['endereco_referencia'] ?? null,
            'cidadao_nome' => $item['cidadao_nome'] ?? null,
            'cidadao_telefone' => $item['cidadao_telefone'] ?? null,
            'cidadao_email' => $item['cidadao_email'] ?? null,
            'imagem' => $item['imagem'] ?? null,
            'criado_em' => $item['criado_em'] ?? null,
            'concluido_em' => $item['concluido_em'] ?? null
        ];
    }
}
