/**
 * Server configuration wizard (TUI)
 */

import { Box, render, Text } from 'ink';
import TextInput from 'ink-text-input';
import React, { useEffect, useState } from 'react';
import { listLocalDevices } from '../usbip/commands.js';
import { getConfigPaths, saveServerConfig } from './manager.js';
import type { ServerConfig, ServerDeviceConfig } from './schema.js';

interface WizardState {
  step: 'address' | 'port' | 'list' | 'devices' | 'done';
  config: Partial<ServerConfig>;
  availableDevices?: Array<{
    path: string;
    vendorId: string;
    productId: string;
    description: string;
  }>;
}

function ServerConfigWizard() {
  const [state, setState] = useState<WizardState>({
    step: 'address',
    config: {
      listenAddress: '0.0.0.0',
      listenPort: 3240,
      devices: [],
    },
  });

  const [input, setInput] = useState('');

  // Load available devices when we reach the list step
  useEffect(() => {
    if (state.step === 'list') {
      listLocalDevices().then((devices) => {
        setState({
          ...state,
          availableDevices: devices,
          step: 'devices',
        });
      });
    }
  }, [state.step]);

  const handleSubmit = async (value: string) => {
    const newState = { ...state };

    switch (state.step) {
      case 'address':
        newState.config.listenAddress = value || '0.0.0.0';
        newState.step = 'port';
        break;

      case 'port':
        newState.config.listenPort = Number.parseInt(value, 10) || 3240;
        newState.step = 'list';
        break;

      case 'devices':
        if (value === 'done') {
          newState.step = 'done';
          try {
            await saveServerConfig(newState.config as ServerConfig);
            console.log(`\nConfiguration saved to ${getConfigPaths().server}`);
            process.exit(0);
          } catch (error) {
            console.error(`\nFailed to save config: ${error}`);
            process.exit(1);
          }
        } else if (value) {
          // Parse device: path or index:clientId1,clientId2
          const parts = value.split(':');
          const availableDevices = newState.availableDevices || [];

          // Check if it's an index
          const firstPart = parts[0];
          if (!firstPart) break;

          const index = Number.parseInt(firstPart, 10);
          let selectedDevice;

          if (!Number.isNaN(index) && index >= 0 && index < availableDevices.length) {
            selectedDevice = availableDevices[index];
          } else {
            // Treat as path
            selectedDevice = availableDevices.find((d) => d.path === firstPart);
          }

          if (selectedDevice) {
            const device: ServerDeviceConfig = {
              path: selectedDevice.path,
              vendorId: selectedDevice.vendorId,
              productId: selectedDevice.productId,
              description: selectedDevice.description,
              allowedClients: parts[1] ? parts[1].split(',') : [],
            };
            newState.config.devices = [...(newState.config.devices || []), device];
          }
        }
        break;
    }

    setState(newState);
    setInput('');
  };

  return (
    <Box flexDirection="column" padding={1}>
      <Text bold color="cyan">
        USB/IP Supervisor - Server Configuration
      </Text>
      <Text> </Text>

      {state.step === 'address' && (
        <>
          <Text>Listen Address (default: 0.0.0.0):</Text>
          <TextInput value={input} onChange={setInput} onSubmit={handleSubmit} />
        </>
      )}

      {state.step === 'port' && (
        <>
          <Text>Listen Port (default: 3240):</Text>
          <TextInput value={input} onChange={setInput} onSubmit={handleSubmit} />
        </>
      )}

      {state.step === 'list' && (
        <>
          <Text color="yellow">Loading available USB devices...</Text>
        </>
      )}

      {state.step === 'devices' && (
        <>
          <Text bold>Available USB devices:</Text>
          <Text dimColor>Select by index number and optionally specify allowed clients</Text>
          <Text> </Text>
          {state.availableDevices?.map((d, i) => (
            <Text key={d.path}>
              [{i}] {d.vendorId}:{d.productId} - {d.description}
              <Text dimColor> ({d.path})</Text>
            </Text>
          )) || <Text color="red">No devices found</Text>}
          <Text> </Text>
          <Text dimColor>Format: index[:clientId1,clientId2]</Text>
          <Text dimColor>Example: 0:client1,client2 (or just 0 for all clients)</Text>
          <Text dimColor>Type 'done' when finished</Text>
          <Text> </Text>
          {state.config.devices && state.config.devices.length > 0 && (
            <>
              <Text color="green">Configured devices:</Text>
              {state.config.devices.map((d) => (
                <Text key={d.path}>
                  - {d.vendorId}:{d.productId} - {d.description}
                  {d.allowedClients.length > 0 && ` (clients: ${d.allowedClients.join(', ')})`}
                </Text>
              ))}
              <Text> </Text>
            </>
          )}
          <TextInput value={input} onChange={setInput} onSubmit={handleSubmit} />
        </>
      )}
    </Box>
  );
}

export async function runServerConfigWizard(): Promise<void> {
  render(<ServerConfigWizard />);
}
