<?php

namespace App\Controllers;

use Exception;

class AreaController extends BaseController
{
    /**
     * Listagem de áreas
     */
    public function index(): void
    {
        // Verificar permissão de visualização
        if (!$this->canView('areas')) {
            $this->response->forbidden('Você não tem permissão para visualizar áreas comerciais.');
            return;
        }

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

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

            // Paginação
            $perPage = 50;
            $page = max(1, (int) ($this->request->get('page') ?? 1));
            $offset = ($page - 1) * $perPage;

            // Contar total de áreas
            $stmtCount = $this->db->prepare("
                SELECT COUNT(*) as total
                FROM areas
                WHERE company_id = :company_id
            ");
            $stmtCount->execute(['company_id' => $companyId]);
            $total = (int) $stmtCount->fetch()['total'];
            $totalPages = max(1, (int) ceil($total / $perPage));

            // Buscar áreas (paginado)
            $stmt = $this->db->prepare("
                SELECT id, name, description, is_active, created_at, updated_at
                FROM areas
                WHERE company_id = :company_id
                ORDER BY name ASC
                LIMIT :limit OFFSET :offset
            ");
            $stmt->bindValue(':company_id', $companyId, \PDO::PARAM_INT);
            $stmt->bindValue(':limit', $perPage, \PDO::PARAM_INT);
            $stmt->bindValue(':offset', $offset, \PDO::PARAM_INT);
            $stmt->execute();
            $areas = $stmt->fetchAll();

            $this->view('areas/index', [
                'areas' => $areas,
                'pageTitle' => 'Áreas Comerciais',
                'page' => $page,
                'perPage' => $perPage,
                'total' => $total,
                'totalPages' => $totalPages
            ]);

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

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

        $this->view('areas/create', [
            'vendedores' => $vendedores,
            'pageTitle' => 'Nova Área Comercial'
        ]);
    }

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

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

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

            $name = trim($this->request->post('name', ''));
            $description = trim($this->request->post('description', ''));
            $vendedorId = $this->request->post('vendedor_id') ?: null;
            $vendedorAuxiliarId = $this->request->post('vendedor_auxiliar_id') ?: null;

            if (empty($name)) {
                $this->error('Nome da área é obrigatório');
                return;
            }

            // Validar que vendedor principal e auxiliar não sejam a mesma pessoa
            if ($vendedorId && $vendedorAuxiliarId && $vendedorId == $vendedorAuxiliarId) {
                $this->error('O vendedor principal e o vendedor auxiliar não podem ser a mesma pessoa');
                return;
            }

            // Verificar duplicação
            $stmt = $this->db->prepare("
                SELECT id FROM areas
                WHERE company_id = :company_id AND LOWER(name) = LOWER(:name)
            ");
            $stmt->execute(['company_id' => $companyId, 'name' => $name]);

            if ($stmt->fetch()) {
                $this->error('Já existe uma área com este nome');
                return;
            }

            $this->db->beginTransaction();

            $stmt = $this->db->prepare("
                INSERT INTO areas (company_id, name, description, vendedor_id, vendedor_auxiliar_id, is_active, created_at, updated_at)
                VALUES (:company_id, :name, :description, :vendedor_id, :vendedor_auxiliar_id, 1, NOW(), NOW())
            ");

            $stmt->execute([
                'company_id' => $companyId,
                'name' => $name,
                'description' => $description,
                'vendedor_id' => $vendedorId,
                'vendedor_auxiliar_id' => $vendedorAuxiliarId
            ]);

            $areaId = $this->db->lastInsertId();
            $this->logActivity('create', 'areas', $areaId, ['name' => $name, 'description' => $description]);

            // Atualizar vendedores nas pessoas vinculadas a esta área
            $this->atualizarVendedoresPessoasPorArea($areaId, $vendedorId, $vendedorAuxiliarId);

            $this->db->commit();

            $this->success('Área criada com sucesso', [
                'redirect' => '/areas'
            ]);

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

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

        try {
            $id = (int) $this->request->get('id');
            $area = $this->getArea($id);

            if (!$area) {
                $this->response->notFound('Área não encontrada');
                return;
            }

            $companyId = $this->getCompanyId();
            $vendedores = $this->getVendedores($companyId);

            $this->view('areas/edit', [
                'area' => $area,
                'vendedores' => $vendedores,
                'pageTitle' => 'Editar ' . $area['name']
            ]);

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

    /**
     * Atualizar área
     */
    public function update(): void
    {
        // Verificar permissão de edição
        if (!$this->canEdit('areas')) {
            $this->response->forbidden('Você não tem permissão para editar áreas comerciais.');
            return;
        }

        $id = (int) $this->request->post('id', 0);
        $name = trim($this->request->post('name', ''));
        $description = trim($this->request->post('description', ''));
        $vendedorId = $this->request->post('vendedor_id') ?: null;
        $vendedorAuxiliarId = $this->request->post('vendedor_auxiliar_id') ?: null;
        $isActive = $this->request->post('is_active') ? 1 : 0;

        // Validações
        if (empty($name)) {
            $this->error('Nome da área é obrigatório');
            return;
        }

        if (strlen($name) > 255) {
            $this->error('Nome não pode ter mais de 255 caracteres');
            return;
        }

        // Validar que vendedor principal e auxiliar não sejam a mesma pessoa
        if ($vendedorId && $vendedorAuxiliarId && $vendedorId == $vendedorAuxiliarId) {
            $this->error('O vendedor principal e o vendedor auxiliar não podem ser a mesma pessoa');
            return;
        }

        // Verificar se área existe
        $area = $this->getArea($id);
        if (!$area) {
            $this->error('Área não encontrada');
            return;
        }

        // Verificar duplicação de nome (case-insensitive)
        $companyId = $this->getCompanyId();
        $stmt = $this->db->prepare("
            SELECT id FROM areas
            WHERE company_id = :company_id AND LOWER(name) = LOWER(:name) AND id != :id
        ");
        $stmt->execute([
            'company_id' => $companyId,
            'name' => $name,
            'id' => $id
        ]);

        if ($stmt->fetch()) {
            $this->error('Já existe uma área com este nome');
            return;
        }

        try {
            $this->db->beginTransaction();

            $stmt = $this->db->prepare("
                UPDATE areas
                SET name = :name, description = :description, vendedor_id = :vendedor_id, vendedor_auxiliar_id = :vendedor_auxiliar_id, is_active = :is_active, updated_at = NOW()
                WHERE id = :id AND company_id = :company_id
            ");

            $stmt->execute([
                'name' => $name,
                'description' => $description,
                'vendedor_id' => $vendedorId,
                'vendedor_auxiliar_id' => $vendedorAuxiliarId,
                'is_active' => $isActive,
                'id' => $id,
                'company_id' => $companyId
            ]);

            $this->logActivity('update', 'areas', $id, ['name' => $name, 'description' => $description]);

            // Atualizar vendedores nas pessoas vinculadas a esta área
            $this->atualizarVendedoresPessoasPorArea($id, $vendedorId, $vendedorAuxiliarId);

            $this->db->commit();

            $this->success('Área atualizada com sucesso', [
                'redirect' => '/areas'
            ]);

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

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

        $id = (int) $this->request->post('id', 0);

        $area = $this->getArea($id);
        if (!$area) {
            $this->error('Área não encontrada');
            return;
        }

        try {
            $this->db->beginTransaction();

            $companyId = $this->getCompanyId();
            $stmt = $this->db->prepare("
                DELETE FROM areas
                WHERE id = :id AND company_id = :company_id
            ");

            $stmt->execute([
                'id' => $id,
                'company_id' => $companyId
            ]);

            $this->logActivity('delete', 'areas', $id, ['name' => $area['name']]);

            $this->db->commit();

            $this->success('Área deletada com sucesso', [
                'redirect' => '/areas'
            ]);

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

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

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

    /**
     * Atualiza vendedores nas pessoas vinculadas a uma área
     */
    private function atualizarVendedoresPessoasPorArea(int $areaId, ?int $vendedorId, ?int $vendedorAuxiliarId): void
    {
        try {
            // Verificar se a coluna area_comercial_id existe na tabela pessoas
            $stmtCheck = $this->db->query("SHOW COLUMNS FROM pessoas LIKE 'area_comercial_id'");
            if ($stmtCheck->rowCount() === 0) {
                // Coluna não existe ainda, não há nada para atualizar
                return;
            }

            $companyId = $this->getCompanyId();

            // Atualizar todas as pessoas que estão vinculadas a esta área
            $stmt = $this->db->prepare("
                UPDATE pessoas
                SET vendedor_id = :vendedor_id,
                    vendedor_auxiliar_id = :vendedor_auxiliar_id,
                    updated_at = NOW()
                WHERE company_id = :company_id
                  AND area_comercial_id = :area_comercial_id
            ");

            $stmt->execute([
                'vendedor_id' => $vendedorId,
                'vendedor_auxiliar_id' => $vendedorAuxiliarId,
                'company_id' => $companyId,
                'area_comercial_id' => $areaId
            ]);

            $rowsAffected = $stmt->rowCount();
            if ($rowsAffected > 0) {
                error_log("AreaController: Atualizadas {$rowsAffected} pessoa(s) vinculadas à área ID {$areaId}");
            }

        } catch (Exception $e) {
            error_log("Erro ao atualizar vendedores nas pessoas: " . $e->getMessage());
            // Não lançar exceção para não interromper o fluxo principal
        }
    }

    /**
     * Busca vendedores (usuários com role ou type = 'vendedor')
     */
    private function getVendedores(int $companyId): array
    {
        try {
            // Verificar se a tabela users existe
            $stmt = $this->db->query("SHOW TABLES LIKE 'users'");
            if ($stmt->rowCount() === 0) {
                return [];
            }

            // Verificar se o campo é 'type' ou 'role'
            $stmtCheck = $this->db->query("SHOW COLUMNS FROM users LIKE 'type'");
            $temCampoType = $stmtCheck->fetch() !== false;

            $stmtCheck = $this->db->query("SHOW COLUMNS FROM users LIKE 'role'");
            $temCampoRole = $stmtCheck->fetch() !== false;

            // Buscar vendedores - tentar type primeiro, depois role
            if ($temCampoType) {
                $stmt = $this->db->prepare("
                    SELECT id, name FROM users
                    WHERE company_id = :company_id
                      AND type = 'vendedor'
                      AND is_active = 1
                    ORDER BY name ASC
                ");
            } elseif ($temCampoRole) {
                $stmt = $this->db->prepare("
                    SELECT id, name FROM users
                    WHERE company_id = :company_id
                      AND role = 'vendedor'
                      AND is_active = 1
                    ORDER BY name ASC
                ");
            } else {
                // Se não tiver nenhum dos campos, buscar todos os usuários ativos
                $stmt = $this->db->prepare("
                    SELECT id, name FROM users
                    WHERE company_id = :company_id
                      AND is_active = 1
                    ORDER BY name ASC
                ");
            }

            $stmt->execute(['company_id' => $companyId]);
            return $stmt->fetchAll();
        } catch (Exception $e) {
            error_log("Erro ao buscar vendedores: " . $e->getMessage());
            return [];
        }
    }
}
