# LovenseRemoteSDK.py
# =============================================
# A unified wrapper for Lovense Game Mode API functionalities
#
# Based on the official Lovense Standard API
# Reference: https://developer.lovense.com/docs/standard-solutions/standard-api.html
#
#  This SDK is built to simplify integration for Ren'Py developers.
# =============================================

import Toys
import Functions
import Pattern
import StopFunction
import PositionCommand
import PatternV2
import re

# ------------------------
# Utility Functions
# ------------------------

def ConvertIpToDomain(game_mode_ip, port):
    """
    Convert a local IP address to the Lovense Remote Game Mode domain format.
    
    Args:
        game_mode_ip (str): The local IP address (e.g., "192.168.1.1")
        port (int): The port number
            - 20010: Returns HTTP URL format (http://{ip}:20010)
            - 30010: Returns HTTPS URL format (https://{ip}.lovense.club:30010)
    
    Returns:
        tuple: (Formatted domain URL, Status message)
        
    Examples:
        ConvertIpToDomain("192.168.1.1", 20010) -> ("http://192.168.1.1:20010", "✅ Converted domain: http://192.168.1.1:20010")
        ConvertIpToDomain("192.168.1.1", 30010) -> ("https://192-168-1-1.lovense.club:30010", "✅ Converted domain: https://192-168-1-1.lovense.club:30010")
    """
    if not game_mode_ip:
        return None, "❌ IP address cannot be empty"

    ip = game_mode_ip.strip()

    if not re.match(r"^(\d{1,3}\.){3}\d{1,3}$", ip):
        return None, "❌ Invalid IP format (e.g. 192.168.1.1)"

    for part in ip.split('.'):
        try:
            if not 0 <= int(part) <= 255:
                raise ValueError
        except ValueError:
            return None, "❌ Each IP segment must be between 0 and 255"

    # Check port and return appropriate URL format
    if port == "20010":
        # HTTP URL format
        domain = f"http://{ip}:{port}"
        return domain, f"✅ Converted domain: {domain}"
    elif port == "30010":
        # HTTPS URL format with lovense.club domain
        domain = f"https://{ip.replace('.', '-')}.lovense.club:{port}"
        return domain, f"✅ Converted domain: {domain}"
    else:
        return None, f"❌ Unsupported port: {port}. Only ports 20010 (HTTP) and 30010 (HTTPS) are supported"

# ------------------------
# Toys Management
# ------------------------

def GetToys(domain_url):
    """
    Fetch the list of connected toys.
    
    Args:
        domain_url (str): The target domain URL.
        
    Returns:
        dict: Toys information.
    """
    return Toys.GetToys(domain_url)

# ------------------------
# Basic Functions For All Toys
# ------------------------

def SendFunctions(toy_ids, commands, time_sec, loop_running_sec=None, loop_pause_sec=None, stop_previous=None):
    """
    Send a vibration or action command to toys.
    """
    Functions.SendFunctions(toy_ids, commands, time_sec, loop_running_sec, loop_pause_sec, stop_previous)

def SendStopFunction(toy_ids):
    """
    Stop all actions currently running on the toys.
    """
    StopFunction.SendStopFunction(toy_ids)

# ------------------------
# Pattern Controls For All Toys
# ------------------------

def SendPresetPattern(toy_ids, preset_name, time_sec):
    """
    Send a predefined vibration pattern to toys.
    """
    Pattern.SendPresetPattern(toy_ids, preset_name, time_sec)

def SendPattern(toy_ids, types, strength_values, time_sec):
    """
    Send a custom pattern with strength variations.
    """
    Pattern.SendPattern(toy_ids, types, strength_values, time_sec)

# ------------------------
# Position Controls (Currently Only for Solace Pro)
# ------------------------

def SendPositionCommand(toy_ids, position):
    """
    Move the toy to a specific position.
    (Only supported by Solace Pro toys.)
    """
    return PositionCommand.SendPositionCommand(toy_ids, position)

# ------------------------
# PatternV2 Controls (Currently Only for Solace Pro)
# ------------------------

def SendPatternV2Setup(actions):
    """
    Setup a PatternV2 sequence with multiple actions.
    """
    PatternV2.SendPatternV2Setup(actions)

def SendPatternV2Play(toy_ids, start_time, offset_time):
    """
    Play the configured PatternV2 sequence.
    """
    PatternV2.SendPatternV2Play(toy_ids, start_time, offset_time)

def GetPatternV2SyncTime():
    """
    Fetch the synchronization time for PatternV2 playback.
    """
    return PatternV2.GetPatternV2SyncTime()

def StopPatternV2(toy_ids):
    """
    Stop a running PatternV2 sequence.
    """
    PatternV2.StopPatternV2(toy_ids)