<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Управление серверами</title>
    <link rel="stylesheet" href="/static/styles.css">
</head>
<body>
    <div class="container">
        <!-- Auth forms container -->
        <div id="auth-container">
            <!-- Форма входа -->
            <div id="login-form" class="form-container">
                <h2><p align="center">Вход в систему</p></h2>
                <form id="login">
                    <input type="text" id="login-username" placeholder="Имя пользователя" required>
                    <input type="password" id="login-password" placeholder="Пароль" required>
                    <button type="submit" class="btn primary">Войти</button>
                    <p>Нет аккаунта? <a href="#" id="show-register">Зарегистрироваться</a></p>
                </form>
            </div>

            <!-- Форма регистрации -->
            <div id="register-form" class="form-container hidden">
                <h2><p align="center">Регистрация</p></h2>
                <form id="register">
                    <input type="text" id="reg-username" placeholder="Имя пользователя" required>
                    <input type="password" id="reg-password" placeholder="Пароль" required>
                    <button type="submit" class="btn primary">Зарегистрироваться</button>
                    <p>Уже есть аккаунт? <a href="#" id="show-login">Войти</a></p>
                </form>
            </div>
        </div>

        <!-- User panel container -->
        <div id="main-content" class="hidden">
            <header>
                <div id="user-info">
                    <span id="username"></span>
                    <span id="balance"></span>
                </div>
                <button id="logout-btn" class="btn primary">Выйти</button>
            </header>

            <nav>
                <button class="tab-btn active" data-tab="servers">Серверы</button>
                <button class="tab-btn" data-tab="shop">Магазин</button>
                <button class="tab-btn" data-tab="support">Поддержка</button>
            </nav>

            <!-- Секция серверов -->
            <section id="servers" class="tab-content">
                <h2>Мои серверы</h2>
                <div id="servers-list" class="grid"></div>
            </section>

            <!-- Секция магазина -->
            <section id="shop" class="tab-content hidden">
                <h2>Магазин серверов</h2>
                <div class="plans-grid">
                    <div class="plan-card">
                        <h3>Базовый</h3>
                        <p>2 CPU / 4 GB RAM</p>
                        <p class="price">500 ₽/мес</p>
                        <button class="btn primary buy-server" data-plan="basic">Купить</button>
                    </div>
                    <div class="plan-card">
                        <h3>Продвинутый</h3>
                        <p>4 CPU / 8 GB RAM</p>
                        <p class="price">1000 ₽/мес</p>
                        <button class="btn primary buy-server" data-plan="advanced">Купить</button>
                    </div>
                    <div class="plan-card">
                        <h3>Премиум</h3>
                        <p>8 CPU / 16 GB RAM</p>
                        <p class="price">2000 ₽/мес</p>
                        <button class="btn primary buy-server" data-plan="premium">Купить</button>
                    </div>
                </div>
            </section>

            <!-- Секция поддержки -->
            <section id="support" class="tab-content hidden">
                <h2>Поддержка</h2>
                <div class="support-container">
                    <form id="ticket-form">
                        <input type="text" id="ticket-title" placeholder="Тема" required>
                        <textarea id="ticket-description" placeholder="Описание проблемы" required></textarea>
                        <button type="submit" class="btn primary">Отправить</button>
                    </form>
                    <div id="tickets-list"></div>
                </div>
            </section>
        </div>
    </div>
    <script src="/static/script.js"></script>
</body>
</html>



from flask import Flask, jsonify, request, render_template
from flask_cors import CORS
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity
from passlib.hash import pbkdf2_sha256
from logging.handlers import RotatingFileHandler
import json
from datetime import datetime, timedelta
import random
import logging
import string
import os
import user_agents
import traceback
from werkzeug.exceptions import BadRequest

app = Flask(__name__, static_folder='static', template_folder='templates')
CORS(app)

# JWT Configuration
app.config['JWT_SECRET_KEY'] = 'gbauy45bguyab3e4gbaehrbghbg'  # Change this in production
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(hours=1)
jwt = JWTManager(app)

OS_OPTIONS = {
    'win2020': 'Windows Server 2020',
    'win2022': 'Windows Server 2022',
    'win2025': 'Windows Server 2025',
    'win10': 'Windows 10',
    'win11': 'Windows 11'
}

@app.route('/')
def home():
    return render_template('index.html')

def setup_logging():
    # Create logs directory if it doesn't exist
    if not os.path.exists('logs'):
        os.makedirs('logs')
    
    # Configure main application logger
    formatter = logging.Formatter(
        '[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
    )
    
    # File handler for general logs
    file_handler = RotatingFileHandler(
        'logs/app.log', 
        maxBytes=1024 * 1024,  # 1MB
        backupCount=10
    )
    file_handler.setFormatter(formatter)
    file_handler.setLevel(logging.INFO)
    
    # File handler for errors
    error_file_handler = RotatingFileHandler(
        'logs/error.log',
        maxBytes=1024 * 1024,  # 1MB
        backupCount=10
    )
    error_file_handler.setFormatter(formatter)
    error_file_handler.setLevel(logging.ERROR)
    
    # Configure Flask logger
    app.logger.addHandler(file_handler)
    app.logger.addHandler(error_file_handler)
    app.logger.setLevel(logging.INFO)
    
    # Also log basic request info
    @app.before_request
    def log_request_info():
        app.logger.info(f'Request: {request.method} {request.url} from {request.remote_addr}')
        app.logger.debug(f'Headers: {dict(request.headers)}')
        
        if request.method in ['POST', 'PUT', 'PATCH']:
            if request.is_json:
                try:
                    json_body = request.get_json()
                    app.logger.debug(f'JSON Body: {json_body}')
                except BadRequest as e:
                    app.logger.warning(f'Failed to parse JSON body: {e}')
            else:
                app.logger.debug('No JSON body present in the request.')
        else:
            app.logger.debug('Request method does not contain a JSON body.')
    
    # Add error handler
    @app.errorhandler(Exception)
    def handle_exception(e):
        app.logger.error(f'Unhandled Exception: {str(e)}')
        app.logger.error(traceback.format_exc())
        return jsonify({
            'error': 'An internal server error occurred',
            'details': str(e) if app.debug else None
        }), 500

def load_db():
    try:
        if not os.path.exists('db.json'):
            app.logger.info('Creating new database file')
            with open('db.json', 'w') as f:
                json.dump({
                    'users': {},
                    'server_plans': [
                        {
                            'name': 'План 1',
                            'specs': '1 vCPU, 2 GB RAM',
                            'price': 10
                        },
                        {
                            'name': 'План 2',
                            'specs': '2 vCPU, 4 GB RAM',
                            'price': 20
                        }
                    ],
                    'logs': []  # Ensure logs array exists in initial DB structure
                }, f)
        with open('db.json', 'r') as f:
            db = json.load(f)
            # Ensure logs array exists even in existing DB files
            if 'logs' not in db:
                db['logs'] = []
                save_db(db)
            return db
    except Exception as e:
        app.logger.error(f'Database load error: {str(e)}')
        app.logger.error(traceback.format_exc())
        raise

def save_db(db):
    with open('db.json', 'w') as f:
        json.dump(db, f, indent=2)

def log_activity(username, action, user_agent_string):
    try:
        db = load_db()
        ua = user_agents.parse(user_agent_string)
        log_entry = {
            'timestamp': datetime.now().isoformat(),
            'username': username,
            'action': action,
            'browser': ua.browser.family,
            'os': ua.os.family,
            'device': ua.device.family,
            'ip': request.remote_addr
        }
        
        if 'logs' not in db:
            db['logs'] = []
            
        db['logs'].append(log_entry)
        save_db(db)
    except Exception as e:
        app.logger.error(f'Error logging activity: {str(e)}')
        app.logger.error(traceback.format_exc())

def generate_password():
    return ''.join(random.choices(string.ascii_letters + string.digits, k=12))

@app.route('/api/login', methods=['POST'])
def login():
    try:
        app.logger.info('Processing login request')
        db = load_db()
        data = request.get_json()
        
        if not data:
            app.logger.warning('No JSON data in login request')
            return jsonify({'error': 'No JSON data provided'}), 400
        
        username = data.get('username')
        password = data.get('password')
        
        app.logger.info(f'Login attempt for user: {username}')
        
        if not username or not password:
            app.logger.warning('Missing username or password in login request')
            return jsonify({'error': 'Username and password are required'}), 400
        
        user_data = db['users'].get(username)
        if not user_data:
            app.logger.warning(f'Login failed: User {username} not found')
            return jsonify({'error': 'Invalid credentials'}), 401
            
        if pbkdf2_sha256.verify(password, user_data['password']):
            app.logger.info(f'Login successful for user: {username}')
            access_token = create_access_token(identity=username)
            try:
                log_activity(username, 'login', request.headers.get('User-Agent', ''))
            except Exception as e:
                app.logger.error(f'Failed to log login activity: {str(e)}')
                # Continue with login even if logging fails
            return jsonify({
                'token': access_token,
                'username': username,
                'balance': user_data.get('balance', 0)
            })
        
        app.logger.warning(f'Login failed: Invalid password for user {username}')
        return jsonify({'error': 'Invalid credentials'}), 401
        
    except Exception as e:
        app.logger.error(f'Login error: {str(e)}')
        app.logger.error(traceback.format_exc())
        return jsonify({'error': 'An internal server error occurred'}), 500

@app.route('/api/register', methods=['POST'])
def register():
    try:
        app.logger.info('Processing registration request')
        db = load_db()
        data = request.get_json()
        
        if not data:
            app.logger.warning('No JSON data in registration request')
            return jsonify({'error': 'No JSON data provided'}), 400
        
        username = data.get('username')
        password = data.get('password')
        
        app.logger.info(f'Registration attempt for username: {username}')
        
        if not username or not password:
            app.logger.warning('Missing username or password in registration request')
            return jsonify({'error': 'Username and password are required'}), 400
        
        if username in db['users']:
            app.logger.warning(f'Registration failed: Username {username} already exists')
            return jsonify({'error': 'Username already taken'}), 400
        
        hashed_password = pbkdf2_sha256.hash(password)
        
        db['users'][username] = {
            'password': hashed_password,
            'servers': [],
            'balance': 0,
            'tickets': [],
            'created_at': datetime.now().isoformat()
        }
        
        save_db(db)
        app.logger.info(f'Registration successful for user: {username}')
        log_activity(username, 'register', request.headers.get('User-Agent', ''))
        return jsonify({'message': 'Registration successful'}), 201
        
    except Exception as e:
        app.logger.error(f'Registration error: {str(e)}')
        app.logger.error(traceback.format_exc())
        return jsonify({'error': 'An internal server error occurred'}), 500

@app.route('/api/servers', methods=['GET', 'POST'])
@jwt_required()
def servers():
    current_user = get_jwt_identity()
    db = load_db()
    
    if request.method == 'GET':
        user_data = db['users'].get(current_user)
        if not user_data:
            return jsonify({'error': 'User not found'}), 404
            
        return jsonify(user_data.get('servers', []))
    
    elif request.method == 'POST':
        data = request.get_json()
        if not data or 'plan' not in data or 'os' not in data:
            return jsonify({'error': 'Invalid request data'}), 400
            
        user_data = db['users'].get(current_user)
        
        if not user_data:
            return jsonify({'error': 'User not found'}), 404
            
        if user_data['balance'] < data['plan']['price']:
            return jsonify({'error': 'Insufficient funds'}), 400
            
        if data['os'] not in OS_OPTIONS:
            return jsonify({'error': 'Invalid operating system selected'}), 400
            
        new_server = {
            'id': len(user_data['servers']) + 1,
            'name': data.get('name', f"Server-{len(user_data['servers']) + 1}"),
            'plan': data['plan'],
            'os': OS_OPTIONS[data['os']],
            'status': 'active',
            'password': generate_password(),
            'created_at': datetime.now().isoformat(),
            'auto_renewal': True
        }
        
        user_data['balance'] -= data['plan']['price']
        user_data['servers'].append(new_server)
        save_db(db)
        log_activity(current_user, 'create_server', request.headers.get('User-Agent', ''))
        return jsonify(new_server), 201

@app.route('/api/userinfo', methods=['GET'])
@jwt_required()
def userinfo():
    try:
        current_user = get_jwt_identity()
        db = load_db()
        user_data = db['users'].get(current_user)
        if not user_data:
            return jsonify({'error': 'User not found'}), 404
        return jsonify({'username': current_user, 'balance': user_data.get('balance', 0)}), 200
    except Exception as e:
        app.logger.error(f'Userinfo error: {str(e)}')
        app.logger.error(traceback.format_exc())
        return jsonify({'error': 'An internal server error occurred'}), 500

@app.route('/api/tickets', methods=['GET', 'POST'])
@jwt_required()
def tickets():
    current_user = get_jwt_identity()
    db = load_db()
    
    if request.method == 'GET':
        user_data = db['users'].get(current_user)
        if not user_data:
            return jsonify({'error': 'User not found'}), 404
            
        return jsonify(user_data.get('tickets', []))
    
    elif request.method == 'POST':
        data = request.get_json()
        if not data or 'title' not in data:
            return jsonify({'error': 'Invalid request data'}), 400
            
        user_data = db['users'].get(current_user)
        if not user_data:
            return jsonify({'error': 'User not found'}), 404
            
        new_ticket = {
            'id': len(user_data['tickets']) + 1,
            'title': data['title'],
            'description': data.get('description', ''),
            'status': 'open',
            'created_at': datetime.now().isoformat(),
            'messages': []
        }
        
        user_data['tickets'].append(new_ticket)
        save_db(db)
        log_activity(current_user, 'create_ticket', request.headers.get('User-Agent', ''))
        return jsonify(new_ticket), 201

@app.route('/api/tickets/<int:ticket_id>/reply', methods=['POST'])
@jwt_required()
def reply_ticket(ticket_id):
    current_user = get_jwt_identity()
    db = load_db()
    
    user_data = db['users'].get(current_user)
    if not user_data:
        return jsonify({'error': 'User not found'}), 404
        
    ticket = next((t for t in user_data['tickets'] if t['id'] == ticket_id), None)
    if not ticket:
        return jsonify({'error': 'Ticket not found'}), 404
        
    data = request.get_json()
    if not data or 'message' not in data:
        return jsonify({'error': 'Message is required'}), 400
        
    message = {
        'content': data['message'],
        'sender': current_user,
        'timestamp': datetime.now().isoformat()
    }
    
    ticket['messages'].append(message)
    save_db(db)
    log_activity(current_user, f'reply_ticket_{ticket_id}', request.headers.get('User-Agent', ''))
    return jsonify(message), 201

if __name__ == '__main__':
    setup_logging()
    app.run(debug=True)



/* Основные стили */
:root {
    --primary-color: #941b31;
    --secondary-color: #bbb;
    --success-color: #46d369;
    --danger-color: #f53b57;
    --light-gray: #0a0909; /* Dark background color */
    --dark-gray: #eaeaea; /* Light text color */
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    line-height: 1.8;
    color: var(--dark-gray);
    background-color: var(--light-gray);
}

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px;
}

/* Заголовок */
header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 30px;
    padding: 20px;
    background-color: #1e1e1e;
    color: var(--dark-gray);
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
}

#user-info {
    display: flex;
    align-items: center;
    gap: 20px;
}

/* Формы */
.form-container {
    width: 800px;
    height: 370px;
    margin: 290px auto;
    padding: 70px;
    background-image: url("https://api15.iloveimg.com/v1/download/1thxyjmgs31rqAnbAm61gfgd0wp969xy0kw96mzb811s717rAs2k5089zhk5Asj0svvjhdbgvwrrnts9plw9rx99xf1qpbmlqp7zdwdzq3sbp9j384lxjcfzkwvp87yg1n0z2AcnAxls24w5mz5pqnjcp6wwt298jbvjqjcq0msmncz7pxp1");
    color: var(--dark-gray);
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
}

form {
    display: flex;
    flex-direction: column;
    gap: 15px;
}

input,
textarea {
    padding: 10px;
    background-color: #333;
    border: 2px solid #5c5c5c;
    border-radius: 12px;
    color: var(--dark-gray);
    font-size: 16px;
}

textarea {
    min-height: 100px;
    resize: vertical;
}

/* Кнопки */
.btn {
    padding: 10px 20px;
    border: none;
    border-radius: 9px;
    cursor: pointer;
    font-size: 16px;
    transition: background-color 0.3s;
}

.btn.primary {
    background-color: var(--primary-color);
    color: white;
}

.btn.primary:hover {
    background-color: #b51844;
}

/* Навигация */
nav {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
}

.tab-btn {
    padding: 10px 20px;
    background: none;
    border: none;
    cursor: pointer;
    font-size: 16px;
    color: var(--secondary-color);
    border-bottom: 2px solid transparent;
}

.tab-btn.active {
    color: var(--primary-color);
    border-bottom-color: var(--primary-color);
}

/* Сетка серверов */
.grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 20px;
    margin-top: 20px;
}

.server-card {
    background-color: #1e1e1e;
    color: var(--dark-gray);
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
}

.server-card h3 {
    margin-bottom: 10px;
}

.server-password {
    background-color: #333;
    padding: 8px;
    border-radius: 4px;
    margin-top: 10px;
    cursor: pointer;
}

.server-password.hidden-password {
    color: transparent;
    text-shadow: 0 0 8px rgba(255,255,255,0.5);
}

.server-status {
    display: inline-block;
    padding: 4px 8px;
    border-radius: 4px;
    font-size: 14px;
    margin-bottom: 10px;
    color: var(--dark-gray);
}

.status-active {
    background-color: var(--success-color);
}

.status-frozen {
    background-color: var(--danger-color);
}

/* Планы в магазине */
.plans-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 20px;
    margin-top: 20px;
}

.plan-card {
    background-color: #1e1e1e;
    color: var(--dark-gray);
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
    text-align: center;
}

.plan-card h3 {
    margin-bottom: 10px;
}

.price {
    font-size: 24px;
    font-weight: bold;
    color: var(--primary-color);
    margin: 15px 0;
}

/* Поддержка */
.support-container {
    max-width: 800px;
    margin: 0 auto;
}

.ticket-card {
    background-color: #1e1e1e;
    color: var(--dark-gray);
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
    margin-bottom: 15px;
}

.ticket-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
}

.ticket-status {
    padding: 4px 8px;
    border-radius: 4px;
    font-size: 14px;
    color: var(--dark-gray);
}

/* Notification */
.notification {
    position: fixed;
    top: 20px;
    right: 20px;
    padding: 15px 25px;
    background-color: #1e1e1e;
    color: var(--dark-gray);
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    z-index: 1000;
    transform: translateX(120%);
    transition: transform 0.3s ease-in-out;
}

.notification.show {
    transform: translateX(0);
}

.notification-content {
    display: flex;
    align-items: center;
    gap: 10px;
}

/* Animation */
@keyframes slideIn {
    from {
        transform: translateX(120%);
    }
    to {
        transform: translateX(0);
    }
}

@keyframes slideOut {
    from {
        transform: translateX(0);
    }
    to {
        transform: translateX(120%);
    }
}

.notification-slide-in {
    animation: slideIn 0.3s ease-in-out forwards;
}

.notification-slide-out {
    animation: slideOut 0.3s ease-in-out forwards;
}

.status-open {
    background-color: var(--primary-color);
}

.status-closed {
    background-color: var(--secondary-color);
}

/* Утилиты */
.hidden {
    display: none !important;
}

/* Адаптивность */
@media (max-width: 768px) {
    .container {
        padding: 10px;
    }

    header {
        flex-direction: column;
        text-align: center;
        gap: 15px;
    }

    .grid,
    .plans-grid {
        grid-template-columns: 1fr;
    }

    nav {
        flex-wrap: wrap;
    }

    .tab-btn {
        flex: 1;
        min-width: 120px;
    }
}

.error-message {
    position: fixed;
    top: 20px;
    right: 20px;
    background-color: #ff4444;
    color: white;
    padding: 15px 20px;
    border-radius: 8px;
    z-index: 1000;
    display: flex;
    align-items: center;
    gap: 10px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    animation: slideIn 0.3s ease-in-out;
}

.close-error {
    background: none;
    border: none;
    color: white;
    font-size: 20px;
    cursor: pointer;
    padding: 0 5px;
}

.password-container {
    position: relative;
    display: flex;
    align-items: center;
}

.password-toggle {
    position: absolute;
    right: 10px;
    background: none;
    border: none;
    color: var(--secondary-color);
    cursor: pointer;
}

.modal {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.7);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 1000;
}

.modal-content {
    background-color: #1e1e1e;
    padding: 20px;
    border-radius: 8px;
    width: 90%;
    max-width: 500px;
}

.form-group {
    margin-bottom: 15px;
}

.form-group label {
    display: block;
    margin-bottom: 5px;
}

.form-group select,
.form-group input {
    width: 100%;
    padding: 8px;
    border-radius: 4px;
    background-color: #333;
    border: 1px solid #444;
    color: var(--dark-gray);
}


/* Анимации */
@keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

.fade-in {
    animation: fadeIn 0.3s ease-in;
}

/* Модальные окна */
.modal {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.7);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 1000;
}

.modal-content {
    background-color: #1e1e1e;
    color: var(--dark-gray);
    padding: 20px;
    border-radius: 8px;
    max-width: 500px;
    width: 90%;
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 15px;
}

.close-modal {
    background: none;
    border: none;
    font-size: 24px;
    cursor: pointer;
    color: var(--secondary-color);
}



// Глобальные переменные
let currentUser = null;
const API_URL = '/api';

// Утилиты
const showElement = (id) => document.getElementById(id).classList.remove('hidden');
const hideElement = (id) => document.getElementById(id).classList.add('hidden');
const setActiveTab = (tabId) => {
    document.querySelectorAll('.tab-content').forEach(tab => tab.classList.add('hidden'));
    document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
    document.getElementById(tabId).classList.remove('hidden');
    document.querySelector(`[data-tab="${tabId}"]`).classList.add('active');
};

// Helper function to get auth headers
const getAuthHeaders = () => {
    const token = localStorage.getItem('authToken');
    return {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
    };
};

// Function to show errors
function showError(message) {
    const errorBox = document.getElementById('error-box');
    const errorText = document.getElementById('error-text');
    const closeBtn = document.querySelector('.close-error');

    errorText.textContent = message;
    errorBox.classList.remove('hidden');

    // Remove previous event listeners to prevent multiple triggers
    const newCloseBtn = closeBtn.cloneNode(true);
    closeBtn.parentNode.replaceChild(newCloseBtn, closeBtn);

    newCloseBtn.addEventListener('click', () => {
        errorBox.classList.add('hidden');
    });
}

// Function to logout
function logout() {
    localStorage.removeItem('authToken');
    localStorage.removeItem('username');
    localStorage.removeItem('balance');
    currentUser = null;
    updateUserInterface();
    location.reload(); // Reload the page after logout
}

// Обработчик регистрации
document.getElementById('register').addEventListener('submit', async (e) => {
    e.preventDefault();
    const username = document.getElementById('reg-username').value;
    const password = document.getElementById('reg-password').value;

    if (!username || !password) {
        showError('Пожалуйста, заполните все поля');
        return;
    }

    try {
        const response = await fetch(`${API_URL}/register`, {
            method: 'POST',
            headers: { 
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            },
            body: JSON.stringify({ username, password })
        });

        const data = await response.json();

        if (response.ok) {
            alert('Регистрация успешна! Теперь вы можете войти.');
            showElement('login-form');
            hideElement('register-form');
        } else {
            showError(data.error || 'Ошибка регистрации');
        }
    } catch (error) {
        console.error('Ошибка регистрации:', error);
        showError('Ошибка при регистрации');
    }
});

// Обработчик входа
document.getElementById('login').addEventListener('submit', async (e) => {
    e.preventDefault();
    const username = document.getElementById('login-username').value;
    const password = document.getElementById('login-password').value;

    if (!username || !password) {
        showError('Пожалуйста, заполните все поля');
        return;
    }

    try {
        const response = await fetch(`${API_URL}/login`, {
            method: 'POST',
            headers: { 
                'Content-Type': 'application/json',
                'Accept': 'application/json',
                'X-Requested-With': 'XMLHttpRequest' // Add this header
            },
            credentials: 'same-origin', // Add credentials
            body: JSON.stringify({ username, password })
        });

        if (!response.ok) {
            const data = await response.json();
            throw new Error(data.error || `HTTP error! status: ${response.status}`);
        }

        const data = await response.json();

        if (data.token) {
            // Store the token and user data in localStorage
            localStorage.setItem('authToken', data.token);
            localStorage.setItem('username', data.username);
            localStorage.setItem('balance', data.balance); // Assuming balance is a number
            currentUser = {
                username: data.username,
                balance: data.balance
            };
            updateUserInterface();
            setActiveTab('servers');
        } else {
            showError('Неверные учетные данные');
        }
    } catch (error) {
        console.error('Ошибка входа:', error);
        showError(`Ошибка при входе в систему: ${error.message}`);
    }
});

// Add a function to check if user is authenticated
function isAuthenticated() {
    return localStorage.getItem('authToken') !== null;
}

// Управление серверами
async function loadServers() {
    try {
        const response = await fetch(`${API_URL}/servers`, {
            method: 'GET',
            headers: getAuthHeaders()
        });

        if (!response.ok) {
            const errorData = await response.json();
            throw new Error(errorData.error || `HTTP error! status: ${response.status}`);
        }

        const servers = await response.json();
        displayServers(servers);
    } catch (error) {
        console.error('Ошибка загрузки серверов:', error);
        showError(error.message);
    }
}

function displayServers(servers) {
    const serversList = document.getElementById('servers-list');
    serversList.innerHTML = '';

    servers.forEach(server => {
        const serverCard = document.createElement('div');
        serverCard.className = 'server-card';
        serverCard.innerHTML = `
            <h3>${server.name}</h3>
            <span class="server-status status-${server.status}">${server.status}</span>
            <p>План: ${server.plan.name}</p>
            <p>CPU: ${server.plan.cpu} / RAM: ${server.plan.ram}GB</p>
            <div class="server-actions">
                <button class="btn primary" onclick="toggleServer(${server.id}, '${server.status}')">
                    ${server.status === 'active' ? 'Остановить' : 'Запустить'}
                </button>
                <button class="btn danger" onclick="deleteServer(${server.id})">Удалить</button>
            </div>
        `;
        serversList.appendChild(serverCard);
    });
}

// Function to toggle server status (implement this function)
async function toggleServer(serverId, currentStatus) {
    // Implementation based on your backend API
    // Example:
    // Send a POST request to toggle the server status
    // Update the server list upon success
    try {
        const response = await fetch(`${API_URL}/servers/${serverId}/toggle`, {
            method: 'POST',
            headers: getAuthHeaders()
        });

        if (!response.ok) {
            const errorData = await response.json();
            throw new Error(errorData.error || `HTTP error! status: ${response.status}`);
        }

        await loadServers();
    } catch (error) {
        console.error('Ошибка при переключении сервера:', error);
        showError(error.message);
    }
}

// Function to delete a server (implement this function)
async function deleteServer(serverId) {
    // Implementation based on your backend API
    // Example:
    // Send a DELETE request to remove the server
    // Update the server list upon success
    if (!confirm('Вы уверены, что хотите удалить этот сервер?')) return;

    try {
        const response = await fetch(`${API_URL}/servers/${serverId}`, {
            method: 'DELETE',
            headers: getAuthHeaders()
        });

        if (!response.ok) {
            const errorData = await response.json();
            throw new Error(errorData.error || `HTTP error! status: ${response.status}`);
        }

        await loadServers();
    } catch (error) {
        console.error('Ошибка при удалении сервера:', error);
        showError(error.message);
    }
}

// Обработчик отправки тикетов
document.getElementById('ticket-form').addEventListener('submit', async (e) => {
    e.preventDefault();
    const title = document.getElementById('ticket-title').value;
    const description = document.getElementById('ticket-description').value;

    if (!title || !description) {
        showError('Пожалуйста, заполните все поля');
        return;
    }

    try {
        const response = await fetch(`${API_URL}/tickets`, {
            method: 'POST',
            headers: getAuthHeaders(),
            body: JSON.stringify({
                title,
                description
            })
        });

        if (!response.ok) {
            const data = await response.json();
            throw new Error(data.error || 'Ошибка при создании тикета');
        }

        alert('Тикет успешно создан!');
        document.getElementById('ticket-form').reset();
        loadTickets();
    } catch (error) {
        console.error('Ошибка создания тикета:', error);
        showError(error.message);
    }
});

async function loadTickets() {
    try {
        const response = await fetch(`${API_URL}/tickets`, {
            method: 'GET',
            headers: getAuthHeaders()
        });

        if (!response.ok) {
            const errorData = await response.json();
            throw new Error(errorData.error || `HTTP error! status: ${response.status}`);
        }

        const tickets = await response.json();
        displayTickets(tickets);
    } catch (error) {
        console.error('Ошибка загрузки тикетов:', error);
        showError(error.message);
    }
}

function displayTickets(tickets) {
    const ticketsList = document.getElementById('tickets-list');
    ticketsList.innerHTML = '';

    tickets.forEach(ticket => {
        const ticketCard = document.createElement('div');
        ticketCard.className = 'ticket-card';
        ticketCard.innerHTML = `
            <div class="ticket-header">
                <h3>${ticket.title}</h3>
                <span class="ticket-status status-${ticket.status}">${ticket.status}</span>
            </div>
            <p>${ticket.description}</p>
            <small>Создан: ${new Date(ticket.created_at).toLocaleString()}</small>
        `;
        ticketsList.appendChild(ticketCard);
    });
}

// updateUserInterface function
function updateUserInterface() {
    const authContainer = document.getElementById('auth-container');
    const mainContent = document.getElementById('main-content');
    const usernameElement = document.getElementById('username');
    const balanceElement = document.getElementById('balance');

    if (isAuthenticated()) {
        if (!currentUser) {
            const username = localStorage.getItem('username');
            const balance = parseFloat(localStorage.getItem('balance'));

            if (username && !isNaN(balance)) {
                currentUser = {
                    username: username,
                    balance: balance
                };
            } else {
                // Optionally, fetch user info from backend (recommended)
                const token = localStorage.getItem('authToken');
                fetch(`${API_URL}/userinfo`, {
                    method: 'GET',
                    headers: getAuthHeaders()
                })
                .then(response => {
                    if (!response.ok) {
                        throw new Error('Failed to fetch user info');
                    }
                    return response.json();
                })
                .then(data => {
                    currentUser = {
                        username: data.username,
                        balance: data.balance
                    };
                    // Optionally, store these details in localStorage
                    localStorage.setItem('username', data.username);
                    localStorage.setItem('balance', data.balance);
                    // Update UI
                    authContainer?.classList.add('hidden');
                    mainContent?.classList.remove('hidden');
                    if (usernameElement) usernameElement.textContent = `Пользователь: ${currentUser.username}`;
                    if (balanceElement) balanceElement.textContent = `Баланс: ${currentUser.balance} ₽`;
                    // Load user data
                    loadServers();
                    loadTickets();
                })
                .catch(error => {
                    console.error('Failed to fetch user info:', error);
                    logout(); // Optionally, log out the user if fetching fails
                });
            }
        } else {
            authContainer?.classList.add('hidden');
            mainContent?.classList.remove('hidden');

            // Update user information in the header
            if (usernameElement) usernameElement.textContent = `Пользователь: ${currentUser.username}`;
            if (balanceElement) balanceElement.textContent = `Баланс: ${currentUser.balance} ₽`;

            // Load user data
            loadServers();
            loadTickets();
        }
    } else {
        // Show auth container and hide main content
        authContainer?.classList.remove('hidden');
        mainContent?.classList.add('hidden');
    }
}

// Обработчики переключения форм
document.getElementById('show-register').addEventListener('click', (e) => {
    e.preventDefault();
    hideElement('login-form');
    showElement('register-form');
});

document.getElementById('show-login').addEventListener('click', (e) => {
    e.preventDefault();
    hideElement('register-form');
    showElement('login-form');
});

// Обработчики вкладок
document.querySelectorAll('.tab-btn').forEach(btn => {
    btn.addEventListener('click', () => setActiveTab(btn.dataset.tab));
});

// Покупка сервера
document.querySelectorAll('.buy-server').forEach(btn => {
    btn.addEventListener('click', async () => {
        const plan = btn.dataset.plan;
        const planConfigs = {
            basic: { name: 'Базовый', cpu: 2, ram: 4, price: 500 },
            advanced: { name: 'Продвинутый', cpu: 4, ram: 8, price: 1000 },
            premium: { name: 'Премиум', cpu: 8, ram: 16, price: 2000 }
        };

        try {
            const response = await fetch(`${API_URL}/servers`, {
                method: 'POST',
                headers: getAuthHeaders(),
                body: JSON.stringify({
                    name: `Server-${Date.now()}`,
                    plan: planConfigs[plan],
                    os: 'win2022' // Example OS, adjust as needed
                })
            });

            if (!response.ok) {
                const errorData = await response.json();
                throw new Error(errorData.error || 'Ошибка при создании сервера');
            }

            const newServer = await response.json();
            alert('Сервер успешно создан!');
            loadServers();

            // Update the user balance
            currentUser.balance -= planConfigs[plan].price;
            localStorage.setItem('balance', currentUser.balance); // Update localStorage
            updateUserInterface();
        } catch (error) {
            console.error('Ошибка покупки сервера:', error);
            showError(error.message);
        }
    });
});

document.addEventListener('DOMContentLoaded', function() {
    const logoutBtn = document.getElementById('logout-btn');
    if (logoutBtn) {
        logoutBtn.addEventListener('click', logout);
    }
    updateUserInterface();
});

// Инициализация при загрузке страницы
document.addEventListener('DOMContentLoaded', updateUserInterface);



add page to view ticket and reply in it, also add notifications for all errors, not  alert window, add setting button, when user will click on it he will see page where he can change his password and username