<?php

namespace App\Controllers;

use Exception;

class CategoriasController extends BaseController
{
    /**
     * Lista todas as categorias
     */
    public function index(): void
    {
        // Verificar permissão de visualização
        if (!$this->canView('categorias')) {
            $this->response->forbidden('Você não tem permissão para visualizar categorias.');
            return;
        }

        try {
            $companyId = $this->getCompanyId();

            // Busca categorias com contagem de produtos
            $stmt = $this->db->prepare("
                SELECT c.*,
                       COUNT(p.id) as product_count
                FROM categorias c
                LEFT JOIN produtos p ON c.id = p.category_id AND p.is_active = 1
                WHERE c.company_id = :company_id
                GROUP BY c.id
                ORDER BY c.sort_order ASC, c.name ASC
            ");
            $stmt->execute(['company_id' => $companyId]);
            $categorias = $stmt->fetchAll();

            $this->view('categorias/index', [
                'categorias' => $categorias,
                'pageTitle' => 'Categorias'
            ]);

        } catch (Exception $e) {
            error_log("Erro ao carregar categorias: " . $e->getMessage());
            $this->error('Erro ao carregar categorias');
        }
    }

    /**
     * Exibe formulário de criação
     */
    public function create(): void
    {
        $categoriasPai = $this->getCategoriasPai();

        $this->view('categorias/form', [
            'categoriasPai' => $categoriasPai,
            'pageTitle' => 'Nova Categoria'
        ]);
    }

    /**
     * Salva nova categoria
     */
    public function store(): void
    {
        // Verificar permissão de criação
        if (!$this->canCreate('categorias')) {
            $this->response->forbidden('Você não tem permissão para criar categorias.');
            return;
        }

        try {
            $companyId = $this->getCompanyId();

            $data = [
                'company_id' => $companyId,
                'name' => $this->request->post('name'),
                'type' => $this->request->post('type'),
                'description' => $this->request->post('description'),
                'icon' => $this->request->post('icon'),
                'color' => $this->request->post('color'),
                'parent_id' => $this->request->post('parent_id') ?: null,
                'sort_order' => $this->request->post('sort_order') ?: 0,
                'is_active' => $this->request->post('is_active') ? 1 : 0,
                'requires_serial' => $this->request->post('requires_serial') ? 1 : 0,
                'requires_warranty' => $this->request->post('requires_warranty') ? 1 : 0,
                'taxable' => $this->request->post('taxable') ? 1 : 0,
            ];

            $errors = $this->validate([
                'name' => 'required|min:2',
                'type' => 'required|in:produtos,servicos,ambos',
            ]);

            if (!empty($errors)) {
                $this->error('Dados inválidos', $errors);
                return;
            }

            $this->db->beginTransaction();

            $stmt = $this->db->prepare("
                INSERT INTO categorias (
                    company_id, name, type, description, icon, color,
                    parent_id, sort_order, is_active, requires_serial,
                    requires_warranty, taxable, created_at, updated_at
                ) VALUES (
                    :company_id, :name, :type, :description, :icon, :color,
                    :parent_id, :sort_order, :is_active, :requires_serial,
                    :requires_warranty, :taxable, NOW(), NOW()
                )
            ");

            $stmt->execute($data);
            $categoriaId = $this->db->lastInsertId();

            $this->logActivity('create', 'categorias', $categoriaId, $data);

            $this->db->commit();

            $this->success('Categoria criada com sucesso', [
                'id' => $categoriaId,
                'redirect' => '/categorias'
            ]);

        } catch (Exception $e) {
            $this->db->rollBack();
            error_log("Erro ao criar categoria: " . $e->getMessage());
            $this->error('Erro ao cadastrar categoria');
        }
    }

    /**
     * Exibe formulário de edição
     */
    public function edit(): void
    {
        // Verificar permissão de edição
        if (!$this->canEdit('categorias')) {
            $this->response->forbidden('Você não tem permissão para editar categorias.');
            return;
        }

        try {
            $id = (int) $this->request->get('id');
            $categoria = $this->getCategoria($id);

            if (!$categoria) {
                $this->response->notFound('Categoria não encontrada');
                return;
            }

            $categoriasPai = $this->getCategoriasPai($id);

            $this->view('categorias/edit', [
                'categoria' => $categoria,
                'categoriasPai' => $categoriasPai,
                'pageTitle' => 'Editar ' . $categoria['name']
            ]);

        } catch (Exception $e) {
            error_log("Erro ao exibir formulário de edição: " . $e->getMessage());
            $this->error('Erro ao carregar formulário');
        }
    }

    /**
     * Atualiza uma categoria
     */
    public function update(): void
    {
        // Verificar permissão de edição
        if (!$this->canEdit('categorias')) {
            $this->response->forbidden('Você não tem permissão para editar categorias.');
            return;
        }

        try {
            $id = (int) $this->request->post('id');
            $categoria = $this->getCategoria($id);

            if (!$categoria) {
                $this->error('Categoria não encontrada');
                return;
            }

            $data = [
                'name' => $this->request->post('name'),
                'type' => $this->request->post('type'),
                'description' => $this->request->post('description'),
                'icon' => $this->request->post('icon'),
                'color' => $this->request->post('color'),
                'parent_id' => $this->request->post('parent_id') ?: null,
                'sort_order' => $this->request->post('sort_order') ?: 0,
                'is_active' => $this->request->post('is_active') ? 1 : 0,
                'requires_serial' => $this->request->post('requires_serial') ? 1 : 0,
                'requires_warranty' => $this->request->post('requires_warranty') ? 1 : 0,
                'taxable' => $this->request->post('taxable') ? 1 : 0,
                'id' => $id
            ];

            $errors = $this->validate([
                'name' => 'required|min:2',
                'type' => 'required|in:produtos,servicos,ambos',
            ]);

            if (!empty($errors)) {
                $this->error('Dados inválidos', $errors);
                return;
            }

            $this->db->beginTransaction();

            $stmt = $this->db->prepare("
                UPDATE categorias SET
                    name = :name,
                    type = :type,
                    description = :description,
                    icon = :icon,
                    color = :color,
                    parent_id = :parent_id,
                    sort_order = :sort_order,
                    is_active = :is_active,
                    requires_serial = :requires_serial,
                    requires_warranty = :requires_warranty,
                    taxable = :taxable,
                    updated_at = NOW()
                WHERE id = :id AND company_id = :company_id
            ");

            $data['company_id'] = $this->getCompanyId();
            $stmt->execute($data);

            $this->logActivity('update', 'categorias', $id, $data);

            $this->db->commit();

            $this->success('Categoria atualizada com sucesso', [
                'redirect' => '/categorias'
            ]);

        } catch (Exception $e) {
            $this->db->rollBack();
            error_log("Erro ao atualizar categoria: " . $e->getMessage());
            $this->error('Erro ao atualizar categoria');
        }
    }

    /**
     * Exclui uma categoria
     */
    public function delete(): void
    {
        // Verificar permissão de exclusão
        if (!$this->canDelete('categorias')) {
            $this->response->forbidden('Você não tem permissão para excluir categorias.');
            return;
        }

        try {
            $id = (int) $this->request->post('id');
            $categoria = $this->getCategoria($id);

            if (!$categoria) {
                $this->error('Categoria não encontrada');
                return;
            }

            // Verifica se há produtos vinculados
            $stmt = $this->db->prepare("
                SELECT COUNT(*) FROM produtos
                WHERE category_id = :id AND is_active = 1
            ");
            $stmt->execute(['id' => $id]);
            $produtosCount = $stmt->fetchColumn();

            if ($produtosCount > 0) {
                $this->error("Não é possível excluir esta categoria. Existem {$produtosCount} produto(s) vinculado(s).");
                return;
            }

            $this->db->beginTransaction();

            // Exclui subcategorias primeiro
            $stmt = $this->db->prepare("DELETE FROM categorias WHERE parent_id = :id AND company_id = :company_id");
            $stmt->execute(['id' => $id, 'company_id' => $this->getCompanyId()]);

            // Exclui a categoria
            $stmt = $this->db->prepare("DELETE FROM categorias WHERE id = :id AND company_id = :company_id");
            $stmt->execute(['id' => $id, 'company_id' => $this->getCompanyId()]);

            $this->logActivity('delete', 'categorias', $id, $categoria);

            $this->db->commit();

            $this->success('Categoria excluída com sucesso');

        } catch (Exception $e) {
            $this->db->rollBack();
            error_log("Erro ao excluir categoria: " . $e->getMessage());
            $this->error('Erro ao excluir categoria');
        }
    }

    /**
     * Busca uma categoria por ID
     */
    private function getCategoria(int $id): ?array
    {
        $stmt = $this->db->prepare("
            SELECT * FROM categorias
            WHERE id = :id AND company_id = :company_id
        ");
        $stmt->execute([
            'id' => $id,
            'company_id' => $this->getCompanyId()
        ]);

        return $stmt->fetch() ?: null;
    }

    /**
     * Busca categorias pai (para select)
     */
    private function getCategoriasPai(?int $excludeId = null): array
    {
        $sql = "
            SELECT id, name, type
            FROM categorias
            WHERE company_id = :company_id
            AND parent_id IS NULL
            AND is_active = 1
        ";

        $params = ['company_id' => $this->getCompanyId()];

        if ($excludeId) {
            $sql .= " AND id != :exclude_id";
            $params['exclude_id'] = $excludeId;
        }

        $sql .= " ORDER BY sort_order ASC, name ASC";

        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);

        return $stmt->fetchAll();
    }
}
