#!/usr/bin/env python3
"""
Простой веб-сервер для панели оператора GodEye
Обслуживает WebRTC интерфейс и Socket.IO соединения
"""

import socketio
import eventlet
import eventlet.wsgi
from flask import Flask, send_file
import json
import uuid
from datetime import datetime
import os

# Создаем Flask приложение
app = Flask(__name__)

# Создаем Socket.IO сервер
sio = socketio.Server(cors_allowed_origins="*")
app.wsgi_app = socketio.WSGIApp(sio, app.wsgi_app)

# Хранилище подключенных устройств и операторов
connected_devices = {}
connected_operators = {}
active_sessions = {}

@app.route('/')
def serve_interface():
    """Обслуживает панель оператора"""
    return send_file('operator-interface.html')

@sio.event
def connect(sid, environ):
    """Обработка подключения клиента"""
    print(f"[{datetime.now().strftime('%H:%M:%S')}] 🔗 Клиент подключился: {sid}")

@sio.event
def disconnect(sid):
    """Обработка отключения клиента"""
    print(f"[{datetime.now().strftime('%H:%M:%S')}] ❌ Клиент отключился: {sid}")

    # Удаляем из устройств
    if sid in connected_devices:
        device_data = connected_devices[sid]
        del connected_devices[sid]
        sio.emit('device_disconnected', {
            'deviceId': device_data['deviceId'],
            'deviceName': device_data['deviceName']
        })
        print(f"[{datetime.now().strftime('%H:%M:%S')}] 📱 Устройство отключилось: {device_data['deviceName']}")

    # Удаляем из операторов
    if sid in connected_operators:
        del connected_operators[sid]
        print(f"[{datetime.now().strftime('%H:%M:%S')}] 👨‍💼 Оператор отключился")

@sio.event
def device_register(sid, data):
    """Регистрация Android устройства"""
    device_id = data.get('deviceId')
    device_name = data.get('deviceName', 'Unknown Device')

    connected_devices[sid] = {
        'deviceId': device_id,
        'deviceName': device_name,
        'connectedAt': datetime.now().isoformat()
    }

    print(f"[{datetime.now().strftime('%H:%M:%S')}] 📱 Устройство зарегистрировано: {device_name} ({device_id})")

    # Уведомляем всех операторов о новом устройстве
    sio.emit('device_connected', {
        'deviceId': device_id,
        'deviceName': device_name
    })

    # Отправляем подтверждение устройству
    sio.emit('registration_confirmed', {
        'status': 'success',
        'message': 'Устройство успешно зарегистрировано'
    }, room=sid)

@sio.event
def operator_register(sid, data):
    """Регистрация оператора"""
    operator_id = data.get('operatorId', f'operator_{uuid.uuid4().hex[:8]}')

    connected_operators[sid] = {
        'operatorId': operator_id,
        'connectedAt': datetime.now().isoformat()
    }

    print(f"[{datetime.now().strftime('%H:%M:%S')}] 👨‍💼 Оператор зарегистрирован: {operator_id}")

    # Отправляем список подключенных устройств
    devices_list = []
    for device_sid, device_data in connected_devices.items():
        devices_list.append({
            'deviceId': device_data['deviceId'],
            'deviceName': device_data['deviceName']
        })

    sio.emit('devices_list', {'devices': devices_list}, room=sid)

@sio.event
def request_camera(sid, data):
    """Запрос камеры от оператора"""
    device_id = data.get('deviceId')
    operator_id = data.get('operatorId')
    camera_type = data.get('cameraType', 'back')  # Убеждаемся что есть значение по умолчанию

    print(f"[{datetime.now().strftime('%H:%M:%S')}] 📹 Запрос камеры от {operator_id} для устройства {device_id}, тип камеры: {camera_type}")

    # Находим устройство по ID
    target_device_sid = None
    for device_sid, device_data in connected_devices.items():
        if device_data['deviceId'] == device_id:
            target_device_sid = device_sid
            break

    if target_device_sid:
        session_id = str(uuid.uuid4())

        # Сохраняем сессию с правильными данными
        active_sessions[session_id] = {
            'deviceSid': target_device_sid,
            'operatorSid': sid,
            'deviceId': device_id,
            'operatorId': operator_id,
            'cameraType': camera_type,  # Явно сохраняем тип камеры
            'status': 'pending',  # Добавляем статус
            'startedAt': datetime.now().isoformat()
        }

        # Отправляем запрос устройству с полными данными
        sio.emit('camera_request', {
            'sessionId': session_id,
            'operatorId': operator_id,
            'cameraType': camera_type,
            'deviceId': device_id,  # Добавляем deviceId
            'message': f'Оператор {operator_id} запрашивает доступ к камере'
        }, room=target_device_sid)

        # Уведомляем оператора о создании сессии
        sio.emit('session_created', {
            'sessionId': session_id,
            'deviceId': device_id,
            'cameraType': camera_type,
            'status': 'pending'
        }, room=sid)

        print(f"[{datetime.now().strftime('%H:%M:%S')}] 📤 Запрос отправлен устройству, сессия: {session_id}, камера: {camera_type}")
    else:
        sio.emit('error', {
            'message': f'Устройство {device_id} не найдено'
        }, room=sid)

@sio.event
def camera_approved(sid, data):
    """Подтверждение доступа к камере от устройства"""
    session_id = data.get('sessionId')

    if session_id in active_sessions:
        session = active_sessions[session_id]
        operator_sid = session['operatorSid']

        # Обновляем статус сессии
        active_sessions[session_id]['status'] = 'approved'

        print(f"[{datetime.now().strftime('%H:%M:%S')}] ✅ Доступ к камере подтвержден для сессии: {session_id}")

        # Уведомляем оператора с полными данными
        sio.emit('camera_approved', {
            'sessionId': session_id,
            'deviceId': session['deviceId'],
            'cameraType': session['cameraType'],
            'status': 'approved'
        }, room=operator_sid)

@sio.event
def camera_rejected(sid, data):
    """Отклонение доступа к камере от устройства"""
    session_id = data.get('sessionId')
    reason = data.get('reason', 'Отклонено пользователем')

    if session_id in active_sessions:
        session = active_sessions[session_id]
        operator_sid = session['operatorSid']

        print(f"[{datetime.now().strftime('%H:%M:%S')}] ❌ Доступ к камере отклонен для сессии: {session_id}, причина: {reason}")

        # Уведомляем оператора об отклонении
        sio.emit('camera_rejected', {
            'sessionId': session_id,
            'deviceId': session['deviceId'],
            'reason': reason
        }, room=operator_sid)

        # Удаляем сессию, так как она отклонена
        del active_sessions[session_id]

@sio.event
def camera_started(sid, data):
    """Уведомление о запуске камеры"""
    session_id = data.get('sessionId')

    if session_id in active_sessions:
        session = active_sessions[session_id]
        operator_sid = session['operatorSid']

        # Обновляем статус сессии на активный
        active_sessions[session_id]['status'] = 'active'
        active_sessions[session_id]['actualStartedAt'] = datetime.now().isoformat()

        print(f"[{datetime.now().strftime('%H:%M:%S')}] 📹 Камера запущена для сессии: {session_id}")

        # Уведомляем оператора с обновленным статусом
        sio.emit('camera_started', {
            'sessionId': session_id,
            'deviceId': session['deviceId'],
            'cameraType': session['cameraType'],
            'status': 'active'
        }, room=operator_sid)

        # Также отправляем обновление статуса сессии
        sio.emit('session_status_update', {
            'sessionId': session_id,
            'status': 'active',
            'cameraType': session['cameraType']
        }, room=operator_sid)

@sio.event
def webrtc_offer(sid, data):
    """Пересылка WebRTC offer от устройства к оператору"""
    session_id = data.get('sessionId')
    offer = data.get('offer')

    if session_id in active_sessions:
        session = active_sessions[session_id]
        operator_sid = session['operatorSid']

        print(f"[{datetime.now().strftime('%H:%M:%S')}] 📡 Пересылка WebRTC offer для сессии: {session_id}")

        # Пересылаем offer оператору
        sio.emit('webrtc_offer', {
            'sessionId': session_id,
            'offer': offer
        }, room=operator_sid)

@sio.event
def webrtc_answer(sid, data):
    """Пересылка WebRTC answer от оператора к устройству"""
    session_id = data.get('sessionId')
    answer = data.get('answer')

    if session_id in active_sessions:
        session = active_sessions[session_id]
        device_sid = session['deviceSid']

        print(f"[{datetime.now().strftime('%H:%M:%S')}] 📡 Пересылка WebRTC answer для сессии: {session_id}")

        # Пересылаем answer устройству
        sio.emit('webrtc_answer', {
            'sessionId': session_id,
            'answer': answer
        }, room=device_sid)

@sio.event
def webrtc_ice_candidate(sid, data):
    """Пересылка ICE candidates между устройством и оператором"""
    session_id = data.get('sessionId')
    candidate = data.get('candidate')

    if session_id in active_sessions:
        session = active_sessions[session_id]

        # Определяем куда пересылать (от устройства к оператору или наоборот)
        if sid == session['deviceSid']:
            # От устройства к оператору
            target_sid = session['operatorSid']
        else:
            # От оператора к устройству
            target_sid = session['deviceSid']

        print(f"[{datetime.now().strftime('%H:%M:%S')}] 🧊 Пересылка ICE candidate для сессии: {session_id}")

        sio.emit('webrtc_ice_candidate', {
            'sessionId': session_id,
            'candidate': candidate
        }, room=target_sid)

@sio.event
def switch_camera(sid, data):
    """Переключение камеры"""
    session_id = data.get('sessionId')

    if session_id in active_sessions:
        session = active_sessions[session_id]
        device_sid = session['deviceSid']

        print(f"[{datetime.now().strftime('%H:%M:%S')}] 🔄 Переключение камеры для сессии: {session_id}")

        # Отправляем команду устройству
        sio.emit('switch_camera', {
            'sessionId': session_id
        }, room=device_sid)

@sio.event
def stop_camera(sid, data):
    """Остановка камеры"""
    session_id = data.get('sessionId')

    if session_id in active_sessions:
        session = active_sessions[session_id]
        device_sid = session['deviceSid']
        operator_sid = session['operatorSid']

        print(f"[{datetime.now().strftime('%H:%M:%S')}] 🛑 Остановка камеры для сессии: {session_id}")

        # Отправляем команду устройству
        sio.emit('stop_camera', {
            'sessionId': session_id
        }, room=device_sid)

        # Уведомляем оператора
        sio.emit('camera_stopped', {
            'sessionId': session_id
        }, room=operator_sid)

        # Удаляем сессию
        del active_sessions[session_id]

if __name__ == '__main__':
    # ИСПРАВЛЕНО: Используем localhost для локального тестирования
    host = '0.0.0.0'  # Слушаем на всех интерфейсах
    port = 3001

    print("🚀 Запуск GodEye сервера...")
    print(f"🌐 Веб-интерфейс: http://localhost:{port}")
    print(f"🔌 Socket.IO endpoint: http://localhost:{port}/socket.io/")
    print("📱 Настройте Android приложение на адрес вашего компьютера")
    print("-" * 50)

    try:
        eventlet.wsgi.server(eventlet.listen((host, port)), app)
    except KeyboardInterrupt:
        print("\n🛑 Сервер остановлен")
    except Exception as e:
        print(f"❌ Ошибка сервера: {e}")
