import { h } from 'preact';
import { useEffect, useState } from 'preact/hooks';
import { registerImageProvider } from './core/image-providers';
import type { AsukaModuleComponent } from './core/modules';
import { getI18n } from './core/i18n';
import { UploadImagePanel } from './components/modules/UploadImageModule';
import { QRCodePanel } from './components/modules/QRCodeImageModule';

type ProviderModule = Record<string, unknown> & { default?: AsukaModuleComponent };
type ProviderPanelLoader = () => Promise<ProviderModule>;
type ProviderPanelResolver = (mod: ProviderModule) => AsukaModuleComponent | undefined;

function createLazyProviderPanel(
  label: string,
  loader: ProviderPanelLoader,
  resolve: ProviderPanelResolver,
): AsukaModuleComponent {
  let cachedPanel: AsukaModuleComponent | null = null;
  let pendingLoad: Promise<AsukaModuleComponent> | null = null;

  const loadPanel = async (): Promise<AsukaModuleComponent> => {
    if (cachedPanel) return cachedPanel;
    if (!pendingLoad) {
      pendingLoad = loader().then((mod) => {
        const panel = resolve(mod);
        if (!panel) throw new Error(`[AsukaDesigner] ${label} provider panel could not be resolved.`);
        cachedPanel = panel;
        return panel;
      }).catch((error) => {
        pendingLoad = null;
        throw error;
      });
    }
    return pendingLoad;
  };

  const LazyProviderPanel: AsukaModuleComponent = (props) => {
    const [Panel, setPanel] = useState<AsukaModuleComponent | null>(() => cachedPanel);
    const [error, setError] = useState<string | null>(null);

    useEffect(() => {
      let mounted = true;
      loadPanel()
        .then((panel) => {
          if (!mounted) return;
          setPanel(() => panel);
          setError(null);
        })
        .catch((err) => {
          if (!mounted) return;
          setError(err instanceof Error ? err.message : String(err ?? 'Unknown error'));
        });
      return () => {
        mounted = false;
      };
    }, []);

    if (Panel) return h(Panel as any, props as any);

    const i18n = getI18n();
    return h(
      'div',
      {
        className: 'ask-rounded-xl ask-border ask-border-borderSubtle ask-bg-surfaceAlt ask-p-3 ask-text-[12px] ask-text-textMuted',
      },
      error
        ? `${i18n.t('common.error', 'Error')}: ${error}`
        : `${i18n.t('common.loading', 'Loading')} ${label}…`,
    );
  };

  return LazyProviderPanel;
}

const AiTextToImageProviderPanel = createLazyProviderPanel(
  'AI image',
  () => import('./components/modules/AiTextToImageModule'),
  (mod) => (mod.AiTextToImagePanel as AsukaModuleComponent | undefined) ?? mod.default,
);

let registered = false;

export function registerCoreImageProviders(): void {
  if (registered) return;
  registered = true;

  registerImageProvider({
    id: 'upload',
    label: 'Upload',
    icon: 'upload',
    group: 'core',
    order: 10,
    permissionFlags: ['canUploadImage', 'canAddImage'],
    render: UploadImagePanel,
  });

  registerImageProvider({
    id: 'qrcode',
    label: 'QR Code',
    icon: 'qr-code',
    group: 'core',
    order: 20,
    permissionFlags: ['canAddImage'],
    render: QRCodePanel,
  });

  registerImageProvider({
    id: 'ai',
    label: 'AI image',
    icon: 'ai-image',
    group: 'core',
    order: 30,
    permissionFlags: ['canAddImage'],
    licenseFeature: 'aiCredits',
    render: AiTextToImageProviderPanel,
  });
}
