<?php

declare(strict_types=1);

require_once __DIR__ . '/../models/Ocorrencia.php';
require_once __DIR__ . '/../models/Categoria.php';
require_once __DIR__ . '/../models/Setor.php';

class OcorrenciaController extends Controller
{
    public function home(): void
    {
        $this->view('public/home', [], 'public');
    }

    public function appHome(): void
    {
        $categoriaModel = new Categoria();
        $categorias = $categoriaModel->ativas();

        $appMode = true;
        $this->view('public/app_home', compact('appMode', 'categorias'), 'app');
    }

    public function create(): void
    {
        $categoriaModel = new Categoria();
        $categorias = $categoriaModel->ativas();

        $this->view('public/registrar', compact('categorias'), 'public');
    }

    public function appCreate(): void
    {
        $categoriaModel = new Categoria();
        $categorias = $categoriaModel->ativas();
        $categoriaSelecionada = (int)($_GET['categoria_id'] ?? 0);

        $appMode = true;
        $this->view('public/registrar', compact('categorias', 'appMode', 'categoriaSelecionada'), 'app');
    }

    public function store(): void
    {
        $this->handleStore(false);
    }

    public function appStore(): void
    {
        $this->handleStore(true);
    }

    private function handleStore(bool $appMode): void
    {
        try {
            $db = Database::getConnection();
            $protocolo = gerarProtocolo($db);
            $imagem = !empty($_FILES['imagem']['name']) ? uploadImagem($_FILES['imagem']) : null;

            $anonima = isset($_POST['anonima']) ? 1 : 0;

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

            if ($dados['categoria_id'] <= 0 || $dados['descricao'] === '' || $dados['latitude'] === '' || $dados['longitude'] === '') {
                throw new RuntimeException('Preencha os campos obrigatórios.');
            }

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

            Session::flash('sucesso', 'Ocorrência registrada com sucesso.');
            Session::flash('protocolo', $protocolo);

            $this->redirect(($appMode ? '/app/sucesso' : '/sucesso') . '?id=' . $id);
        } catch (Throwable $e) {
            Session::flash('erro', APP_DEBUG ? $e->getMessage() : 'Erro ao registrar ocorrência.');
            $this->redirect($appMode ? '/app/registrar' : '/registrar');
        }
    }

    public function success(): void
    {
        $id = (int)($_GET['id'] ?? 0);
        $ocorrencia = null;

        if ($id > 0) {
            $model = new Ocorrencia();
            $ocorrencia = $model->buscarPorId($id);
        }

        $this->view('public/sucesso', compact('ocorrencia'), 'public');
    }

    public function appSuccess(): void
    {
        $id = (int)($_GET['id'] ?? 0);
        $ocorrencia = null;

        if ($id > 0) {
            $model = new Ocorrencia();
            $ocorrencia = $model->buscarPorId($id);
        }

        $appMode = true;
        $this->view('public/sucesso', compact('appMode', 'ocorrencia'), 'app');
    }

    public function index(): void
    {
        Auth::requireOccurrenceView();

        $filtros = [
            'protocolo'    => trim($_GET['protocolo'] ?? ''),
            'status'       => trim($_GET['status'] ?? ''),
            'categoria_id' => trim($_GET['categoria_id'] ?? ''),
            'setor_id'     => trim($_GET['setor_id'] ?? ''),
            'data_inicio'  => trim($_GET['data_inicio'] ?? ''),
            'data_fim'     => trim($_GET['data_fim'] ?? ''),
        ];

        $scope = Auth::occurrenceScope();
        if (array_key_exists('categoria_ids', $scope)) {
            $filtros['categoria_ids_scope'] = $scope['categoria_ids'];
        }

        $model = new Ocorrencia();
        $categoriaModel = new Categoria();
        $setorModel = new Setor();

        $ocorrencias = $model->listarComFiltros($filtros);
        $categorias = $categoriaModel->todas();
        $setores = $setorModel->todos();
        $somenteLeitura = !Auth::canEditOccurrences();

        $this->view('ocorrencias/index', compact('ocorrencias', 'categorias', 'setores', 'somenteLeitura'), 'admin');
    }

    public function show(): void
    {
        Auth::requireOccurrenceView();

        $id = (int)($_GET['id'] ?? 0);

        $model = new Ocorrencia();
        $ocorrencia = $model->buscarPorId($id, Auth::occurrenceScope());
        $historico = $model->historico($id);
        $setorModel = new Setor();
        $setores = $setorModel->ativos();
        $somenteLeitura = !Auth::canEditOccurrences();

        if (!$ocorrencia) {
            echo 'Ocorrência não encontrada.';
            return;
        }

        $this->view('ocorrencias/show', compact('ocorrencia', 'historico', 'setores', 'somenteLeitura'), 'admin');
    }

    public function updateStatus(): void
    {
        Auth::requireOccurrenceEdit();

        $id = (int)($_POST['id'] ?? 0);
        $status = trim($_POST['status'] ?? '');

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

        if (!$id || !in_array($status, $permitidos, true)) {
            Session::flash('erro', 'Dados inválidos para atualização.');
            $this->redirect('/admin/ocorrencias');
        }

        try {
            $model = new Ocorrencia();
            if (!$model->buscarPorId($id, Auth::occurrenceScope())) {
                throw new RuntimeException('Ocorrência não disponível para o seu usuário.');
            }
            $usuarioId = (int)(Auth::user()['id'] ?? 0) ?: null;
            $model->atualizarStatus($id, $status, $usuarioId);
            Session::flash('sucesso', 'Status atualizado com sucesso.');
        } catch (Throwable $e) {
            Session::flash('erro', APP_DEBUG ? $e->getMessage() : 'Nao foi possivel atualizar o status.');
        }

        $this->redirect('/admin/ocorrencias/show?id=' . $id);
    }

    public function updateSetor(): void
    {
        Auth::requireOccurrenceEdit();

        $id = (int)($_POST['id'] ?? 0);
        $setorId = isset($_POST['setor_id']) && $_POST['setor_id'] !== '' ? (int)$_POST['setor_id'] : null;

        if (!$id) {
            Session::flash('erro', 'Ocorrência inválida.');
            $this->redirect('/admin/ocorrencias');
        }

        $model = new Ocorrencia();
        if (!$model->buscarPorId($id, Auth::occurrenceScope())) {
            Session::flash('erro', 'Ocorrência não disponível para o seu usuário.');
            $this->redirect('/admin/ocorrencias');
        }

        $usuarioId = (int)(Auth::user()['id'] ?? 0) ?: null;
        $model->atualizarSetor($id, $setorId, $usuarioId);

        Session::flash('sucesso', 'Setor atualizado com sucesso.');
        $this->redirect('/admin/ocorrencias/show?id=' . $id);
    }
}
