import type { IConfigFlow, IConfigFlowContext, IConfigFlowStep, IDiscoveryCandidate } from '../../core/types.js';
import type { ISnapcastConfig, TSnapcastRpcTransport } from './snapcast.types.js';
import { snapcastHttpControlPort, snapcastTcpControlPort } from './snapcast.types.js';

export class SnapcastConfigFlow implements IConfigFlow<ISnapcastConfig> {
  public async start(candidateArg: IDiscoveryCandidate, contextArg: IConfigFlowContext): Promise<IConfigFlowStep<ISnapcastConfig>> {
    void contextArg;
    return {
      kind: 'form',
      title: 'Connect Snapcast Server',
      description: 'Provide the Snapserver host and JSON-RPC control port. TCP defaults to 1705; HTTP defaults to 1780.',
      fields: [
        { name: 'host', label: 'Host', type: 'text', required: true },
        { name: 'transport', label: 'JSON-RPC transport', type: 'select', required: true, options: [
          { label: 'TCP control port (1705)', value: 'tcp' },
          { label: 'HTTP /jsonrpc (1780)', value: 'http' },
          { label: 'HTTPS /jsonrpc', value: 'https' },
        ] },
        { name: 'port', label: 'Control port', type: 'number' },
      ],
      submit: async (valuesArg) => {
        const transport = this.transportValue(valuesArg.transport, candidateArg);
        const host = String(valuesArg.host || candidateArg.host || '').trim();
        const port = this.portValue(valuesArg.port, candidateArg.port, transport);
        if (!host) {
          return { kind: 'error', title: 'Snapcast setup failed', error: 'Snapcast host is required.' };
        }
        return {
          kind: 'done',
          title: 'Snapcast configured',
          config: {
            host,
            port,
            transport,
            serverId: candidateArg.id || `${host}:${port}`,
          },
        };
      },
    };
  }

  private transportValue(valueArg: unknown, candidateArg: IDiscoveryCandidate): TSnapcastRpcTransport {
    if (valueArg === 'http' || valueArg === 'https' || valueArg === 'tcp') {
      return valueArg;
    }
    const candidateTransport = candidateArg.metadata?.transport;
    if (candidateTransport === 'http' || candidateTransport === 'https' || candidateTransport === 'tcp') {
      return candidateTransport;
    }
    return candidateArg.port === snapcastHttpControlPort ? 'http' : 'tcp';
  }

  private portValue(valueArg: unknown, candidatePortArg: number | undefined, transportArg: TSnapcastRpcTransport): number {
    if (typeof valueArg === 'number' && Number.isFinite(valueArg) && valueArg > 0) {
      return Math.round(valueArg);
    }
    if (typeof valueArg === 'string' && valueArg.trim()) {
      const parsed = Number(valueArg);
      if (Number.isFinite(parsed) && parsed > 0) {
        return Math.round(parsed);
      }
    }
    return candidatePortArg || (transportArg === 'http' || transportArg === 'https' ? snapcastHttpControlPort : snapcastTcpControlPort);
  }
}
