<?php

require_once __DIR__ . '/../../config/bootstrap.php';

use ControleFrotas\Config\Database;
use ControleFrotas\Utils\Response;
use ControleFrotas\Utils\Logger;

header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit();
}

// Verificar autenticação e permissão
$user = requireRole('Administrador', 'Supervisor');

if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    obterRelatorioViagens();
} else {
    Response::error('Método não permitido', 405);
}

function obterRelatorioViagens(): void {
    try {
        // Obter parâmetros de filtro da URL
        $filtros = [
            'data_inicio' => $_GET['data_inicio'] ?? null,
            'data_fim' => $_GET['data_fim'] ?? null,
            'tecnico_id' => $_GET['tecnico_id'] ?? null,
            'veiculo_id' => $_GET['veiculo_id'] ?? null,
            'status' => $_GET['status'] ?? null,
            'cliente' => $_GET['cliente'] ?? null,
            'periodo' => $_GET['periodo'] ?? null,
            'agrupamento' => $_GET['agrupamento'] ?? 'dia'
        ];

        // Buscar dados baseados nos filtros
        $dadosRelatorio = [
            'resumo' => obterResumoViagens($filtros),
            'viagens' => obterListaViagens($filtros),
            'estatisticas' => obterEstatisticasViagens($filtros),
            'graficos' => obterDadosGraficos($filtros),
            'tecnicos_performance' => obterPerformanceTecnicos($filtros),
            'veiculos_utilizacao' => obterUtilizacaoVeiculos($filtros),
            'filtros_aplicados' => $filtros
        ];

        Logger::info('Relatório de viagens acessado', [
            'user_id' => getCurrentUser()['user_id'],
            'filtros' => $filtros
        ]);

        Response::success($dadosRelatorio);

    } catch (Exception $e) {
        Logger::error('Erro ao gerar relatório de viagens', [
            'error' => $e->getMessage(),
            'trace' => $e->getTraceAsString()
        ]);
        Response::error('Erro ao carregar relatório: ' . $e->getMessage(), 500);
    }
}

function construirWhere(array $filtros): array {
    $whereConditions = [];
    $params = [];

    // Filtro por período predefinido
    if (!empty($filtros['periodo'])) {
        switch ($filtros['periodo']) {
            case 'hoje':
                $whereConditions[] = 'DATE(v.data_inicio) = CURDATE()';
                break;
            case 'ontem':
                $whereConditions[] = 'DATE(v.data_inicio) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)';
                break;
            case 'semana':
                $whereConditions[] = 'v.data_inicio >= DATE_SUB(NOW(), INTERVAL 7 DAY)';
                break;
            case 'mes':
                $whereConditions[] = 'MONTH(v.data_inicio) = MONTH(CURDATE()) AND YEAR(v.data_inicio) = YEAR(CURDATE())';
                break;
            case 'mes_anterior':
                $whereConditions[] = 'MONTH(v.data_inicio) = MONTH(DATE_SUB(CURDATE(), INTERVAL 1 MONTH)) AND YEAR(v.data_inicio) = YEAR(DATE_SUB(CURDATE(), INTERVAL 1 MONTH))';
                break;
            case 'trimestre':
                $whereConditions[] = 'v.data_inicio >= DATE_SUB(NOW(), INTERVAL 3 MONTH)';
                break;
            case 'ano':
                $whereConditions[] = 'YEAR(v.data_inicio) = YEAR(CURDATE())';
                break;
        }
    } else {
        // Filtros por data específica
        if (!empty($filtros['data_inicio'])) {
            $whereConditions[] = 'DATE(v.data_inicio) >= ?';
            $params[] = $filtros['data_inicio'];
        }
        
        if (!empty($filtros['data_fim'])) {
            $whereConditions[] = 'DATE(v.data_inicio) <= ?';
            $params[] = $filtros['data_fim'];
        }
    }

    // Outros filtros
    if (!empty($filtros['tecnico_id'])) {
        $whereConditions[] = 'v.tecnico_id = ?';
        $params[] = $filtros['tecnico_id'];
    }

    if (!empty($filtros['veiculo_id'])) {
        $whereConditions[] = 'v.veiculo_id = ?';
        $params[] = $filtros['veiculo_id'];
    }

    if (!empty($filtros['status'])) {
        if ($filtros['status'] === 'em_andamento') {
            $whereConditions[] = 'v.data_fim IS NULL';
        } elseif ($filtros['status'] === 'finalizada') {
            $whereConditions[] = 'v.data_fim IS NOT NULL';
        }
    }

    if (!empty($filtros['cliente'])) {
        $whereConditions[] = 'v.cliente LIKE ?';
        $params[] = '%' . $filtros['cliente'] . '%';
    }

    return [
        'where' => empty($whereConditions) ? '1=1' : implode(' AND ', $whereConditions),
        'params' => $params
    ];
}

function obterResumoViagens(array $filtros): array {
    $where = construirWhere($filtros);
    
    $sql = "SELECT 
        COUNT(*) as total_viagens,
        COUNT(CASE WHEN v.data_fim IS NULL THEN 1 END) as em_andamento,
        COUNT(CASE WHEN v.data_fim IS NOT NULL THEN 1 END) as finalizadas,
        COUNT(DISTINCT v.tecnico_id) as tecnicos_envolvidos,
        COUNT(DISTINCT v.veiculo_id) as veiculos_utilizados,
        SUM(CASE WHEN v.km_final IS NOT NULL THEN v.km_final - v.km_inicial ELSE 0 END) as km_total,
        AVG(CASE WHEN v.km_final IS NOT NULL THEN v.km_final - v.km_inicial ELSE NULL END) as km_medio,
        AVG(CASE WHEN v.data_fim IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, v.data_inicio, v.data_fim) ELSE NULL END) as tempo_medio_minutos
        FROM viagens v
        WHERE " . $where['where'];
    
    return Database::queryOne($sql, $where['params']) ?: [];
}

function obterListaViagens(array $filtros): array {
    $where = construirWhere($filtros);
    
    $sql = "SELECT 
        v.*,
        u.nome as tecnico_nome,
        ve.modelo as veiculo_modelo,
        ve.placa as veiculo_placa,
        ve.marca as veiculo_marca,
        CASE 
            WHEN v.data_fim IS NULL THEN 'Em Andamento'
            ELSE 'Finalizada'
        END as status_viagem,
        CASE 
            WHEN v.data_fim IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, v.data_inicio, v.data_fim)
            ELSE NULL 
        END as duracao_minutos,
        CASE 
            WHEN v.km_final IS NOT NULL THEN v.km_final - v.km_inicial
            ELSE NULL 
        END as km_percorridos
        FROM viagens v
        LEFT JOIN usuarios u ON v.tecnico_id = u.id
        LEFT JOIN veiculos ve ON v.veiculo_id = ve.id
        WHERE " . $where['where'] . "
        ORDER BY v.data_inicio DESC
        LIMIT 1000";
    
    return Database::queryAll($sql, $where['params']);
}

function obterEstatisticasViagens(array $filtros): array {
    $where = construirWhere($filtros);
    
    try {
        $stats = Database::queryOne("
            SELECT 
                MAX(v.km_final - v.km_inicial) as maior_km,
                MIN(CASE WHEN v.km_final > v.km_inicial THEN v.km_final - v.km_inicial ELSE NULL END) as menor_km,
                MAX(CASE WHEN v.data_fim IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, v.data_inicio, v.data_fim) ELSE NULL END) as maior_duracao,
                MIN(CASE WHEN v.data_fim IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, v.data_inicio, v.data_fim) ELSE NULL END) as menor_duracao,
                COUNT(CASE WHEN HOUR(v.data_inicio) BETWEEN 6 AND 12 THEN 1 END) as viagens_manha,
                COUNT(CASE WHEN HOUR(v.data_inicio) BETWEEN 12 AND 18 THEN 1 END) as viagens_tarde,
                COUNT(CASE WHEN HOUR(v.data_inicio) BETWEEN 18 AND 23 OR HOUR(v.data_inicio) BETWEEN 0 AND 6 THEN 1 END) as viagens_noite
            FROM viagens v
            WHERE " . $where['where'], $where['params']);

        return $stats ?: [];
    } catch (Exception $e) {
        return [];
    }
}

function obterDadosGraficos(array $filtros): array {
    $where = construirWhere($filtros);
    $agrupamento = $filtros['agrupamento'] ?? 'dia';
    
    // Viagens por período
    $formatData = match($agrupamento) {
        'hora' => 'DATE_FORMAT(v.data_inicio, "%Y-%m-%d %H:00")',
        'dia' => 'DATE(v.data_inicio)',
        'semana' => 'DATE_FORMAT(v.data_inicio, "%Y-%u")',
        'mes' => 'DATE_FORMAT(v.data_inicio, "%Y-%m")',
        default => 'DATE(v.data_inicio)'
    };
    
    $viagensPorPeriodo = Database::queryAll("
        SELECT 
            $formatData as periodo,
            COUNT(*) as total_viagens,
            COUNT(CASE WHEN v.data_fim IS NOT NULL THEN 1 END) as finalizadas,
            SUM(CASE WHEN v.km_final IS NOT NULL THEN v.km_final - v.km_inicial ELSE 0 END) as km_total
        FROM viagens v
        WHERE " . $where['where'] . "
        GROUP BY $formatData
        ORDER BY periodo", $where['params']);

    // Status das viagens (gráfico pizza)
    $statusViagens = Database::queryAll("
        SELECT 
            CASE 
                WHEN v.data_fim IS NULL THEN 'Em Andamento'
                ELSE 'Finalizada'
            END as status,
            COUNT(*) as quantidade
        FROM viagens v
        WHERE " . $where['where'] . "
        GROUP BY status", $where['params']);

    // Top técnicos
    $topTecnicos = Database::queryAll("
        SELECT 
            u.nome,
            COUNT(v.id) as total_viagens,
            SUM(CASE WHEN v.km_final IS NOT NULL THEN v.km_final - v.km_inicial ELSE 0 END) as km_total
        FROM viagens v
        LEFT JOIN usuarios u ON v.tecnico_id = u.id
        WHERE " . $where['where'] . "
        GROUP BY v.tecnico_id, u.nome
        ORDER BY total_viagens DESC
        LIMIT 10", $where['params']);

    // Quilometragem por veículo
    $kmPorVeiculo = Database::queryAll("
        SELECT 
            CONCAT(ve.marca, ' ', ve.modelo, ' (', ve.placa, ')') as veiculo,
            COUNT(v.id) as total_viagens,
            SUM(CASE WHEN v.km_final IS NOT NULL THEN v.km_final - v.km_inicial ELSE 0 END) as km_total
        FROM viagens v
        LEFT JOIN veiculos ve ON v.veiculo_id = ve.id
        WHERE " . $where['where'] . "
        GROUP BY v.veiculo_id, ve.marca, ve.modelo, ve.placa
        ORDER BY km_total DESC
        LIMIT 10", $where['params']);

    return [
        'viagens_por_periodo' => $viagensPorPeriodo,
        'status_viagens' => $statusViagens,
        'top_tecnicos' => $topTecnicos,
        'km_por_veiculo' => $kmPorVeiculo
    ];
}

function obterPerformanceTecnicos(array $filtros): array {
    $where = construirWhere($filtros);
    
    return Database::queryAll("
        SELECT 
            u.nome,
            u.id as tecnico_id,
            COUNT(v.id) as total_viagens,
            COUNT(CASE WHEN v.data_fim IS NOT NULL THEN 1 END) as viagens_finalizadas,
            COUNT(CASE WHEN v.data_fim IS NULL THEN 1 END) as viagens_andamento,
            SUM(CASE WHEN v.km_final IS NOT NULL THEN v.km_final - v.km_inicial ELSE 0 END) as km_total,
            AVG(CASE WHEN v.km_final IS NOT NULL THEN v.km_final - v.km_inicial ELSE NULL END) as km_medio,
            AVG(CASE WHEN v.data_fim IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, v.data_inicio, v.data_fim) ELSE NULL END) as tempo_medio_minutos,
            ROUND((COUNT(CASE WHEN v.data_fim IS NOT NULL THEN 1 END) * 100.0 / COUNT(v.id)), 2) as taxa_finalizacao
        FROM usuarios u
        LEFT JOIN viagens v ON u.id = v.tecnico_id AND " . $where['where'] . "
        WHERE u.cargo = 'Técnico' AND u.ativo = 1
        GROUP BY u.id, u.nome
        HAVING total_viagens > 0
        ORDER BY total_viagens DESC", $where['params']);
}

function obterUtilizacaoVeiculos(array $filtros): array {
    $where = construirWhere($filtros);
    
    return Database::queryAll("
        SELECT 
            ve.id as veiculo_id,
            CONCAT(ve.marca, ' ', ve.modelo) as veiculo_nome,
            ve.placa,
            ve.tipo,
            COUNT(v.id) as total_viagens,
            SUM(CASE WHEN v.km_final IS NOT NULL THEN v.km_final - v.km_inicial ELSE 0 END) as km_total,
            AVG(CASE WHEN v.km_final IS NOT NULL THEN v.km_final - v.km_inicial ELSE NULL END) as km_medio_viagem,
            SUM(CASE WHEN v.data_fim IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, v.data_inicio, v.data_fim) ELSE 0 END) as tempo_uso_minutos,
            COUNT(DISTINCT DATE(v.data_inicio)) as dias_utilizados
        FROM veiculos ve
        LEFT JOIN viagens v ON ve.id = v.veiculo_id AND " . $where['where'] . "
        WHERE ve.status IN ('ativo', 'em_uso')
        GROUP BY ve.id, ve.marca, ve.modelo, ve.placa, ve.tipo
        HAVING total_viagens > 0
        ORDER BY total_viagens DESC", $where['params']);
} 
