<?php

declare(strict_types=1);

namespace App\Controllers;

use Exception;

class AgendaTecnicaController extends BaseController
{
    public function index(): void
    {
        // Verificar se o usuário é admin ou tem permissão de suporte
        $user = $this->session->get('user');
        if (!$user || ($user['role'] !== 'admin' && $user['role'] !== 'suporte')) {
            $this->response->forbidden('Acesso negado. Área restrita ao suporte.');
            return;
        }

        try {
            $companyId = $this->getCompanyId();
            $search = $this->request->get('search', '');
            $tecnicoId = $this->request->get('tecnico_id', '');
            $clienteId = $this->request->get('cliente_id', '');
            $dataDe = $this->request->get('data_de', '');
            $dataAte = $this->request->get('data_ate', '');

            // Criar tabela se não existir
            $this->criarTabelaAgendaTecnica();

            $query = "
                SELECT
                    at.*,
                    u.name as tecnico_nome,
                    p.name as cliente_nome
                FROM agenda_tecnica at
                LEFT JOIN users u ON at.tecnico_id = u.id
                LEFT JOIN pessoas p ON at.cliente_id = p.id
                WHERE at.company_id = :company_id
            ";

            $params = ['company_id' => $companyId];

            if (!empty($search)) {
                $query .= " AND (at.titulo LIKE :search OR at.descricao LIKE :search OR p.name LIKE :search OR u.name LIKE :search)";
                $params['search'] = "%{$search}%";
            }

            if (!empty($tecnicoId)) {
                $query .= " AND at.tecnico_id = :tecnico_id";
                $params['tecnico_id'] = $tecnicoId;
            }

            if (!empty($clienteId)) {
                $query .= " AND at.cliente_id = :cliente_id";
                $params['cliente_id'] = $clienteId;
            }

            if (!empty($dataDe)) {
                $query .= " AND DATE(at.data_agendamento) >= :data_de";
                $params['data_de'] = $dataDe;
            }

            if (!empty($dataAte)) {
                $query .= " AND DATE(at.data_agendamento) <= :data_ate";
                $params['data_ate'] = $dataAte;
            }

            $query .= " ORDER BY at.data_agendamento ASC, at.hora_inicio ASC";

            $stmt = $this->db->prepare($query);
            $stmt->execute($params);
            $agendamentos = $stmt->fetchAll();

            // Buscar técnicos
            $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]);
            $tecnicos = $stmt->fetchAll();

            // Buscar clientes
            $stmt = $this->db->prepare("
                SELECT id, name FROM pessoas
                WHERE company_id = :company_id AND is_active = 1
                ORDER BY name ASC
            ");
            $stmt->execute(['company_id' => $companyId]);
            $clientes = $stmt->fetchAll();

            $this->view('agenda-tecnica/index', [
                'agendamentos' => $agendamentos,
                'tecnicos' => $tecnicos,
                'clientes' => $clientes,
                'search' => $search,
                'tecnico_id' => $tecnicoId,
                'cliente_id' => $clienteId,
                'data_de' => $dataDe,
                'data_ate' => $dataAte,
                'pageTitle' => 'Agenda Técnica',
                'activeMenu' => 'agenda-tecnica'
            ]);

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

    public function criar(): void
    {
        $user = $this->session->get('user');
        if (!$user || ($user['role'] !== 'admin' && $user['role'] !== 'suporte')) {
            $this->response->forbidden('Acesso negado. Área restrita ao suporte.');
            return;
        }

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

            // Buscar técnicos
            $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]);
            $tecnicos = $stmt->fetchAll();

            $this->view('agenda-tecnica/form', [
                'tecnicos' => $tecnicos,
                'pageTitle' => 'Novo Agendamento Técnico',
                'activeMenu' => 'agenda-tecnica'
            ]);

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

    public function store(): void
    {
        $user = $this->session->get('user');
        if (!$user || ($user['role'] !== 'admin' && $user['role'] !== 'suporte')) {
            $this->response->forbidden('Acesso negado. Área restrita ao suporte.');
            return;
        }

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

            $modulosJson = $this->request->post('modulos', '[]');
            $modulosArray = json_decode($modulosJson, true);
            $modulosFinal = is_array($modulosArray) ? json_encode($modulosArray) : '[]';

            $funcionariosJson = $this->request->post('funcionarios_treinados', '[]');
            $funcionariosArray = json_decode($funcionariosJson, true);
            $funcionariosArray = is_array($funcionariosArray) ? $funcionariosArray : [];

            $clienteId = $this->request->post('cliente_id');
            if (empty($clienteId)) {
                $this->error('Cliente é obrigatório');
                return;
            }

            $data = [
                'company_id' => $companyId,
                'tecnico_id' => $this->request->post('tecnico_id'),
                'cliente_id' => $clienteId,
                'titulo' => $this->request->post('titulo'),
                'tipo_atendimento' => $this->request->post('tipo_atendimento'),
                'produto_visita_comercial' => $this->request->post('produto_visita_comercial'),
                'assunto_tratado_com' => $this->request->post('assunto_tratado_com'),
                'descricao' => $this->request->post('descricao'),
                'data_agendamento' => $this->request->post('data_agendamento'),
                'hora_inicio' => $this->request->post('hora_inicio'),
                'hora_fim' => $this->request->post('hora_fim'),
                'status' => $this->request->post('status', 'agendado'),
                'observacoes' => $this->request->post('observacoes'),
                'created_by' => $userId
            ];

            // Criar tabela auxiliar se não existir
            $this->criarTabelaFuncionariosModulos();

            $this->db->beginTransaction();

            try {
                $stmt = $this->db->prepare("
                    INSERT INTO agenda_tecnica (
                        company_id, tecnico_id, cliente_id, titulo, tipo_atendimento, produto_visita_comercial, assunto_tratado_com, descricao,
                        data_agendamento, hora_inicio, hora_fim, status, observacoes,
                        created_by, created_at, updated_at
                    ) VALUES (
                        :company_id, :tecnico_id, :cliente_id, :titulo, :tipo_atendimento, :produto_visita_comercial, :assunto_tratado_com, :descricao,
                        :data_agendamento, :hora_inicio, :hora_fim, :status, :observacoes,
                        :created_by, NOW(), NOW()
                    )
                ");

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

                // Salvar funcionários e módulos na tabela auxiliar
                if (!empty($funcionariosModulosArray)) {
                    $stmtFunc = $this->db->prepare("
                        INSERT INTO agenda_tecnica_funcionarios_modulos (agenda_tecnica_id, funcionario_nome, modulo_nome)
                        VALUES (:agenda_tecnica_id, :funcionario_nome, :modulo_nome)
                    ");

                    foreach ($funcionariosModulosArray as $item) {
                        $funcionario = trim($item['funcionario'] ?? '');
                        $modulos = $item['modulos'] ?? [];

                        if (!empty($funcionario) && is_array($modulos)) {
                            foreach ($modulos as $modulo) {
                                $modulo = trim($modulo);
                                if (!empty($modulo)) {
                                    $stmtFunc->execute([
                                        'agenda_tecnica_id' => $id,
                                        'funcionario_nome' => $funcionario,
                                        'modulo_nome' => $modulo
                                    ]);
                                }
                            }
                        }
                    }
                }

                $this->db->commit();
                $this->logActivity('create', 'agenda_tecnica', $id, $data);
                $this->success('Agendamento criado com sucesso', [
                    'redirect' => '/agenda-tecnica'
                ]);

            } catch (Exception $e) {
                $this->db->rollBack();
                throw $e;
            }

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

    public function editar(): void
    {
        $user = $this->session->get('user');
        if (!$user || ($user['role'] !== 'admin' && $user['role'] !== 'suporte')) {
            $this->response->forbidden('Acesso negado. Área restrita ao suporte.');
            return;
        }

        try {
            $id = (int) $this->request->get('id');
            $companyId = $this->getCompanyId();

            $stmt = $this->db->prepare("
                SELECT * FROM agenda_tecnica
                WHERE id = :id AND company_id = :company_id
            ");
            $stmt->execute(['id' => $id, 'company_id' => $companyId]);
            $agendamento = $stmt->fetch();

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

            // Buscar técnicos
            $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]);
            $tecnicos = $stmt->fetchAll();

            // Buscar funcionários e módulos da tabela auxiliar
            $this->criarTabelaFuncionariosModulos();
            $stmt = $this->db->prepare("
                SELECT funcionario_nome, modulo_nome
                FROM agenda_tecnica_funcionarios_modulos
                WHERE agenda_tecnica_id = :agenda_tecnica_id
                ORDER BY funcionario_nome, modulo_nome ASC
            ");
            $stmt->execute(['agenda_tecnica_id' => $id]);
            $funcionariosModulos = $stmt->fetchAll();

            $this->view('agenda-tecnica/form', [
                'agendamento' => $agendamento,
                'tecnicos' => $tecnicos,
                'funcionarios_treinados' => $funcionariosModulos,
                'pageTitle' => 'Editar Agendamento Técnico',
                'activeMenu' => 'agenda-tecnica'
            ]);

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

    public function update(): void
    {
        $user = $this->session->get('user');
        if (!$user || ($user['role'] !== 'admin' && $user['role'] !== 'suporte')) {
            $this->response->forbidden('Acesso negado. Área restrita ao suporte.');
            return;
        }

        try {
            $id = (int) $this->request->post('id');
            $companyId = $this->getCompanyId();

            $stmt = $this->db->prepare("
                SELECT * FROM agenda_tecnica
                WHERE id = :id AND company_id = :company_id
            ");
            $stmt->execute(['id' => $id, 'company_id' => $companyId]);
            $agendamento = $stmt->fetch();

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

            $funcionariosModulosJson = $this->request->post('funcionarios_modulos', '[]');
            $funcionariosModulosArray = json_decode($funcionariosModulosJson, true);
            $funcionariosModulosArray = is_array($funcionariosModulosArray) ? $funcionariosModulosArray : [];

            $clienteId = $this->request->post('cliente_id');
            if (empty($clienteId)) {
                $this->error('Cliente é obrigatório');
                return;
            }

            $data = [
                'id' => $id,
                'tecnico_id' => $this->request->post('tecnico_id'),
                'cliente_id' => $clienteId,
                'titulo' => $this->request->post('titulo'),
                'tipo_atendimento' => $this->request->post('tipo_atendimento'),
                'produto_visita_comercial' => $this->request->post('produto_visita_comercial'),
                'assunto_tratado_com' => $this->request->post('assunto_tratado_com'),
                'descricao' => $this->request->post('descricao'),
                'data_agendamento' => $this->request->post('data_agendamento'),
                'hora_inicio' => $this->request->post('hora_inicio'),
                'hora_fim' => $this->request->post('hora_fim'),
                'status' => $this->request->post('status'),
                'observacoes' => $this->request->post('observacoes')
            ];

            $this->criarTabelaFuncionariosModulos();

            $this->db->beginTransaction();

            try {
                $stmt = $this->db->prepare("
                    UPDATE agenda_tecnica SET
                        tecnico_id = :tecnico_id,
                        cliente_id = :cliente_id,
                        titulo = :titulo,
                        tipo_atendimento = :tipo_atendimento,
                        produto_visita_comercial = :produto_visita_comercial,
                        assunto_tratado_com = :assunto_tratado_com,
                        descricao = :descricao,
                        data_agendamento = :data_agendamento,
                        hora_inicio = :hora_inicio,
                        hora_fim = :hora_fim,
                        status = :status,
                        observacoes = :observacoes,
                        updated_at = NOW()
                    WHERE id = :id AND company_id = :company_id
                ");

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

                // Remover funcionários e módulos antigos
                $stmtDel = $this->db->prepare("
                    DELETE FROM agenda_tecnica_funcionarios_modulos
                    WHERE agenda_tecnica_id = :agenda_tecnica_id
                ");
                $stmtDel->execute(['agenda_tecnica_id' => $id]);

                // Inserir funcionários e módulos atualizados
                if (!empty($funcionariosModulosArray)) {
                    $stmtFunc = $this->db->prepare("
                        INSERT INTO agenda_tecnica_funcionarios_modulos (agenda_tecnica_id, funcionario_nome, modulo_nome)
                        VALUES (:agenda_tecnica_id, :funcionario_nome, :modulo_nome)
                    ");

                    foreach ($funcionariosModulosArray as $item) {
                        $funcionario = trim($item['funcionario'] ?? '');
                        $modulos = $item['modulos'] ?? [];

                        if (!empty($funcionario) && is_array($modulos)) {
                            foreach ($modulos as $modulo) {
                                $modulo = trim($modulo);
                                if (!empty($modulo)) {
                                    $stmtFunc->execute([
                                        'agenda_tecnica_id' => $id,
                                        'funcionario_nome' => $funcionario,
                                        'modulo_nome' => $modulo
                                    ]);
                                }
                            }
                        }
                    }
                }

                $this->db->commit();
                $this->logActivity('update', 'agenda_tecnica', $id, $data);
                $this->success('Agendamento atualizado com sucesso', [
                    'redirect' => '/agenda-tecnica'
                ]);

            } catch (Exception $e) {
                $this->db->rollBack();
                throw $e;
            }

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

    public function deletar(): void
    {
        $user = $this->session->get('user');
        if (!$user || ($user['role'] !== 'admin' && $user['role'] !== 'suporte')) {
            $this->response->forbidden('Acesso negado. Área restrita ao suporte.');
            return;
        }

        try {
            $id = (int) $this->request->post('id');
            $companyId = $this->getCompanyId();

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

            $this->logActivity('delete', 'agenda_tecnica', $id);
            $this->success('Agendamento excluído com sucesso');

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

    private function criarTabelaFuncionariosModulos(): void
    {
        try {
            $stmt = $this->db->query("SHOW TABLES LIKE 'agenda_tecnica_funcionarios_modulos'");
            if ($stmt->rowCount() > 0) {
                return;
            }

            $sql = "
                CREATE TABLE IF NOT EXISTS `agenda_tecnica_funcionarios_modulos` (
                    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                    `agenda_tecnica_id` INT UNSIGNED NOT NULL,
                    `funcionario_nome` VARCHAR(255) NOT NULL,
                    `modulo_nome` VARCHAR(255) NOT NULL,
                    `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
                    INDEX `idx_agenda_tecnica` (`agenda_tecnica_id`),
                    INDEX `idx_funcionario` (`funcionario_nome`),
                    UNIQUE KEY `uk_funcionario_modulo` (`agenda_tecnica_id`, `funcionario_nome`, `modulo_nome`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
            ";

            $this->db->exec($sql);

        } catch (Exception $e) {
            error_log("Erro ao criar tabela agenda_tecnica_funcionarios_modulos: " . $e->getMessage());
        }
    }

    public function buscarClientes(): void
    {
        try {
            $companyId = $this->getCompanyId();
            $termo = trim((string) $this->request->get('q', ''));

            // Se termo vazio, retornar todos (limitado) - igual ao módulo de vendas
            if (empty($termo)) {
                $stmt = $this->db->prepare("
                    SELECT id, name, trade_name, document, phone, mobile, email, tabela_preco_id,
                           vendedor_id, vendedor_auxiliar_id
                    FROM pessoas
                    WHERE company_id = :company_id
                      AND is_active = 1
                      AND (type = 'cliente' OR type = 'ambos')
                    ORDER BY name ASC
                    LIMIT 100
                ");
                $stmt->execute(['company_id' => $companyId]);
            } else {
                $consulta = "%{$termo}%";
                $stmt = $this->db->prepare("
                    SELECT id, name, trade_name, document, phone, mobile, email, tabela_preco_id,
                           vendedor_id, vendedor_auxiliar_id
                    FROM pessoas
                    WHERE company_id = :company_id
                      AND is_active = 1
                      AND (type = 'cliente' OR type = 'ambos')
                      AND (name LIKE :busca OR trade_name LIKE :busca OR document LIKE :busca OR email LIKE :busca OR phone LIKE :busca OR mobile LIKE :busca)
                    ORDER BY name ASC
                    LIMIT 20
                ");
                $stmt->execute([
                    'company_id' => $companyId,
                    'busca' => $consulta
                ]);
            }

            $clientes = $stmt->fetchAll();
            $this->success('Clientes encontrados', ['clientes' => $clientes]);

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

    private function criarTabelaAgendaTecnica(): void
    {
        try {
            $stmt = $this->db->query("SHOW TABLES LIKE 'agenda_tecnica'");
            if ($stmt->rowCount() > 0) {
                return;
            }

            $sql = "
                CREATE TABLE IF NOT EXISTS `agenda_tecnica` (
                    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                    `company_id` INT UNSIGNED NOT NULL,
                    `tecnico_id` INT UNSIGNED NULL,
                    `cliente_id` INT UNSIGNED NULL,
                    `titulo` VARCHAR(255) NOT NULL,
                    `tipo_atendimento` VARCHAR(50) NULL,
                    `produto_visita_comercial` VARCHAR(100) NULL,
                    `assunto_tratado_com` VARCHAR(255) NULL,
                    `funcionario_treinado` TEXT NULL,
                    `modulos` TEXT NULL,
                    `descricao` TEXT NULL,
                    `data_agendamento` DATE NOT NULL,
                    `hora_inicio` TIME NOT NULL,
                    `hora_fim` TIME NULL,
                    `status` VARCHAR(50) DEFAULT 'agendado',
                    `observacoes` TEXT NULL,
                    `created_by` INT UNSIGNED NULL,
                    `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
                    `updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                    INDEX `idx_company` (`company_id`),
                    INDEX `idx_tecnico` (`tecnico_id`),
                    INDEX `idx_cliente` (`cliente_id`),
                    INDEX `idx_data` (`data_agendamento`),
                    INDEX `idx_status` (`status`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
            ";

            $this->db->exec($sql);

        } catch (Exception $e) {
            error_log("Erro ao criar tabela agenda_tecnica: " . $e->getMessage());
        }
    }
}

