<?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, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');

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

switch ($_SERVER['REQUEST_METHOD']) {
    case 'GET':
        $acao = $_GET['acao'] ?? 'listar';
        switch ($acao) {
            case 'listar':
                listarNotificacoes();
                break;
            case 'nao_lidas':
                listarNotificacaoesNaoLidas();
                break;
            case 'contar':
                contarNotificacaoesNaoLidas();
                break;
            default:
                Response::error('Ação não reconhecida', 400);
        }
        break;
    
    case 'POST':
        $acao = $_GET['acao'] ?? 'marcar_lida';
        switch ($acao) {
            case 'marcar_lida':
                marcarComoLida();
                break;
            case 'marcar_todas_lidas':
                marcarTodasComoLidas();
                break;
            case 'registrar_token':
                registrarTokenFCM();
                break;
            case 'enviar_teste':
                enviarNotificacaoTeste();
                break;
            default:
                Response::error('Ação não reconhecida', 400);
        }
        break;
    
    default:
        Response::error('Método não permitido', 405);
}

/**
 * Listar notificações de um usuário
 */
function listarNotificacoes(): void {
    $userId = $_GET['user_id'] ?? null;
    $limite = (int)($_GET['limite'] ?? 20);
    $offset = (int)($_GET['offset'] ?? 0);
    
    if (!$userId) {
        Response::error('ID do usuário é obrigatório', 400);
    }

    try {
        $sql = "SELECT 
                    n.*,
                    s.cliente as solicitacao_cliente,
                    s.status as solicitacao_status,
                    v.cliente as viagem_cliente
                FROM notificacoes_push n
                LEFT JOIN solicitacoes_viagem s ON n.solicitacao_id = s.id
                LEFT JOIN viagens v ON n.viagem_id = v.id
                WHERE n.user_id = ?
                ORDER BY n.created_at DESC
                LIMIT ? OFFSET ?";

        $notificacoes = Database::query($sql, [$userId, $limite, $offset]);

        Response::success([
            'notificacoes' => $notificacoes,
            'total' => count($notificacoes),
            'limite' => $limite,
            'offset' => $offset
        ]);

    } catch (Exception $e) {
        Logger::error('Erro ao listar notificações', [
            'error' => $e->getMessage(),
            'user_id' => $userId
        ]);
        Response::error('Erro ao listar notificações: ' . $e->getMessage(), 500);
    }
}

/**
 * Listar apenas notificações não lidas
 */
function listarNotificacaoesNaoLidas(): void {
    $userId = $_GET['user_id'] ?? null;
    
    if (!$userId) {
        Response::error('ID do usuário é obrigatório', 400);
    }

    try {
        // Se o user_id é um número (ID do motorista), buscar pelo motorista
        if (is_numeric($userId)) {
            $sql = "SELECT 
                        n.*,
                        s.cliente as solicitacao_cliente,
                        s.prioridade as solicitacao_prioridade,
                        s.tecnico_id as solicitacao_tecnico_id,
                        m.nome as tecnico_nome
                    FROM notificacoes_push n
                    LEFT JOIN solicitacoes_viagem s ON n.solicitacao_id = s.id
                    LEFT JOIN motoristas m ON s.tecnico_id = m.id
                    WHERE n.user_id = ? AND n.lida = FALSE
                    ORDER BY 
                        CASE 
                            WHEN n.tipo = 'solicitacao_viagem' THEN 1
                            ELSE 2
                        END,
                        n.created_at DESC";

            $notificacoes = Database::query($sql, [$userId]);
        } else {
            // Se não é numérico, retornar array vazio (usuário não existe)
            $notificacoes = [];
        }

        Response::success([
            'notificacoes_nao_lidas' => $notificacoes,
            'total_nao_lidas' => count($notificacoes)
        ]);

    } catch (Exception $e) {
        Logger::error('Erro ao listar notificações não lidas', [
            'error' => $e->getMessage(),
            'user_id' => $userId
        ]);
        Response::success([
            'notificacoes_nao_lidas' => [],
            'total_nao_lidas' => 0
        ]);
    }
}

/**
 * Contar notificações não lidas
 */
function contarNotificacaoesNaoLidas(): void {
    $userId = $_GET['user_id'] ?? null;
    
    if (!$userId) {
        Response::error('ID do usuário é obrigatório', 400);
    }

    try {
        // Se o user_id é um número (ID do motorista), buscar pelo motorista
        if (is_numeric($userId)) {
            $sql = "SELECT 
                        COUNT(*) as total_nao_lidas,
                        COUNT(CASE WHEN tipo = 'solicitacao_viagem' THEN 1 END) as solicitacoes_pendentes,
                        COUNT(CASE WHEN tipo = 'aprovacao_viagem' THEN 1 END) as aprovacoes,
                        COUNT(CASE WHEN tipo = 'negacao_viagem' THEN 1 END) as negacoes
                    FROM notificacoes_push 
                    WHERE user_id = ? AND lida = FALSE";

            $resultado = Database::queryOne($sql, [$userId]);
        } else {
            // Se não é numérico, retornar zeros
            $resultado = [
                'total_nao_lidas' => 0,
                'solicitacoes_pendentes' => 0,
                'aprovacoes' => 0,
                'negacoes' => 0
            ];
        }

        Response::success([
            'total_nao_lidas' => (int)$resultado['total_nao_lidas'],
            'solicitacoes_pendentes' => (int)$resultado['solicitacoes_pendentes'],
            'aprovacoes' => (int)$resultado['aprovacoes'],
            'negacoes' => (int)$resultado['negacoes'],
            'tem_notificacoes' => $resultado['total_nao_lidas'] > 0
        ]);

    } catch (Exception $e) {
        Logger::error('Erro ao contar notificações não lidas', [
            'error' => $e->getMessage(),
            'user_id' => $userId
        ]);
        Response::success([
            'total_nao_lidas' => 0,
            'solicitacoes_pendentes' => 0,
            'aprovacoes' => 0,
            'negacoes' => 0,
            'tem_notificacoes' => false
        ]);
    }
}

/**
 * Marcar notificação como lida
 */
function marcarComoLida(): void {
    $input = json_decode(file_get_contents('php://input'), true);
    $notificacaoId = $input['notificacao_id'] ?? null;
    $userId = $input['user_id'] ?? null;
    
    if (!$notificacaoId || !$userId) {
        Response::error('ID da notificação e do usuário são obrigatórios', 400);
    }

    try {
        $linhasAfetadas = Database::execute(
            "UPDATE notificacoes_push 
             SET lida = TRUE, updated_at = NOW() 
             WHERE id = ? AND user_id = ?",
            [$notificacaoId, $userId]
        )->rowCount();

        if ($linhasAfetadas === 0) {
            Response::error('Notificação não encontrada ou não pertence ao usuário', 404);
        }

        Logger::info('Notificação marcada como lida', [
            'notificacao_id' => $notificacaoId,
            'user_id' => $userId
        ]);

        Response::success([
            'notificacao_id' => $notificacaoId,
            'lida' => true,
            'mensagem' => 'Notificação marcada como lida'
        ]);

    } catch (Exception $e) {
        Logger::error('Erro ao marcar notificação como lida', [
            'error' => $e->getMessage(),
            'notificacao_id' => $notificacaoId,
            'user_id' => $userId
        ]);
        Response::error('Erro ao marcar como lida: ' . $e->getMessage(), 500);
    }
}

/**
 * Marcar todas as notificações como lidas
 */
function marcarTodasComoLidas(): void {
    $input = json_decode(file_get_contents('php://input'), true);
    $userId = $input['user_id'] ?? null;
    
    if (!$userId) {
        Response::error('ID do usuário é obrigatório', 400);
    }

    try {
        $resultado = Database::execute(
            "UPDATE notificacoes_push 
             SET lida = TRUE, updated_at = NOW() 
             WHERE user_id = ? AND lida = FALSE",
            [$userId]
        );

        $linhasAfetadas = $resultado->rowCount();

        Logger::info('Todas as notificações marcadas como lidas', [
            'user_id' => $userId,
            'notificacoes_atualizadas' => $linhasAfetadas
        ]);

        Response::success([
            'user_id' => $userId,
            'notificacoes_atualizadas' => $linhasAfetadas,
            'mensagem' => 'Todas as notificações foram marcadas como lidas'
        ]);

    } catch (Exception $e) {
        Logger::error('Erro ao marcar todas as notificações como lidas', [
            'error' => $e->getMessage(),
            'user_id' => $userId
        ]);
        Response::error('Erro ao marcar todas como lidas: ' . $e->getMessage(), 500);
    }
}

/**
 * Registrar token FCM do dispositivo
 */
function registrarTokenFCM(): void {
    $input = json_decode(file_get_contents('php://input'), true);
    
    $userId = $input['user_id'] ?? null;
    $token = $input['token'] ?? null;
    $deviceId = $input['device_id'] ?? null;
    $deviceName = $input['device_name'] ?? null;
    $appVersion = $input['app_version'] ?? null;
    $platform = $input['platform'] ?? 'android';
    
    if (!$userId || !$token) {
        Response::error('ID do usuário e token são obrigatórios', 400);
    }

    try {
        // Desativar tokens antigos do mesmo dispositivo
        if ($deviceId) {
            Database::execute(
                "UPDATE fcm_tokens SET ativo = FALSE 
                 WHERE user_id = ? AND device_id = ?",
                [$userId, $deviceId]
            );
        }

        // Inserir ou atualizar token
        $sql = "INSERT INTO fcm_tokens 
                (user_id, token, device_id, device_name, app_version, platform, ultimo_uso)
                VALUES (?, ?, ?, ?, ?, ?, NOW())
                ON DUPLICATE KEY UPDATE 
                device_name = VALUES(device_name),
                app_version = VALUES(app_version),
                ativo = TRUE,
                ultimo_uso = NOW()";

        Database::execute($sql, [
            $userId, $token, $deviceId, $deviceName, $appVersion, $platform
        ]);

        Logger::info('Token FCM registrado', [
            'user_id' => $userId,
            'device_id' => $deviceId,
            'platform' => $platform
        ]);

        Response::success([
            'user_id' => $userId,
            'token_registrado' => true,
            'platform' => $platform,
            'mensagem' => 'Token FCM registrado com sucesso'
        ]);

    } catch (Exception $e) {
        Logger::error('Erro ao registrar token FCM', [
            'error' => $e->getMessage(),
            'user_id' => $userId,
            'device_id' => $deviceId
        ]);
        Response::error('Erro ao registrar token: ' . $e->getMessage(), 500);
    }
}

/**
 * Enviar notificação de teste
 */
function enviarNotificacaoTeste(): void {
    $input = json_decode(file_get_contents('php://input'), true);
    
    $userId = $input['user_id'] ?? null;
    $titulo = $input['titulo'] ?? 'Notificação de Teste';
    $mensagem = $input['mensagem'] ?? 'Esta é uma notificação de teste do sistema.';
    
    if (!$userId) {
        Response::error('ID do usuário é obrigatório', 400);
    }

    try {
        // Inserir notificação no banco
        Database::execute(
            "INSERT INTO notificacoes_push 
             (user_id, tipo, titulo, mensagem) 
             VALUES (?, 'teste', ?, ?)",
            [$userId, $titulo, $mensagem]
        );

        $notificacaoId = Database::lastInsertId();

        // Buscar tokens FCM do usuário
        $tokens = Database::query(
            "SELECT token FROM fcm_tokens 
             WHERE user_id = ? AND ativo = TRUE",
            [$userId]
        );

        $tokensEnviados = 0;
        foreach ($tokens as $tokenData) {
            if (enviarNotificacaoFCM($tokenData['token'], $titulo, $mensagem)) {
                $tokensEnviados++;
            }
        }

        Logger::info('Notificação de teste enviada', [
            'notificacao_id' => $notificacaoId,
            'user_id' => $userId,
            'tokens_enviados' => $tokensEnviados
        ]);

        Response::success([
            'notificacao_id' => $notificacaoId,
            'tokens_enviados' => $tokensEnviados,
            'total_tokens' => count($tokens),
            'mensagem' => 'Notificação de teste enviada'
        ]);

    } catch (Exception $e) {
        Logger::error('Erro ao enviar notificação de teste', [
            'error' => $e->getMessage(),
            'user_id' => $userId
        ]);
        Response::error('Erro ao enviar notificação de teste: ' . $e->getMessage(), 500);
    }
}

/**
 * Enviar notificação via Firebase Cloud Messaging
 */
function enviarNotificacaoFCM(string $token, string $titulo, string $mensagem): bool {
    // Buscar chave do servidor FCM das configurações
    $fcmServerKey = Database::queryOne(
        "SELECT valor FROM configuracoes WHERE chave = 'fcm_server_key'"
    )['valor'] ?? '';

    if (empty($fcmServerKey)) {
        Logger::warning('Chave do servidor FCM não configurada');
        return false;
    }

    $data = [
        'to' => $token,
        'notification' => [
            'title' => $titulo,
            'body' => $mensagem,
            'icon' => 'ic_notification',
            'sound' => 'default',
            'click_action' => 'FLUTTER_NOTIFICATION_CLICK'
        ],
        'data' => [
            'tipo' => 'geral',
            'timestamp' => time()
        ]
    ];

    $headers = [
        'Authorization: key=' . $fcmServerKey,
        'Content-Type: application/json'
    ];

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode === 200) {
        Logger::info('Notificação FCM enviada com sucesso', [
            'token' => substr($token, -10), // Apenas últimos 10 chars por segurança
            'response' => $response
        ]);
        return true;
    } else {
        Logger::error('Falha ao enviar notificação FCM', [
            'http_code' => $httpCode,
            'response' => $response,
            'token' => substr($token, -10)
        ]);
        return false;
    }
}

?> 
