import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
import ShireScanForgeAgentClient from '@/lib/ShireScanForgeAgentClient';
import { appConfig } from '@/lib/appConfig';
import { joinUrl } from '@/lib/httpPaths';

const ShireModuleContext = createContext(null);

function sanitiseContext(value) {
  if (!value || typeof value !== 'object') return null;
  return {
    sessionId: value.sessionId || null,
    userId: value.userId || null,
    userRole: value.userRole || null,
    deviceId: value.deviceId || null,
    apiBaseUrl: value.apiBaseUrl || appConfig.shireApiBaseUrl,
    agentId: 'scanforge',
    permissions: Array.isArray(value.permissions) ? value.permissions : [],
    accessToken: value.accessToken || null
  };
}

export function ShireModuleProvider({ children, initialContext = null }) {
  const [session, setSession] = useState(() => sanitiseContext(initialContext || window.__SHIRE_MODULE_CONTEXT__));
  const [available, setAvailable] = useState(false);
  const [connectionError, setConnectionError] = useState(null);

  useEffect(() => {
    if (appConfig.mode !== 'SHIRE_MODULE') return undefined;

    const acceptContext = (detail) => {
      const next = sanitiseContext(detail);
      if (next) setSession(next);
    };
    const onCustomEvent = (event) => acceptContext(event.detail);
    const onMessage = (event) => {
      if (event.origin !== window.location.origin) return;
      if (event.data?.type === 'SHIRE_MODULE_CONTEXT' && event.data?.agentId === 'scanforge') {
        acceptContext(event.data.context);
      }
    };

    window.addEventListener('shire:module-context', onCustomEvent);
    window.addEventListener('message', onMessage);
    if (window.parent !== window) {
      window.parent.postMessage({ type: 'SHIRE_MODULE_CONTEXT_REQUEST', agentId: 'scanforge' }, window.location.origin);
    }

    let cancelled = false;
    if (!session) {
      fetch(joinUrl(appConfig.shireApiBaseUrl, appConfig.shireModuleContextUrl), {
        credentials: 'same-origin',
        headers: { Accept: 'application/json' }
      }).then(async (response) => {
        if (!response.ok) throw new Error(`MODULE_CONTEXT_UNAVAILABLE (${response.status})`);
        const data = await response.json();
        if (!cancelled) acceptContext(data?.context || data);
      }).catch(() => {});
    }

    return () => {
      cancelled = true;
      window.removeEventListener('shire:module-context', onCustomEvent);
      window.removeEventListener('message', onMessage);
    };
  }, []);

  const getToken = () => session?.accessToken || null;
  const client = useMemo(() => new ShireScanForgeAgentClient({ apiBaseUrl: session?.apiBaseUrl || appConfig.shireApiBaseUrl, getToken }), [session]);

  useEffect(() => {
    if (appConfig.mode !== 'SHIRE_MODULE') return undefined;
    let cancelled = false;
    client.getMetadata().then(() => {
      if (!cancelled) { setAvailable(true); setConnectionError(null); }
    }).catch((error) => {
      if (!cancelled) { setAvailable(false); setConnectionError(error.message); }
    });
    return () => { cancelled = true; };
  }, [client]);

  useEffect(() => {
    if (!session) sessionStorage.removeItem('shire_scanforge_session');
  }, [session]);

  const value = {
    sessionId: session?.sessionId || null,
    userId: session?.userId || null,
    userRole: session?.userRole || null,
    deviceId: session?.deviceId || null,
    apiBaseUrl: session?.apiBaseUrl || appConfig.shireApiBaseUrl,
    agentId: 'scanforge',
    permissions: session?.permissions || [],
    available,
    connectionError,
    client
  };

  return <ShireModuleContext.Provider value={value}>{children}</ShireModuleContext.Provider>;
}

export const useShireModule = () => useContext(ShireModuleContext);
