import type { IConfigFlow, IConfigFlowContext, IConfigFlowStep, IDiscoveryCandidate } from '../../core/types.js';
import type { IJellyfinConfig } from './jellyfin.types.js';

const defaultHttpPort = 8096;
const defaultHttpsPort = 8920;
const defaultTimeoutMs = 5000;

export class JellyfinConfigFlow implements IConfigFlow<IJellyfinConfig> {
  public async start(candidateArg: IDiscoveryCandidate, contextArg: IConfigFlowContext): Promise<IConfigFlowStep<IJellyfinConfig>> {
    void contextArg;
    return {
      kind: 'form',
      title: 'Connect Jellyfin',
      description: 'Configure the local Jellyfin server endpoint. Use an access token for session polling and client control.',
      fields: [
        { name: 'url', label: 'Server URL', type: 'text', required: true },
        { name: 'accessToken', label: 'Access token or API key', type: 'password' },
        { name: 'username', label: 'Username', type: 'text' },
        { name: 'password', label: 'Password', type: 'password' },
        { name: 'name', label: 'Name', type: 'text' },
        { name: 'activeWithinSeconds', label: 'Session activity window', type: 'number' },
      ],
      submit: async (valuesArg) => ({
        kind: 'done',
        title: 'Jellyfin configured',
        config: {
          url: this.stringValue(valuesArg.url) || this.urlFromCandidate(candidateArg),
          accessToken: this.stringValue(valuesArg.accessToken),
          username: this.stringValue(valuesArg.username),
          password: this.stringValue(valuesArg.password),
          name: this.stringValue(valuesArg.name) || candidateArg.name,
          uniqueId: candidateArg.id,
          clientDeviceId: `smarthome-exchange-${candidateArg.id || candidateArg.host || 'jellyfin'}`,
          activeWithinSeconds: this.numberValue(valuesArg.activeWithinSeconds),
          timeoutMs: defaultTimeoutMs,
        },
      }),
    };
  }

  private urlFromCandidate(candidateArg: IDiscoveryCandidate): string {
    const explicitUrl = candidateArg.metadata?.url;
    if (typeof explicitUrl === 'string' && explicitUrl) {
      return explicitUrl;
    }
    const ssl = candidateArg.metadata?.ssl === true;
    const protocol = ssl ? 'https' : 'http';
    const port = candidateArg.port || (ssl ? defaultHttpsPort : defaultHttpPort);
    return candidateArg.host ? `${protocol}://${candidateArg.host}:${port}` : '';
  }

  private stringValue(valueArg: unknown): string | undefined {
    return typeof valueArg === 'string' && valueArg.trim() ? valueArg.trim() : undefined;
  }

  private numberValue(valueArg: unknown): number | undefined {
    return typeof valueArg === 'number' && Number.isFinite(valueArg) ? valueArg : undefined;
  }
}
