<script lang="ts">
  interface ScopeValue {
    value: string;
    label: string;
  }

  interface Scope {
    id: string;
    label: string;
    description: string;
    allows_multiple: boolean;
    values: ScopeValue[];
  }

  let {
    id = '',
    value = {},
    onChange = (_v: unknown) => {},
    ariaDescribedBy = undefined,
  }: {
    id?: string;
    value?: Record<string, string[]>;
    onChange?: (v: unknown) => void;
    ariaDescribedBy?: string;
  } = $props();

  // Normalize the incoming value into a clean { scopeId: string[] } map.
  function normalize(raw: unknown): Record<string, string[]> {
    if (!raw || typeof raw !== 'object') return {};
    const out: Record<string, string[]> = {};
    for (const [key, val] of Object.entries(raw as Record<string, unknown>)) {
      if (Array.isArray(val)) {
        out[key] = val.map((v) => String(v));
      }
      else if (val !== null && val !== undefined && val !== '') {
        out[key] = [String(val)];
      }
    }
    return out;
  }

  let selected: Record<string, string[]> = $state(normalize(value));
  let scopes: Scope[] = $state([]);
  let isLoading = $state(true);
  let loadError = $state(false);

  fetchScopes();

  async function fetchScopes() {
    isLoading = true;
    loadError = false;
    try {
      const res = await fetch('/api/flowdrop/ai-context-scopes');
      if (!res.ok) throw new Error('Failed to load scopes');
      const json = await res.json();
      scopes = json.scopes ?? [];
    }
    catch {
      scopes = [];
      loadError = true;
    }
    finally {
      isLoading = false;
    }
  }

  function isChecked(scopeId: string, valueId: string): boolean {
    return (selected[scopeId] ?? []).includes(valueId);
  }

  function toggleMultiple(scopeId: string, valueId: string) {
    const current = new Set(selected[scopeId] ?? []);
    if (current.has(valueId)) {
      current.delete(valueId);
    }
    else {
      current.add(valueId);
    }
    setScopeValues(scopeId, [...current]);
  }

  function setSingle(scopeId: string, valueId: string) {
    // Selecting an already-selected single value clears it (toggle behaviour).
    if (isChecked(scopeId, valueId)) {
      setScopeValues(scopeId, []);
    }
    else {
      setScopeValues(scopeId, [valueId]);
    }
  }

  function setScopeValues(scopeId: string, values: string[]) {
    const next = { ...selected };
    if (values.length === 0) {
      delete next[scopeId];
    }
    else {
      next[scopeId] = values;
    }
    selected = next;
    onChange(next);
  }

  function clearAll() {
    selected = {};
    onChange({});
  }

  function selectedCount(): number {
    return Object.values(selected).reduce((acc, vals) => acc + vals.length, 0);
  }
</script>

<div class="fd-scope-subs" aria-describedby={ariaDescribedBy}>
  {#if isLoading}
    <div class="fd-scope-subs__loading">
      <span class="fd-scope-subs__spinner"></span>
      <span>Loading scopes…</span>
    </div>
  {:else if loadError}
    <p class="fd-scope-subs__empty">Could not load AI Context scopes.</p>
  {:else if scopes.length === 0}
    <p class="fd-scope-subs__empty">
      No subscribable scopes are enabled. Configure them in the Context Control Center.
    </p>
  {:else}
    <div class="fd-scope-subs__toolbar">
      <span class="fd-scope-subs__count">{selectedCount()} selected</span>
      {#if selectedCount() > 0}
        <button type="button" class="fd-scope-subs__clear" onclick={clearAll}>
          Clear all
        </button>
      {/if}
    </div>

    {#each scopes as scope (scope.id)}
      <fieldset class="fd-scope-subs__group">
        <legend class="fd-scope-subs__legend">{scope.label}</legend>
        {#if scope.description}
          <p class="fd-scope-subs__desc">{scope.description}</p>
        {/if}

        {#if scope.values.length === 0}
          <p class="fd-scope-subs__empty">No values available.</p>
        {:else}
          <div class="fd-scope-subs__options">
            {#each scope.values as val (val.value)}
              <label class="fd-scope-subs__option">
                <input
                  type={scope.allows_multiple ? 'checkbox' : 'radio'}
                  name={`${id}-${scope.id}`}
                  checked={isChecked(scope.id, val.value)}
                  onclick={() =>
                    scope.allows_multiple
                      ? toggleMultiple(scope.id, val.value)
                      : setSingle(scope.id, val.value)}
                />
                <span>{val.label}</span>
              </label>
            {/each}
          </div>
        {/if}
      </fieldset>
    {/each}
  {/if}
</div>

<style>
  .fd-scope-subs {
    font-family: inherit;
    font-size: 0.8125rem;
    line-height: 1.4;
  }

  .fd-scope-subs__loading {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--fd-text-muted, #667085);
    padding: 0.5rem 0;
  }

  .fd-scope-subs__spinner {
    width: 14px;
    height: 14px;
    border: 2px solid var(--fd-border-color, #d0d5dd);
    border-top-color: var(--fd-primary-color, #2563eb);
    border-radius: 50%;
    animation: fd-scope-spin 0.6s linear infinite;
    display: inline-block;
  }

  @keyframes fd-scope-spin {
    to { transform: rotate(360deg); }
  }

  .fd-scope-subs__empty {
    margin: 0.25rem 0;
    color: var(--fd-text-muted, #667085);
    font-size: 0.75rem;
  }

  .fd-scope-subs__toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.5rem;
  }

  .fd-scope-subs__count {
    font-size: 0.6875rem;
    font-weight: 500;
    color: var(--fd-text-muted, #667085);
  }

  .fd-scope-subs__clear {
    background: none;
    border: none;
    color: var(--fd-primary-color, #2563eb);
    cursor: pointer;
    font-size: 0.6875rem;
    font-weight: 500;
    padding: 0;
  }

  .fd-scope-subs__clear:hover {
    text-decoration: underline;
  }

  .fd-scope-subs__group {
    border: 1px solid var(--fd-border-color, #d0d5dd);
    border-radius: 4px;
    padding: 0.5rem;
    margin: 0 0 0.5rem;
  }

  .fd-scope-subs__legend {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--fd-text-color, #344054);
    padding: 0 0.25rem;
  }

  .fd-scope-subs__desc {
    margin: 0 0 0.375rem;
    font-size: 0.6875rem;
    color: var(--fd-text-muted, #667085);
  }

  .fd-scope-subs__options {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 0.75rem;
  }

  .fd-scope-subs__option {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    cursor: pointer;
    color: var(--fd-text-color, #344054);
  }

  .fd-scope-subs__option input {
    margin: 0;
  }
</style>
