'use strict';

(function exposeLimitProviderPresentation(root, factory) {
  const api = factory();
  if (typeof module === 'object' && module.exports) module.exports = api;
  if (root) root.TokenMonitorLimitProviderPresentation = api;
})(typeof window !== 'undefined' ? window : null, function createLimitProviderPresentationApi() {
  const SOURCE_LABELS = {
    oauth: 'OAuth',
    cli: 'CLI',
    web: 'Web',
    rpc: 'RPC',
    local: 'Local',
    api: 'API'
  };

  const PROVIDER_SOURCE_LABELS = {
    claude: { oauth: 'OAuth', cli: 'CLI' },
    codex: { rpc: 'RPC' },
    cursor: { web: 'Web' },
    antigravity: { rpc: 'RPC' },
    opencode: { local: 'Local', web: 'Web' },
    deepseek: { api: 'API' }
  };

  const CODEX_RPC_DETAIL_LABELS = {
    app: 'App',
    cli: 'CLI',
    unknown: 'RPC'
  };

  const CAPABILITY_TAGS = {
    claude: ['Auto', 'OAuth/CLI'],
    codex: ['Auto', 'App/CLI RPC'],
    cursor: ['Manual login', 'Web'],
    antigravity: ['App/CLI must be open', 'RPC'],
    opencode: ['Local/Web', 'Manual login'],
    deepseek: ['Pay-as-you-go', 'API key']
  };

  // Capability hint -> the status label it would duplicate. When that status is
  // active, the hint is suppressed so the row doesn't show two tags saying the
  // same thing (see limitProviderSettingsTags).
  const CAPABILITY_STATUS_DUPLICATES = {
    'App/CLI must be open': 'Open app or CLI'
  };

  function normalizeId(value) {
    return String(value || '').trim().toLowerCase();
  }

  function providerId(value) {
    return normalizeId(typeof value === 'object' && value ? value.provider : value);
  }

  function sourceId(value, fallback = '') {
    return normalizeId(typeof value === 'object' && value ? (value.source || fallback) : (value || fallback));
  }

  function sourceDetailId(value) {
    return normalizeId(typeof value === 'object' && value ? value.sourceDetail : '');
  }

  function deviceKey(value) {
    return String(value || '').trim().toLowerCase();
  }

  function deviceLabel(deviceOrId) {
    if (typeof deviceOrId === 'string') return deviceOrId.trim();
    const id = String(deviceOrId?.deviceId || '').trim();
    if (id) return id;
    return String(deviceOrId?.hostname || '').trim();
  }

  function statusId(provider, fallback = '') {
    return String(provider?.status || fallback).trim();
  }

  function limitProviderSourceLabel(providerOrId, sourceFallback = '') {
    const provider = providerId(providerOrId);
    const source = sourceId(providerOrId, sourceFallback);
    const sourceDetail = sourceDetailId(providerOrId);
    if (provider === 'codex' && source === 'rpc' && CODEX_RPC_DETAIL_LABELS[sourceDetail]) {
      return CODEX_RPC_DETAIL_LABELS[sourceDetail];
    }
    return PROVIDER_SOURCE_LABELS[provider]?.[source] || SOURCE_LABELS[source] || '';
  }

  function limitProviderCapabilityTags(providerOrId) {
    return (CAPABILITY_TAGS[providerId(providerOrId)] || []).slice();
  }

  function isLinkedStatus(provider) {
    const providerName = providerId(provider);
    const source = sourceId(provider);
    return providerName === 'cursor' || (providerName === 'opencode' && source === 'web');
  }

  function limitProviderStatusLabel(provider = {}) {
    const providerName = providerId(provider);
    const status = statusId(provider);

    if (provider?.stale) return { label: 'Stale', tone: 'stale' };
    if (status === 'ok') return { label: isLinkedStatus(provider) ? 'Linked' : 'Live', tone: 'ok' };
    if (status === 'disabled') return { label: 'Disabled', tone: 'muted' };
    if (status === 'noSyncedData') return { label: 'No synced data', tone: 'sync' };
    if (status === 'unauthorized') {
      return providerName === 'deepseek'
        ? { label: 'Update API key', tone: 'setup' }
        : { label: 'Sign in again', tone: 'setup' };
    }
    if (status === 'rateLimited') return { label: 'Limited', tone: 'warn' };
    if (status === 'sourceRateLimited') return { label: 'Usage API limited', tone: 'warn' };
    if (status === 'unavailable') return { label: 'Unavailable', tone: 'warn' };
    if (status === 'notConfigured') {
      if (providerName === 'antigravity') return { label: 'Open app or CLI', tone: 'setup' };
      if (providerName === 'cursor') return { label: 'Sign in', tone: 'setup' };
      if (providerName === 'deepseek') return { label: 'Add API key', tone: 'setup' };
      return { label: 'Not set up', tone: 'setup' };
    }
    return status ? { label: 'Error', tone: 'warn' } : null;
  }

  function usableProviderCandidate(provider) {
    const status = statusId(provider);
    return status !== 'disabled' && status !== 'notConfigured';
  }

  function deviceProviderCandidate(device, providerName) {
    const providers = Array.isArray(device?.limits?.providers) ? device.limits.providers : [];
    return providers.find((provider) => providerId(provider) === providerName && usableProviderCandidate(provider)) || null;
  }

  function limitProviderProvenance(providerOrId, options = {}) {
    const provider = typeof providerOrId === 'object' && providerOrId ? providerOrId : { provider: providerOrId };
    const providerName = providerId(provider);
    const localKey = deviceKey(options.localDeviceId);
    const selectedKey = deviceKey(provider?.sourceDeviceId);
    const devices = Array.isArray(options.devices) ? options.devices : [];
    const selectedDevice = devices.find((device) => deviceKey(device?.deviceId) === selectedKey) || null;
    const candidates = devices.filter((device) => deviceProviderCandidate(device, providerName));
    const localCandidate = candidates.find((device) => localKey && deviceKey(device?.deviceId) === localKey) || null;
    const remoteCandidates = candidates.filter((device) => !localKey || deviceKey(device?.deviceId) !== localKey);
    const selectedIsLocal = Boolean(selectedKey && localKey && selectedKey === localKey);
    const selectedIsRemote = Boolean(selectedKey && localKey && selectedKey !== localKey);

    return {
      syncActive: Boolean(options.syncActive),
      selectedDeviceId: selectedKey,
      selectedDeviceLabel: deviceLabel(selectedDevice) || String(provider?.sourceDeviceId || '').trim(),
      selectedIsLocal,
      selectedIsRemote,
      hasLocalCandidate: Boolean(localCandidate),
      remoteCount: remoteCandidates.length,
      candidateCount: candidates.length
    };
  }

  function limitProviderProvenanceTags(provenance) {
    if (!provenance?.syncActive) return [];
    if (provenance.selectedIsRemote && provenance.selectedDeviceLabel) {
      const tags = [{
        key: 'settings.limits.device.from',
        values: { device: provenance.selectedDeviceLabel },
        deviceLabel: provenance.selectedDeviceLabel,
        kind: 'device',
        tone: 'remote'
      }];
      if (provenance.hasLocalCandidate) {
        tags.push({ key: 'settings.limits.device.localAlso', kind: 'device', tone: 'multi' });
      }
      return tags;
    }
    if (provenance.selectedIsLocal) {
      if (provenance.remoteCount > 0) {
        return [{
          key: 'settings.limits.device.localAndSynced',
          values: { count: provenance.remoteCount },
          count: provenance.remoteCount,
          kind: 'device',
          tone: 'multi'
        }];
      }
      return [{ key: 'settings.limits.device.local', kind: 'device', tone: 'local' }];
    }
    return [];
  }

  function limitProviderMainDeviceLabel(provenance, options = {}) {
    if (!options.showSource || !provenance?.syncActive || !provenance.selectedIsRemote) return '';
    return provenance.selectedDeviceLabel || '';
  }

  function limitProviderSettingsTags(providerOrId, provenance = null) {
    const tags = [];
    const provider = typeof providerOrId === 'object' && providerOrId ? providerOrId : { provider: providerOrId };
    const status = limitProviderStatusLabel(provider);
    if (status) tags.push({ ...status, kind: 'status' });
    if (status && (provider.status === 'ok' || provider.stale)) {
      const sourceLabel = limitProviderSourceLabel(provider);
      if (sourceLabel) tags.push({ label: sourceLabel, kind: 'source' });
      tags.push(...limitProviderProvenanceTags(provenance));
      return tags;
    }
    // Some capability hints restate the active setup status (e.g. antigravity's
    // "App/CLI must be open" vs the notConfigured "Open app or CLI"). Drop the
    // hint when it would duplicate the status tag already shown.
    const statusLabel = status?.label;
    for (const label of limitProviderCapabilityTags(provider)) {
      if (CAPABILITY_STATUS_DUPLICATES[label] === statusLabel) continue;
      tags.push({ label, kind: 'capability' });
    }
    return tags;
  }

  return {
    limitProviderCapabilityTags,
    limitProviderMainDeviceLabel,
    limitProviderProvenance,
    limitProviderSourceLabel,
    limitProviderStatusLabel,
    limitProviderSettingsTags
  };
});
