import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { RestClient, type AiArtifact, type AiJobResult } from '@insignia/iios-kernel-client';

const AiContext = createContext<RestClient | null>(null);

export function AiProvider({
  serviceUrl,
  token,
  children,
}: {
  serviceUrl: string;
  token: string;
  children: React.ReactNode;
}): React.ReactElement {
  const client = useMemo(() => new RestClient({ serviceUrl, token }), [serviceUrl, token]);
  return <AiContext.Provider value={client}>{children}</AiContext.Provider>;
}

function useClient(): RestClient {
  const c = useContext(AiContext);
  if (!c) throw new Error('AI hooks must be used within <AiProvider>');
  return c;
}

/** Run an AI worker (proposal only). Returns the job + proposed artifact (or null on abstain/fail). */
export function useRunJob(): (interactionId: string, jobType: 'CLASSIFY' | 'SUMMARIZE' | 'EXTRACT') => Promise<AiJobResult> {
  const client = useClient();
  return (interactionId, jobType) => client.runAiJob({ interactionId, jobType });
}

/** List AI proposals + human accept/reject feedback. */
export function useAiProposals(opts?: { interactionId?: string; status?: string; pollMs?: number }): {
  artifacts: AiArtifact[];
  refresh: () => Promise<void>;
  accept: (id: string) => Promise<void>;
  reject: (id: string) => Promise<void>;
} {
  const client = useClient();
  const [artifacts, setArtifacts] = useState<AiArtifact[]>([]);
  const refresh = useCallback(async () => {
    try {
      setArtifacts(await client.listArtifacts({ interactionId: opts?.interactionId, status: opts?.status }));
    } catch {
      /* transient */
    }
  }, [client, opts?.interactionId, opts?.status]);
  useEffect(() => {
    void refresh();
    if (!opts?.pollMs) return;
    const t = setInterval(() => void refresh(), opts.pollMs);
    return () => clearInterval(t);
  }, [refresh, opts?.pollMs]);
  const accept = async (id: string) => {
    await client.acceptArtifact(id);
    await refresh();
  };
  const reject = async (id: string) => {
    await client.rejectArtifact(id);
    await refresh();
  };
  return { artifacts, refresh, accept, reject };
}

/** Full artifact detail (claims + evidence + model run) for explainability. */
export function useArtifact(id: string | null): { artifact: AiArtifact | null; refresh: () => Promise<void> } {
  const client = useClient();
  const [artifact, setArtifact] = useState<AiArtifact | null>(null);
  const refresh = useCallback(async () => {
    if (!id) {
      setArtifact(null);
      return;
    }
    try {
      setArtifact(await client.getArtifact(id));
    } catch {
      /* transient */
    }
  }, [client, id]);
  useEffect(() => {
    void refresh();
  }, [refresh]);
  return { artifact, refresh };
}
