<?php
/**
 * Gestor de Tarjetas Usadas con MySQL
 * Sistema profesional que guarda en base de datos
 * Compatible con múltiples navegadores y sesiones
 */

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

require_once 'config.php';

// Clase para gestionar tarjetas usadas
class UsedCardsManager
{
    private $conexion;

    public function __construct()
    {
        try {
            $this->conexion = new PDO(
                "mysql:host=" . DB_HOST . ";dbname=" . getDatabaseConfig()['name'] . ";charset=utf8mb4",
                DB_USER,
                DB_PASS,
                [
                    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
                    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                    PDO::ATTR_EMULATE_PREPARES   => false
                ]
            );
        } catch (PDOException $e) {
            throw new Exception("Error de conexión: " . $e->getMessage());
        }
    }

    /**
     * Obtener todas las tarjetas usadas
     */
    public function getUsedCards($cleanup = false)
    {
        try {
            // Opcional: Limpiar registros antiguos (más de 90 días)
            if ($cleanup) {
                $cleanupQuery = "DELETE FROM used_cards WHERE date_used < DATE_SUB(NOW(), INTERVAL 90 DAY)";
                $this->conexion->exec($cleanupQuery);
            }

            $query = "SELECT * FROM used_cards ORDER BY date_used DESC";
            $stmt = $this->conexion->prepare($query);
            $stmt->execute();

            $results = $stmt->fetchAll();

            // Convertir additional_info de JSON a array
            foreach ($results as &$card) {
                if (isset($card['additional_info'])) {
                    $card['additional_info'] = json_decode($card['additional_info'], true);
                }
            }

            return $results;
        } catch (PDOException $e) {
            throw new Exception("Error al obtener tarjetas: " . $e->getMessage());
        }
    }

    /**
     * Obtener solo los IDs de tarjetas usadas
     */
    public function getUsedCardIds()
    {
        try {
            $query = "SELECT card_id FROM used_cards";
            $stmt = $this->conexion->prepare($query);
            $stmt->execute();

            return $stmt->fetchAll(PDO::FETCH_COLUMN);
        } catch (PDOException $e) {
            throw new Exception("Error al obtener IDs: " . $e->getMessage());
        }
    }

    /**
     * Marcar tarjeta como usada
     */
    public function markAsUsed($cardId, $additionalInfo = [])
    {
        try {
            // Verificar si ya existe
            $checkQuery = "SELECT id FROM used_cards WHERE card_id = ?";
            $checkStmt = $this->conexion->prepare($checkQuery);
            $checkStmt->execute([$cardId]);

            if ($checkStmt->fetch()) {
                // Ya existe, actualizar timestamp
                $updateQuery = "UPDATE used_cards SET 
                                timestamp = ?, 
                                date_used = ?,
                                ip_address = ?,
                                user_agent = ?
                                WHERE card_id = ?";
                
                $updateStmt = $this->conexion->prepare($updateQuery);
                $updateStmt->execute([
                    time(),
                    date('Y-m-d H:i:s'),
                    $_SERVER['REMOTE_ADDR'] ?? 'unknown',
                    $_SERVER['HTTP_USER_AGENT'] ?? 'unknown',
                    $cardId
                ]);

                return ['already_exists' => true, 'updated' => true];
            }

            // No existe, insertar nueva
            $insertQuery = "INSERT INTO used_cards 
                           (card_id, card_number, card_format, titular, banco, timestamp, date_used, ip_address, user_agent, additional_info)
                           VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

            $insertStmt = $this->conexion->prepare($insertQuery);
            $insertStmt->execute([
                $cardId,
                $additionalInfo['card_number'] ?? null,
                $additionalInfo['formato'] ?? null,
                $additionalInfo['titular'] ?? null,
                $additionalInfo['banco'] ?? null,
                time(),
                date('Y-m-d H:i:s'),
                $_SERVER['REMOTE_ADDR'] ?? 'unknown',
                $_SERVER['HTTP_USER_AGENT'] ?? 'unknown',
                json_encode($additionalInfo, JSON_UNESCAPED_UNICODE)
            ]);

            return ['already_exists' => false, 'inserted' => true];
        } catch (PDOException $e) {
            throw new Exception("Error al marcar como usada: " . $e->getMessage());
        }
    }

    /**
     * Eliminar una tarjeta específica del registro
     */
    public function removeCard($cardId)
    {
        try {
            $query = "DELETE FROM used_cards WHERE card_id = ?";
            $stmt = $this->conexion->prepare($query);
            $stmt->execute([$cardId]);

            return $stmt->rowCount() > 0;
        } catch (PDOException $e) {
            throw new Exception("Error al eliminar tarjeta: " . $e->getMessage());
        }
    }

    /**
     * Resetear todas las tarjetas usadas
     */
    public function resetAll()
    {
        try {
            $query = "TRUNCATE TABLE used_cards";
            $this->conexion->exec($query);
            return true;
        } catch (PDOException $e) {
            throw new Exception("Error al resetear: " . $e->getMessage());
        }
    }

    /**
     * Obtener estadísticas
     */
    public function getStats()
    {
        try {
            $stats = [];

            // Total de tarjetas usadas
            $totalQuery = "SELECT COUNT(*) as total FROM used_cards";
            $stmt = $this->conexion->prepare($totalQuery);
            $stmt->execute();
            $stats['total'] = $stmt->fetch()['total'];

            // Por banco
            $bancoQuery = "SELECT banco, COUNT(*) as count FROM used_cards 
                          WHERE banco IS NOT NULL 
                          GROUP BY banco 
                          ORDER BY count DESC 
                          LIMIT 10";
            $stmt = $this->conexion->prepare($bancoQuery);
            $stmt->execute();
            $stats['por_banco'] = $stmt->fetchAll();

            // Usadas hoy
            $hoyQuery = "SELECT COUNT(*) as count FROM used_cards 
                        WHERE DATE(date_used) = CURDATE()";
            $stmt = $this->conexion->prepare($hoyQuery);
            $stmt->execute();
            $stats['hoy'] = $stmt->fetch()['count'];

            // Usadas esta semana
            $semanaQuery = "SELECT COUNT(*) as count FROM used_cards 
                           WHERE date_used >= DATE_SUB(NOW(), INTERVAL 7 DAY)";
            $stmt = $this->conexion->prepare($semanaQuery);
            $stmt->execute();
            $stats['semana'] = $stmt->fetch()['count'];

            return $stats;
        } catch (PDOException $e) {
            throw new Exception("Error al obtener estadísticas: " . $e->getMessage());
        }
    }

    /**
     * Verificar si existe la tabla
     */
    public function checkTable()
    {
        try {
            $query = "SHOW TABLES LIKE 'used_cards'";
            $stmt = $this->conexion->prepare($query);
            $stmt->execute();
            return $stmt->rowCount() > 0;
        } catch (PDOException $e) {
            return false;
        }
    }

    /**
     * Cerrar conexión
     */
    public function close()
    {
        $this->conexion = null;
    }
}

// Procesar la petición
$method = $_SERVER['REQUEST_METHOD'];
$input = json_decode(file_get_contents('php://input'), true);

try {
    $manager = new UsedCardsManager();

    // Verificar que existe la tabla
    if (!$manager->checkTable()) {
        throw new Exception('La tabla used_cards no existe. Por favor ejecuta el script create_used_cards_table.sql');
    }

    switch ($method) {
        case 'GET':
            // Obtener todas las tarjetas usadas
            $cleanup = isset($_GET['cleanup']) && $_GET['cleanup'] === '1';
            
            if (isset($_GET['stats'])) {
                // Devolver estadísticas
                $stats = $manager->getStats();
                echo json_encode([
                    'success' => true,
                    'stats' => $stats
                ]);
            } else {
                // Devolver tarjetas
                $usedCards = $manager->getUsedCards($cleanup);
                $cardIds = $manager->getUsedCardIds();

                echo json_encode([
                    'success'       => true,
                    'used_cards'    => $cardIds,
                    'total_used'    => count($cardIds),
                    'detailed_info' => $usedCards
                ]);
            }
            break;

        case 'POST':
            // Marcar tarjeta como usada
            if (!isset($input['card_id'])) {
                throw new Exception('Card ID is required');
            }

            $cardId = $input['card_id'];
            $additionalInfo = $input['additional_info'] ?? [];

            $result = $manager->markAsUsed($cardId, $additionalInfo);
            $totalUsed = count($manager->getUsedCardIds());

            $message = $result['already_exists'] 
                ? 'La tarjeta ya estaba marcada como usada (actualizada)'
                : 'Tarjeta marcada como usada exitosamente';

            echo json_encode([
                'success'    => true,
                'message'    => $message,
                'card_id'    => $cardId,
                'total_used' => $totalUsed,
                'result'     => $result
            ]);
            break;

        case 'DELETE':
            // Resetear todas las tarjetas usadas o una específica
            if (isset($input['card_id'])) {
                // Eliminar tarjeta específica
                $cardId = $input['card_id'];
                $removed = $manager->removeCard($cardId);

                if ($removed) {
                    $totalUsed = count($manager->getUsedCardIds());
                    echo json_encode([
                        'success'    => true,
                        'message'    => 'Tarjeta eliminada del registro de usadas',
                        'card_id'    => $cardId,
                        'total_used' => $totalUsed
                    ]);
                } else {
                    throw new Exception('La tarjeta no existe en el registro');
                }
            } else {
                // Resetear todas las tarjetas
                $manager->resetAll();
                echo json_encode([
                    'success'    => true,
                    'message'    => 'Todas las tarjetas han sido reseteadas',
                    'total_used' => 0
                ]);
            }
            break;

        default:
            throw new Exception('Método no soportado');
    }

    $manager->close();

} catch (Exception $e) {
    http_response_code(400);
    echo json_encode([
        'success' => false,
        'error'   => $e->getMessage()
    ]);
}
?>
