import { useQuery } from '@tanstack/react-query';
import { useClient } from 'hooks/useClient';
import { useAuth } from 'hooks/useAuth';
import { useCapabilities } from 'hooks/useCapabilities';
import { useAccessPolicy } from './useAccessPolicy';
import { useSettings } from './useSettings';
import type { ModelOption } from 'officerdev';

export type { ModelOption };

export function modelKey(m: ModelOption): string {
  return `${m.provider}:${m.id}`;
}

// Store provider names globally for display
let globalProviderNames: Record<string, string> = {};
let globalHostHome = '';

export function getProviderDisplayName(providerId: string): string {
  return globalProviderNames[providerId] || providerId;
}

export function getHostHome(): string {
  return globalHostHome;
}

export function useModels() {
  const client = useClient();
  const { isAuthenticated } = useAuth();
  // `/chat` is `kind: 'execution'` — the agent runs unsandboxed as the server owner, so it is owner-only and
  // never grantable. The model list is no use to anyone who cannot open a chat.
  const { can } = useCapabilities();

  const { data: models = [] } = useQuery<ModelOption[]>({
    queryKey: ['CHAT_MODELS'],
    enabled: isAuthenticated && can('chat'),
    queryFn: async () => {
      const data = await client.get<{
        models: ModelOption[];
        providerNames?: Record<string, string>;
        hostHome?: string;
      }>('/chat/models');

      if (data.providerNames) {
        globalProviderNames = data.providerNames;
      }

      if (data.hostHome) {
        globalHostHome = data.hostHome;
      }

      return data.models;
    },
    staleTime: 5 * 60 * 1000,
  });

  return models;
}

/** Filter models by system-wide access policy. New providers pass through. */
export function useVisibleModels() {
  const models = useModels();
  const { policy } = useAccessPolicy();
  const allowed = policy.allowedModels;

  if (allowed.length === 0) return models;

  const allowedSet = new Set(allowed);
  const allowedProviderSet = new Set(allowed.map((key) => key.split(':')[0]));

  return models.filter((m) => {
    if (m.provider === 'claude-code') return true;
    const isExplicitlyAllowed = allowedSet.has(modelKey(m));
    const isFromNewProvider = !allowedProviderSet.has(m.provider);
    return isExplicitlyAllowed || isFromNewProvider;
  });
}

/** Models visible to the owner: every model the server knows about, minus the ones they hid. */
export function useUserVisibleModels() {
  const base = useModels();
  const { settings } = useSettings();

  const hidden = settings.chat.hiddenModels;
  if (!hidden || hidden.length === 0) return base;

  const hiddenSet = new Set(hidden);
  return base.filter((m) => !hiddenSet.has(modelKey(m)));
}

/** Strict filtering — only explicitly allowed models, no "new provider" passthrough. */
export function useEnabledModels() {
  const models = useModels();
  const { policy } = useAccessPolicy();
  const allowed = policy.allowedModels;

  if (allowed.length === 0) return models;

  const allowedSet = new Set(allowed);
  return models.filter((m) => m.provider === 'claude-code' || allowedSet.has(modelKey(m)));
}
