<script lang="ts">
    import { robotManager } from "$lib/robot/RobotManager.svelte";
    import { robotUrdfConfigMap } from "$lib/configs/robotUrdfConfig";
    import type { Robot } from "$lib/robot/Robot.svelte";

    interface Props {}
    
    let {}: Props = $props();
    
    // Local state
    let selectedRobotType = $state("so-arm100");
    let isCreating = $state(false);
    let error = $state<string | undefined>(undefined);

    // Robot selection modal state
    let showRobotSelectionModal = $state(false);
    let availableServerRobots = $state<{ id: string; name: string; robot_type: string }[]>([]);
    let selectedServerRobotId = $state<string>("");
    let pendingLocalRobot: Robot | null = $state(null);

    // Reactive values
    const robots = $derived(robotManager.robots);
    const robotsWithSlaves = $derived(robotManager.robotsWithSlaves.length);
    const robotsWithMaster = $derived(robotManager.robotsWithMaster.length);

    async function createRobot() {
        if (isCreating) return;
        
        console.log('Creating robot...');
        isCreating = true;
        error = undefined;
        
        try {
            const urdfConfig = robotUrdfConfigMap[selectedRobotType];
            if (!urdfConfig) {
                throw new Error(`Unknown robot type: ${selectedRobotType}`);
            }
            
            const robotId = `robot-${Date.now()}`;
            console.log('Creating robot with ID:', robotId, 'and config:', urdfConfig);
            const robot = await robotManager.createRobot(robotId, urdfConfig);
            console.log('Robot created successfully:', robot);
            
        } catch (err) {
            error = `Failed to create robot: ${err}`;
            console.error('Robot creation failed:', err);
        } finally {
            isCreating = false;
        }
    }

    // Master connection functions
    async function connectMockSequenceMaster(robot: Robot) {
        try {
            await robotManager.connectDemoSequences(robot.id, true);
        } catch (err) {
            error = `Failed to connect demo sequences: ${err}`;
            console.error(err);
        }
    }

    async function connectRemoteServerMaster(robot: Robot) {
        try {
            const config: import('$lib/types/robotDriver').MasterDriverConfig = {
                type: "remote-server",
                url: "ws://localhost:8080",
                apiKey: undefined,
                pollInterval: 100
            };
            await robotManager.connectMaster(robot.id, config);
        } catch (err) {
            error = `Failed to connect remote server: ${err}`;
            console.error(err);
        }
    }

    async function disconnectMaster(robot: Robot) {
        try {
            await robotManager.disconnectMaster(robot.id);
        } catch (err) {
            error = `Failed to disconnect master: ${err}`;
            console.error(err);
        }
    }

    // Slave connection functions
    async function connectMockSlave(robot: Robot) {
        try {
            await robotManager.connectMockSlave(robot.id, 50);
        } catch (err) {
            error = `Failed to connect mock slave: ${err}`;
            console.error(err);
        }
    }

    async function connectUSBSlave(robot: Robot) {
        try {
            await robotManager.connectUSBSlave(robot.id);
        } catch (err) {
            error = `Failed to connect USB slave: ${err}`;
            console.error(err);
        }
    }

    async function connectRemoteServerSlave(robot: Robot) {
        try {
            // First, fetch available robots from the server
            const serverUrl = "http://localhost:8080";
            const response = await fetch(`${serverUrl}/api/robots`);
            
            if (!response.ok) {
                throw new Error(`Server responded with ${response.status}: ${response.statusText}`);
            }
            
            const robots = await response.json();
            
            if (robots.length === 0) {
                error = "No robots available on the server. Create a robot on the server first.";
                return;
            }
            
            // Show modal for robot selection
            availableServerRobots = robots;
            pendingLocalRobot = robot;
            selectedServerRobotId = robots[0]?.id || "";
            showRobotSelectionModal = true;
            
        } catch (err) {
            error = `Failed to fetch server robots: ${err}`;
            console.error(err);
        }
    }

    async function confirmRobotSelection() {
        if (!pendingLocalRobot || !selectedServerRobotId) return;
        
        try {
            await robotManager.connectRemoteServerSlave(
                pendingLocalRobot.id, 
                "ws://localhost:8080", 
                undefined, 
                selectedServerRobotId
            );
            
            // Close modal
            showRobotSelectionModal = false;
            pendingLocalRobot = null;
            
        } catch (err) {
            error = `Failed to connect remote server slave: ${err}`;
            console.error(err);
        }
    }

    function cancelRobotSelection() {
        showRobotSelectionModal = false;
        pendingLocalRobot = null;
        selectedServerRobotId = "";
    }

    async function disconnectSlave(robot: Robot, slaveId: string) {
        try {
            await robotManager.disconnectSlave(robot.id, slaveId);
        } catch (err) {
            error = `Failed to disconnect slave: ${err}`;
            console.error(err);
        }
    }

    // Robot management
    async function calibrateRobot(robot: Robot) {
        try {
            await robot.calibrateRobot();
        } catch (err) {
            error = `Failed to calibrate: ${err}`;
            console.error(err);
        }
    }

    async function moveToRest(robot: Robot) {
        try {
            await robot.moveToRestPosition();
        } catch (err) {
            error = `Failed to move to rest: ${err}`;
            console.error(err);
        }
    }

    function clearCalibration(robot: Robot) {
        robot.clearCalibration();
    }

    async function removeRobot(robot: Robot) {
        try {
            await robotManager.removeRobot(robot.id);
        } catch (err) {
            error = `Failed to remove robot: ${err}`;
            console.error(err);
        }
    }

    function clearError() {
        error = undefined;
    }

    // Helper functions
    function getConnectionStatusText(robot: Robot): string {
        const hasActiveMaster = robot.controlState.hasActiveMaster;
        const connectedSlaves = robot.connectedSlaves.length;
        const totalSlaves = robot.slaves.length;
        
        if (hasActiveMaster && connectedSlaves > 0) {
            return `Master + ${connectedSlaves}/${totalSlaves} Slaves`;
        } else if (hasActiveMaster) {
            return `Master Only`;
        } else if (connectedSlaves > 0) {
            return `${connectedSlaves}/${totalSlaves} Slaves`;
        } else {
            return "Manual Control";
        }
    }

    function getConnectionStatusColor(robot: Robot): string {
        const hasActiveMaster = robot.controlState.hasActiveMaster;
        const connectedSlaves = robot.connectedSlaves.length;
        
        if (hasActiveMaster && connectedSlaves > 0) {
            return "green";  // Full master-slave setup
        } else if (hasActiveMaster || connectedSlaves > 0) {
            return "yellow"; // Partial connection
        } else {
            return "red";    // No connections
        }
    }

    async function connectUSBMaster(robot: Robot) {
        try {
            await robotManager.connectUSBMaster(robot.id, {
                pollInterval: 200,
                smoothing: true
            });
        } catch (err) {
            error = `Failed to connect USB master: ${err}`;
            console.error(err);
        }
    }
</script>

<div class="space-y-6 p-4">
    <div class="flex items-center justify-between">
        <h2 class="text-xl font-bold text-slate-100">Robot Control - Master/Slave Architecture</h2>
        <div class="text-sm text-slate-400">
            {robots.length} robots, {robotsWithMaster} with masters, {robotsWithSlaves} with slaves
        </div>
    </div>

    <!-- Error Display -->
    {#if error}
        <div class="bg-red-500/20 border border-red-500 rounded-lg p-3 flex items-center justify-between">
            <span class="text-red-200 text-sm">{error}</span>
            <button 
                onclick={clearError}
                class="text-red-200 hover:text-white"
            >×</button>
        </div>
    {/if}

    <!-- Create Robot Section -->
    <div class="bg-slate-800 rounded-lg p-4 space-y-4">
        <h3 class="text-lg font-semibold text-slate-100">Create Robot</h3>
        
        <div class="flex gap-3">
            <select 
                bind:value={selectedRobotType}
                class="flex-1 px-3 py-2 bg-slate-700 border border-slate-600 rounded-md text-slate-100"
            >
                {#each Object.keys(robotUrdfConfigMap) as robotType}
                    <option value={robotType}>{robotType}</option>
                {/each}
            </select>
            
            <button 
                onclick={createRobot}
                disabled={isCreating}
                class="px-4 py-2 bg-blue-600 hover:bg-blue-700 disabled:bg-slate-600 disabled:cursor-not-allowed text-white rounded-md transition-colors"
            >
                {isCreating ? "Creating..." : "Create Robot"}
            </button>
        </div>
    </div>

    <!-- Robots List -->
    <div class="space-y-3">
        {#each robots as robot (robot.id)}
            <div class="bg-slate-800 rounded-lg p-4">
                <div class="flex items-center justify-between mb-3">
                    <div>
                        <h4 class="font-semibold text-slate-100">{robot.id}</h4>
                        <div class="text-sm text-slate-400">
                            Status: 
                            <span class="text-{getConnectionStatusColor(robot)}-400">
                                {getConnectionStatusText(robot)}
                            </span>
                            {#if robot.controlState.lastCommandSource !== "none"}
                                <span class="text-blue-400 ml-2">• Last: {robot.controlState.lastCommandSource}</span>
                            {/if}
                            {#if robot.isCalibrated}
                                <span class="text-green-400 ml-2">• Calibrated</span>
                            {/if}
                        </div>
                    </div>
                    
                    <button 
                        onclick={() => removeRobot(robot)}
                        class="px-3 py-1 bg-red-600 hover:bg-red-700 text-white text-sm rounded transition-colors"
                    >
                        Remove
                    </button>
                </div>

                <!-- Master Controls -->
                <div class="mb-4 p-3 bg-orange-500/10 border border-orange-500/30 rounded-lg">
                    <div class="text-sm text-orange-200 mb-2">
                        <strong>Masters (Control Sources)</strong>
                        {#if robot.controlState.hasActiveMaster}
                            - <span class="text-green-400">Connected: {robot.controlState.masterName}</span>
                        {:else}
                            - <span class="text-slate-400">None Connected</span>
                        {/if}
                    </div>
                    
                    <div class="flex flex-wrap gap-2">
                        <button
                            class="px-3 py-1.5 bg-orange-500 text-white rounded text-sm hover:bg-orange-600 transition-colors disabled:bg-slate-600 disabled:cursor-not-allowed"
                            onclick={() => connectMockSequenceMaster(robot)}
                            disabled={robot.controlState.hasActiveMaster}
                        >
                            Demo Sequences
                        </button>
                        
                        <button
                            class="px-3 py-1.5 bg-purple-500 text-white rounded text-sm hover:bg-purple-600 transition-colors disabled:bg-slate-600 disabled:cursor-not-allowed"
                            onclick={() => connectRemoteServerMaster(robot)}
                            disabled={robot.controlState.hasActiveMaster}
                        >
                            Connect Remote Server
                        </button>

                        <button
                            class="px-3 py-1.5 bg-blue-500 text-white rounded text-sm hover:bg-blue-600 transition-colors disabled:bg-slate-600 disabled:cursor-not-allowed"
                            onclick={() => connectUSBMaster(robot)}
                            disabled={robot.controlState.hasActiveMaster}
                        >
                            Connect USB Master
                        </button>
                        
                        {#if robot.controlState.hasActiveMaster}
                            <button
                                class="px-3 py-1.5 bg-red-500 text-white rounded text-sm hover:bg-red-600 transition-colors"
                                onclick={() => disconnectMaster(robot)}
                            >
                                Disconnect Master
                            </button>
                        {/if}
                    </div>
                </div>

                <!-- Slave Controls -->
                <div class="mb-4 p-3 bg-blue-500/10 border border-blue-500/30 rounded-lg">
                    <div class="text-sm text-blue-200 mb-2">
                        <strong>Slaves (Execution Targets)</strong>
                        - <span class="text-green-400">{robot.connectedSlaves.length} Connected</span>
                        / <span class="text-slate-400">{robot.slaves.length} Total</span>
                    </div>
                    
                    <div class="flex gap-2 mb-2">
                        <button 
                            onclick={() => connectMockSlave(robot)}
                            class="px-3 py-1 bg-yellow-600 hover:bg-yellow-700 text-white text-sm rounded transition-colors"
                        >
                            Add Mock Slave
                        </button>
                        <button 
                            onclick={() => connectUSBSlave(robot)}
                            class="px-3 py-1 bg-green-600 hover:bg-green-700 text-white text-sm rounded transition-colors"
                        >
                            Add USB Slave
                        </button>
                        <button 
                            onclick={() => connectRemoteServerSlave(robot)}
                            class="px-3 py-1 bg-purple-600 hover:bg-purple-700 text-white text-sm rounded transition-colors"
                        >
                            Add Remote Server Slave
                        </button>
                    </div>
                    
                    {#if robot.slaves.length > 0}
                        <div class="text-xs text-blue-300">
                            <strong>Connected Slaves:</strong>
                            {#each robot.slaves as slave}
                                <div class="flex items-center justify-between mt-1">
                                    <span>{slave.name} ({slave.id})</span>
                                    <button 
                                        onclick={() => disconnectSlave(robot, slave.id)}
                                        class="px-2 py-1 bg-red-500 hover:bg-red-600 text-white text-xs rounded"
                                    >
                                        Remove
                                    </button>
                                </div>
                            {/each}
                        </div>
                    {/if}
                </div>

                <!-- Calibration Section (for USB slaves) -->
                {#if robot.connectedSlaves.some(slave => slave.name.includes("USB"))}
                    <div class="mb-3 p-3 bg-orange-500/10 border border-orange-500/30 rounded-lg">
                        <div class="text-sm text-orange-200 mb-2">
                            <strong>USB Robot Calibration</strong>
                        </div>
                        {#if !robot.isCalibrated}
                            <div class="text-xs text-orange-300 mb-2">
                                1. Manually position your robot to match the digital twin's rest pose<br>
                                2. Click "Calibrate" when positioned correctly
                            </div>
                            <div class="flex gap-2">
                                <button 
                                    onclick={() => moveToRest(robot)}
                                    class="px-3 py-1 bg-blue-600 hover:bg-blue-700 text-white text-sm rounded transition-colors"
                                >
                                    Show Rest Pose
                                </button>
                                <button 
                                    onclick={() => calibrateRobot(robot)}
                                    class="px-3 py-1 bg-green-600 hover:bg-green-700 text-white text-sm rounded transition-colors"
                                >
                                    Calibrate
                                </button>
                            </div>
                        {:else}
                            <div class="text-xs text-green-300 mb-2">
                                ✓ Robot calibrated at {robot.calibrationState.calibrationTime?.toLocaleTimeString()}
                            </div>
                            <button 
                                onclick={() => clearCalibration(robot)}
                                class="px-3 py-1 bg-gray-600 hover:bg-gray-700 text-white text-sm rounded transition-colors"
                            >
                                Clear Calibration
                            </button>
                        {/if}
                    </div>
                {/if}

                <!-- Manual Joint Controls (only when no master) -->
                {#if robot.manualControlEnabled}
                    <div class="space-y-3">
                        <h5 class="text-sm font-medium text-slate-300">Manual Control ({robot.activeJoints.length} active joints)</h5>
                        {#each robot.activeJoints as joint}
                            <div class="joint-control">
                                <div class="joint-header">
                                    <span class="joint-name">{joint.name}</span>
                                    <div class="joint-values">
                                        <span class="virtual-value">{joint.virtualValue.toFixed(0)}°</span>
                                        {#if joint.realValue !== undefined}
                                            <span class="real-value" title="Real robot position">
                                                Real: {joint.realValue.toFixed(0)}°
                                            </span>
                                        {:else}
                                            <span class="real-value disconnected">N/A</span>
                                        {/if}
                                    </div>
                                </div>
                                <input 
                                    type="range"
                                    min="-180"
                                    max="180"
                                    step="1"
                                    value={joint.virtualValue}
                                    oninput={(e) => {
                                        const target = e.target as HTMLInputElement;
                                        robot.updateJointValue(joint.name, parseFloat(target.value));
                                    }}
                                    class="joint-slider"
                                />
                            </div>
                        {/each}
                        
                        {#if robot.activeJoints.length === 0}
                            <div class="text-sm text-slate-500 italic">No active joints</div>
                        {/if}
                    </div>
                {:else}
                    <div class="p-3 bg-purple-500/10 border border-purple-500/30 rounded-lg">
                        <div class="text-sm text-purple-200">
                            🎮 <strong>Master Control Active</strong><br>
                            <span class="text-xs text-purple-300">
                                Robot is controlled by: {robot.controlState.masterName}<br>
                                Manual controls are disabled. Disconnect master to regain manual control.
                            </span>
                        </div>
                    </div>
                {/if}
            </div>
        {/each}
        
        {#if robots.length === 0}
            <div class="text-center text-slate-500 py-8">
                No robots created yet. Create one above to get started with the master-slave architecture.
            </div>
        {/if}
    </div>
</div>

<!-- Robot Selection Modal -->
{#if showRobotSelectionModal}
    <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
        <div class="bg-slate-800 rounded-lg p-6 w-96 max-w-full mx-4">
            <h3 class="text-lg font-semibold text-slate-100 mb-4">Select Server Robot</h3>
            
            <div class="mb-4">
                <label class="block text-sm font-medium text-slate-300 mb-2">
                    Available robots on server:
                </label>
                <select 
                    bind:value={selectedServerRobotId}
                    class="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-md text-slate-100"
                >
                    {#each availableServerRobots as serverRobot}
                        <option value={serverRobot.id}>
                            {serverRobot.name} ({serverRobot.id}) - {serverRobot.robot_type}
                        </option>
                    {/each}
                </select>
            </div>
            
            <div class="text-sm text-slate-400 mb-4">
                This will connect your local robot "{pendingLocalRobot?.id}" as a slave to 
                receive commands from the selected server robot.
            </div>
            
            <div class="flex gap-3 justify-end">
                <button 
                    onclick={cancelRobotSelection}
                    class="px-4 py-2 bg-slate-600 hover:bg-slate-700 text-white rounded-md transition-colors"
                >
                    Cancel
                </button>
                <button 
                    onclick={confirmRobotSelection}
                    class="px-4 py-2 bg-purple-600 hover:bg-purple-700 text-white rounded-md transition-colors"
                    disabled={!selectedServerRobotId}
                >
                    Connect Slave
                </button>
            </div>
        </div>
    </div>
{/if}

<style>
    .joint-control {
        background: rgba(71, 85, 105, 0.3);
        border-radius: 8px;
        padding: 12px;
        border: 1px solid rgba(71, 85, 105, 0.5);
    }

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

    .joint-name {
        font-weight: 500;
        color: #e2e8f0;
        font-size: 14px;
    }

    .joint-values {
        display: flex;
        gap: 12px;
        font-size: 12px;
    }

    .virtual-value {
        color: #60a5fa;
        font-weight: 500;
    }

    .real-value {
        color: #34d399;
        font-weight: 500;
    }

    .real-value.disconnected {
        color: #f87171;
    }

    .joint-slider {
        width: 100%;
        height: 6px;
        background: #374151;
        border-radius: 3px;
        outline: none;
        cursor: pointer;
        appearance: none;
    }

    .joint-slider::-webkit-slider-thumb {
        appearance: none;
        width: 18px;
        height: 18px;
        border-radius: 50%;
        background: #3b82f6;
        cursor: pointer;
        border: 2px solid #1e293b;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
        transition: all 0.15s ease;
    }

    .joint-slider::-webkit-slider-thumb:hover {
        background: #2563eb;
        transform: scale(1.1);
    }

    .joint-slider::-moz-range-thumb {
        width: 18px;
        height: 18px;
        border-radius: 50%;
        background: #3b82f6;
        cursor: pointer;
        border: 2px solid #1e293b;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
        transition: all 0.15s ease;
    }

    .joint-slider::-moz-range-track {
        height: 6px;
        background: #374151;
        border-radius: 3px;
        border: none;
    }

    .joint-slider:focus {
        box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5);
    }
</style> 