<?php

declare(strict_types=1);

namespace App\Controllers;

use Exception;
use App\Helpers\UrlHelper;

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

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

            $stmt = $this->db->prepare("
                SELECT * FROM locais_estoque
                WHERE company_id = :company_id
                ORDER BY name ASC
            ");
            $stmt->execute(['company_id' => $companyId]);
            $locais = $stmt->fetchAll();

            $this->view('gestor-estoque/index', [
                'locais' => $locais,
                'pageTitle' => 'Locais de Estoque',
                'activeMenu' => 'gestor-estoque'
            ]);

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

    public function create(): void
    {
        $this->view('gestor-estoque/create', [
            'local' => [],
            'posicoes' => [],
            'pageTitle' => 'Novo Local de Estoque',
            'activeMenu' => 'gestor-estoque'
        ]);
    }

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

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

            $data = [
                'company_id' => $companyId,
                'name' => $this->request->post('name'),
                'tipo' => $this->request->post('tipo'),
                'notes' => $this->request->post('description') ?: null,
                'address' => $this->request->post('address') ?: null,
                'is_active' => 1,
            ];

            $this->db->beginTransaction();

            $stmt = $this->db->prepare("
                INSERT INTO locais_estoque (company_id, name, tipo, notes, address, is_active, created_at, updated_at)
                VALUES (:company_id, :name, :tipo, :notes, :address, :is_active, NOW(), NOW())
            ");
            $stmt->execute($data);
            $localId = (int) $this->db->lastInsertId();

            // Salvar posições
            $this->salvarPosicoes($localId, $companyId);

            $this->logActivity('create', 'locais_estoque', $localId, $data);
            $this->db->commit();

            $this->success('Local criado com sucesso', [
                'id' => $localId,
                'redirect' => UrlHelper::url('/gestor-estoque')
            ]);

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

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

        try {
            $id = (int) $this->request->get('id');
            $local = $this->getLocal($id);

            if (!$local) {
                $this->response->notFound('Local não encontrado');
                return;
            }

            // Carregar posições do local
            $posicoes = $this->carregarPosicoes($id);

            $this->view('gestor-estoque/edit', [
                'local' => $local,
                'posicoes' => $posicoes,
                'pageTitle' => 'Editar Local',
                'activeMenu' => 'gestor-estoque'
            ]);

        } catch (Exception $e) {
            error_log("Erro ao editar local: " . $e->getMessage());
            $this->error('Erro ao carregar formulário');
        }
    }

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

        try {
            $id = (int) $this->request->post('id');
            $local = $this->getLocal($id);

            if (!$local) {
                $this->error('Local não encontrado');
                return;
            }

            $data = [
                'name' => $this->request->post('name'),
                'tipo' => $this->request->post('tipo'),
                'notes' => $this->request->post('description') ?: null,
                'address' => $this->request->post('address') ?: null,
                'is_active' => $this->request->post('is_active') ? 1 : 0,
                'id' => $id,
                'company_id' => $this->getCompanyId()
            ];

            $this->db->beginTransaction();

            $stmt = $this->db->prepare("
                UPDATE locais_estoque SET
                    name = :name,
                    tipo = :tipo,
                    notes = :notes,
                    address = :address,
                    is_active = :is_active,
                    updated_at = NOW()
                WHERE id = :id AND company_id = :company_id
            ");
            $stmt->execute($data);

            // Salvar posições
            $this->salvarPosicoes($id, $data['company_id']);

            $this->logActivity('update', 'locais_estoque', $id, $data);
            $this->db->commit();

            $this->success('Local atualizado com sucesso', [
                'redirect' => UrlHelper::url('/gestor-estoque')
            ]);

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

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

        try {
            $id = (int) $this->request->post('id');
            $local = $this->getLocal($id);

            if (!$local) {
                $this->error('Local não encontrado');
                return;
            }

            $this->db->beginTransaction();

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

            $this->logActivity('delete', 'locais_estoque', $id, $local);
            $this->db->commit();

            $this->success('Local excluído com sucesso');

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

    private function getLocal(int $id): ?array
    {
        $stmt = $this->db->prepare("SELECT * FROM locais_estoque WHERE id = :id AND company_id = :company_id");
        $stmt->execute(['id' => $id, 'company_id' => $this->getCompanyId()]);
        return $stmt->fetch() ?: null;
    }

    /**
     * Carrega posições de um local de estoque
     */
    private function carregarPosicoes(int $localEstoqueId): array
    {
        try {
            // Verificar se a tabela existe
            $stmtCheck = $this->db->query("SHOW TABLES LIKE 'local_estoque_posicoes'");
            if ($stmtCheck->rowCount() === 0) {
                return [];
            }

            $stmt = $this->db->prepare("
                SELECT id, posicao, ordem
                FROM local_estoque_posicoes
                WHERE local_estoque_id = :local_estoque_id
                ORDER BY ordem ASC, id ASC
            ");
            $stmt->execute(['local_estoque_id' => $localEstoqueId]);
            return $stmt->fetchAll() ?: [];
        } catch (Exception $e) {
            error_log("Erro ao carregar posições: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Salva posições de um local de estoque
     */
    private function salvarPosicoes(int $localEstoqueId, int $companyId): void
    {
        try {
            // Verificar se a tabela existe
            $stmtCheck = $this->db->query("SHOW TABLES LIKE 'local_estoque_posicoes'");
            if ($stmtCheck->rowCount() === 0) {
                // Tabela não existe, apenas retorna sem erro
                return;
            }

            $posicoes = $this->request->post('posicoes', []);

            if (!is_array($posicoes)) {
                $posicoes = [];
            }

            // Remover todas as posições existentes
            $stmtDelete = $this->db->prepare("
                DELETE FROM local_estoque_posicoes
                WHERE local_estoque_id = :local_estoque_id AND company_id = :company_id
            ");
            $stmtDelete->execute([
                'local_estoque_id' => $localEstoqueId,
                'company_id' => $companyId
            ]);

            // Inserir novas posições
            if (!empty($posicoes)) {
                $stmtInsert = $this->db->prepare("
                    INSERT INTO local_estoque_posicoes
                    (local_estoque_id, company_id, posicao, ordem, created_at, updated_at)
                    VALUES (:local_estoque_id, :company_id, :posicao, :ordem, NOW(), NOW())
                ");

                foreach ($posicoes as $index => $posicao) {
                    if (!empty($posicao['posicao'])) {
                        $stmtInsert->execute([
                            'local_estoque_id' => $localEstoqueId,
                            'company_id' => $companyId,
                            'posicao' => trim($posicao['posicao']),
                            'ordem' => $index
                        ]);
                    }
                }
            }
        } catch (Exception $e) {
            error_log("Erro ao salvar posições: " . $e->getMessage());
            // Não lança exceção para não quebrar o fluxo principal
        }
    }
}