import { useRef, useState } from 'preact/hooks';
import { useAsukaStore } from '../../store/asukaStore';
import { registerModule, type AsukaModuleComponent } from '../../core/modules';
import { getI18n } from '../../core/i18n';
import { useT } from '../../hooks/useT';

import { captureAsukaState, restoreAsukaState } from '../../core/stateManager';
import { clearStateStorage, loadStateFromStorage, saveStateToStorage } from '../../core/stateStorage';
import { Button } from '../core/Button';
import { Card, CardContent, CardHeader, CardTitle } from '../core/Card';
import { Checkbox } from '../core/Checkbox';
import { Field } from '../core/Field';
import { Input } from '../core/Input';
import { Select } from '../core/Select';
import { OverlayHost } from '../overlays/OverlayHost';

type ScopePresetId = 'full' | 'template' | 'theme' | 'ui' | 'canvas' | 'document';
type StateScopeSelection = {
  meta: boolean;
  layout: boolean;
  modules: boolean;
  documentViews: boolean;
  documentDrawingAreas: boolean;
  documentSnapshots: boolean;
  documentObjects: boolean;
  documentSelection: boolean;
  documentViewport: boolean;
  documentScenes3d: boolean;
  catalogElements: boolean;
  catalogDesigns: boolean;
  catalogColors: boolean;
  catalogPrintingMethods: boolean;
  appearanceDefaults: boolean;
  appearanceTheme: boolean;
  pricingBasePrice: boolean;
  pricingRules: boolean;
  pricingTotals: boolean;
  toolsFixedSlots: boolean;
  toolsMagnifier: boolean;
  toolsRuler: boolean;
  toolsShapes: boolean;
  toolsColorScope: boolean;
  toolsSelectionMenu: boolean;
  behaviorListeners: boolean;
  configurationModuleConfig: boolean;
  configurationIntegrations: boolean;
  configurationFonts: boolean;
  permissions: boolean;
  history: boolean;
};

const SCOPE_PRESETS: Array<{ id: ScopePresetId; labelKey: string }> = [
  { id: 'full', labelKey: 'state.scopePresets.full' },
  { id: 'template', labelKey: 'state.scopePresets.template' },
  { id: 'theme', labelKey: 'state.scopePresets.theme' },
  { id: 'ui', labelKey: 'state.scopePresets.ui' },
  { id: 'canvas', labelKey: 'state.scopePresets.canvas' },
  { id: 'document', labelKey: 'state.scopePresets.document' },
];

function presetToScopeSelection(preset: ScopePresetId): StateScopeSelection {
  if (preset === 'theme') {
    return {
      meta: true,
      layout: false,
      modules: false,
      documentViews: false,
      documentDrawingAreas: false,
      documentSnapshots: false,
      documentObjects: false,
      documentSelection: false,
      documentViewport: false,
      documentScenes3d: false,
      catalogElements: false,
      catalogDesigns: false,
      catalogColors: false,
      catalogPrintingMethods: false,
      appearanceDefaults: false,
      appearanceTheme: true,
      pricingBasePrice: false,
      pricingRules: false,
      pricingTotals: false,
      toolsFixedSlots: false,
      toolsMagnifier: false,
      toolsRuler: false,
      toolsShapes: false,
      toolsColorScope: false,
      toolsSelectionMenu: false,
      behaviorListeners: false,
      configurationModuleConfig: false,
      configurationIntegrations: false,
      configurationFonts: false,
      permissions: false,
      history: false,
    };
  }
  if (preset === 'template') {
    return {
      meta: true,
      layout: true,
      modules: true,
      documentViews: true,
      documentDrawingAreas: true,
      documentSnapshots: true,
      documentObjects: true,
      documentSelection: true,
      documentViewport: true,
      documentScenes3d: true,
      catalogElements: true,
      catalogDesigns: true,
      catalogColors: true,
      catalogPrintingMethods: true,
      appearanceDefaults: true,
      appearanceTheme: false,
      pricingBasePrice: false,
      pricingRules: false,
      pricingTotals: false,
      toolsFixedSlots: true,
      toolsMagnifier: false,
      toolsRuler: false,
      toolsShapes: true,
      toolsColorScope: false,
      toolsSelectionMenu: false,
      behaviorListeners: true,
      configurationModuleConfig: true,
      configurationIntegrations: false,
      configurationFonts: true,
      permissions: false,
      history: false,
    };
  }
  if (preset === 'ui') {
    return {
      meta: true,
      layout: true,
      modules: true,
      documentViews: false,
      documentDrawingAreas: false,
      documentSnapshots: false,
      documentObjects: false,
      documentSelection: false,
      documentViewport: false,
      documentScenes3d: false,
      catalogElements: false,
      catalogDesigns: false,
      catalogColors: false,
      catalogPrintingMethods: false,
      appearanceDefaults: true,
      appearanceTheme: false,
      pricingBasePrice: false,
      pricingRules: false,
      pricingTotals: false,
      toolsFixedSlots: false,
      toolsMagnifier: true,
      toolsRuler: true,
      toolsShapes: false,
      toolsColorScope: true,
      toolsSelectionMenu: true,
      behaviorListeners: true,
      configurationModuleConfig: true,
      configurationIntegrations: true,
      configurationFonts: true,
      permissions: true,
      history: false,
    };
  }
  if (preset === 'canvas' || preset === 'document') {
    return {
      meta: true,
      layout: false,
      modules: false,
      documentViews: true,
      documentDrawingAreas: true,
      documentSnapshots: true,
      documentObjects: true,
      documentSelection: true,
      documentViewport: true,
      documentScenes3d: true,
      catalogElements: true,
      catalogDesigns: true,
      catalogColors: true,
      catalogPrintingMethods: true,
      appearanceDefaults: false,
      appearanceTheme: false,
      pricingBasePrice: false,
      pricingRules: false,
      pricingTotals: false,
      toolsFixedSlots: false,
      toolsMagnifier: false,
      toolsRuler: false,
      toolsShapes: false,
      toolsColorScope: false,
      toolsSelectionMenu: false,
      behaviorListeners: false,
      configurationModuleConfig: false,
      configurationIntegrations: false,
      configurationFonts: false,
      permissions: false,
      history: true,
    };
  }
  return {
    meta: true,
    layout: true,
    modules: true,
    documentViews: true,
    documentDrawingAreas: true,
    documentSnapshots: true,
    documentObjects: true,
    documentSelection: true,
    documentViewport: true,
    documentScenes3d: true,
    catalogElements: true,
    catalogDesigns: true,
    catalogColors: true,
    catalogPrintingMethods: true,
    appearanceDefaults: true,
    appearanceTheme: true,
    pricingBasePrice: true,
    pricingRules: true,
    pricingTotals: true,
    toolsFixedSlots: true,
    toolsMagnifier: true,
    toolsRuler: true,
    toolsShapes: true,
    toolsColorScope: true,
    toolsSelectionMenu: true,
    behaviorListeners: true,
    configurationModuleConfig: true,
    configurationIntegrations: true,
    configurationFonts: true,
    permissions: true,
    history: true,
  };
}

function scopeSelectionToPayload(scope: StateScopeSelection) {
  return {
    meta: scope.meta,
    layout: scope.layout,
    modules: scope.modules,
    document: {
      views: scope.documentViews,
      drawingAreas: scope.documentDrawingAreas,
      snapshots: scope.documentSnapshots,
      objects: scope.documentObjects,
      selection: scope.documentSelection,
      viewportByView: scope.documentViewport,
      scenes3d: scope.documentScenes3d,
    },
    catalog: {
      elements: scope.catalogElements,
      designs: scope.catalogDesigns,
      colors: scope.catalogColors,
      printingMethods: scope.catalogPrintingMethods,
    },
    appearance: {
      defaults: scope.appearanceDefaults,
      theme: scope.appearanceTheme,
    },
    pricing: {
      basePrice: scope.pricingBasePrice,
      rules: scope.pricingRules,
      totals: scope.pricingTotals,
    },
    tools: {
      fixedSlots: scope.toolsFixedSlots,
      magnifier: scope.toolsMagnifier,
      ruler: scope.toolsRuler,
      shapes: scope.toolsShapes,
      colorScope: scope.toolsColorScope,
      selectionMenu: scope.toolsSelectionMenu,
    },
    behavior: {
      listeners: scope.behaviorListeners,
    },
    configuration: {
      moduleConfig: scope.configurationModuleConfig,
      integrations: scope.configurationIntegrations,
      fonts: scope.configurationFonts,
    },
    permissions: scope.permissions,
    history: scope.history,
  } as any;
}

const StateModule: AsukaModuleComponent = ({ context }) => {
  const t = useT();
  const designer = useAsukaStore((s) => s.designerInstance);
  const engine = context?.getEngine?.() ?? null;
  const activeViewId = useAsukaStore((s: any) => String(s.activeViewId ?? ''));
  const setDocument3dSceneForView = useAsukaStore((s: any) => s.setDocument3dSceneForView);
  const activeRenderEngineKind = useAsukaStore((s: any) => s.activeRenderEngineKind ?? 'fabric');
  const runtimeReady = Boolean(designer || activeRenderEngineKind === '3d');
  const permissions = useAsukaStore((s) => (s as any).permissions);
  const canUse = Boolean((permissions as any)?.canUseStateTools ?? true);

  const fileRef = useRef<HTMLInputElement | null>(null);
  const [preset, setPreset] = useState<ScopePresetId>('full');
  const [storageKey, setStorageKey] = useState('asuka:state');
  const [lastExport, setLastExport] = useState<string>('');
  const [status, setStatus] = useState<string>('');
  const [scopeSelection, setScopeSelection] = useState<StateScopeSelection>(() => presetToScopeSelection('full'));

  const [isExportOpen, setIsExportOpen] = useState(false);
  const [isImportOpen, setIsImportOpen] = useState(false);
  const [importText, setImportText] = useState('');


  const setOk = (msg: string) => setStatus(msg);
  const setErr = (msg: string) => setStatus(msg);

  const updatePreset = (next: ScopePresetId) => {
    setPreset(next);
    setScopeSelection(presetToScopeSelection(next));
  };

  const getImportOptions = () => {
    const scope = scopeSelectionToPayload(scopeSelection);
    const replacesDocument = Boolean(scope.document?.views || scope.document?.snapshots || scope.document?.objects || scope.document?.scenes3d);
    return {
      scope,
      replaceViews: replacesDocument,
      replaceSnapshots: replacesDocument,
    } as any;
  };

  const persistActive3DScene = async () => {
    if (activeRenderEngineKind !== '3d' || !activeViewId || !engine) return;
    try {
      const scene = await engine.lifecycle.exportView(activeViewId);
      setDocument3dSceneForView?.(activeViewId, scene as any);
    } catch {}
  };

  const doExport = async () => {
    try {
      await persistActive3DScene();
      const exported = captureAsukaState(scopeSelectionToPayload(scopeSelection));
      const json = JSON.stringify(exported, null, 2);
      setLastExport(json);
      setIsExportOpen(true);
      setOk(t('state.status.exported'));
    } catch (e: any) {
      setErr(e?.message || t('state.errors.exportFailed'));
    }
  };

  const doDownloadFile = () => {
    try {
      const data = lastExport || '';
      const blob = new Blob([data], { type: 'application/json;charset=utf-8' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = 'asuka-state.json';
      a.click();
      window.setTimeout(() => URL.revokeObjectURL(url), 0);
      setOk(t('state.status.saved'));
    } catch (e: any) {
      setErr(e?.message || t('state.errors.saveFailed'));
    }
  };

  const doCopy = async () => {
    try {
      await navigator.clipboard.writeText(lastExport || '');
      setOk(t('state.status.copied'));
    } catch {
      setErr(t('state.errors.copyFailed'));
    }
  };

  const doSaveToStorage = async () => {
    try {
      await persistActive3DScene();
      const exported = captureAsukaState(scopeSelectionToPayload(scopeSelection));
      saveStateToStorage(exported, { key: storageKey });
      setOk(t('state.status.saved'));
    } catch (e: any) {
      setErr(e?.message || t('state.errors.saveFailed'));
    }
  };

  const doLoadFromStorage = () => {
    try {
      const saved = loadStateFromStorage({ key: storageKey });
      if (!saved) return setErr(t('state.errors.noStateInStorage'));
      restoreAsukaState(saved, getImportOptions());
      setOk(t('state.status.loaded'));
    } catch (e: any) {
      setErr(e?.message || t('state.errors.loadFailed'));
    }
  };

  const doClearStorage = () => {
    try {
      clearStateStorage({ key: storageKey });
      setOk(t('state.status.cleared'));
    } catch (e: any) {
      setErr(e?.message || t('state.errors.clearFailed'));
    }
  };

  const doImport = () => {
    try {
      const parsed = JSON.parse(importText || '{}');
      if ((parsed as any)?.format !== 'asuka-state' || (parsed as any)?.schemaVersion !== 2) {
        throw new TypeError('Invalid Asuka state payload. Expected format "asuka-state" with schemaVersion 2.');
      }
      restoreAsukaState(parsed as any, getImportOptions());
      setIsImportOpen(false);
      setOk(t('state.status.imported'));
    } catch (e: any) {
      setErr(e?.message || t('state.errors.importFailed'));
    }
  };

  const onPickFile = async (e: Event) => {
    const input = e.currentTarget as HTMLInputElement;
    const file = input?.files?.[0];
    if (!file) return;
    try {
      const text = await file.text();
      setImportText(text);
      setIsImportOpen(true);
      setOk(t('state.status.loaded'));
    } catch (error: any) {
      setErr(error?.message || t('state.errors.loadFailed'));
    } finally {
      if (input) input.value = '';
    }
  };

  if (!canUse) {
    return (
      <Card>
        <CardHeader>
          <CardTitle>{t('modules.state')}</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="ask-text-[12px] ask-text-textMuted">{t('common.empty', 'Empty')}</div>
        </CardContent>
      </Card>
    );
  }

  return (
    <Card>
      <CardHeader className="ask-flex ask-items-center ask-justify-between">
        <CardTitle>{t('modules.state')}</CardTitle>
        <div className="ask-text-[10px] ask-text-textMuted">
          {designer ? t('state.ready', 'Ready') : t('state.designerNotReady', 'Designer not ready')}
        </div>
      </CardHeader>

      <CardContent className="ask-flex ask-flex-col ask-gap-4">
        <Field label={t('state.scopePreset', 'Scope preset')} required>
          <Select
            required
            aria-required="true"
            value={preset}
            onChange={(e) => updatePreset((e.currentTarget as HTMLSelectElement).value as ScopePresetId)}
            options={SCOPE_PRESETS.map((p) => ({ value: p.id, label: t(p.labelKey, p.id) }))}
          />
        </Field>

        <div className="ask-grid ask-grid-cols-2 ask-gap-2 ask-rounded-[12px] ask-border ask-border-borderSubtle ask-p-3">
            <Checkbox checked={scopeSelection.layout} onChange={(e) => setScopeSelection((s) => ({ ...s, layout: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.layout', 'Layout')} />
            <Checkbox checked={scopeSelection.modules} onChange={(e) => setScopeSelection((s) => ({ ...s, modules: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.modules', 'Modules')} />
            <Checkbox checked={scopeSelection.documentViews} onChange={(e) => setScopeSelection((s) => ({ ...s, documentViews: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.views', 'Views')} />
            <Checkbox checked={scopeSelection.documentDrawingAreas} onChange={(e) => setScopeSelection((s) => ({ ...s, documentDrawingAreas: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.drawingAreas', 'Drawing areas')} />
            <Checkbox checked={scopeSelection.documentObjects} onChange={(e) => setScopeSelection((s) => ({ ...s, documentObjects: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.objects', 'Objects')} />
            <Checkbox checked={scopeSelection.documentSnapshots} onChange={(e) => setScopeSelection((s) => ({ ...s, documentSnapshots: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.snapshots', 'Snapshots')} />
            <Checkbox checked={scopeSelection.documentSelection} onChange={(e) => setScopeSelection((s) => ({ ...s, documentSelection: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.selection', 'Selection')} />
            <Checkbox checked={scopeSelection.documentViewport} onChange={(e) => setScopeSelection((s) => ({ ...s, documentViewport: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.viewport', 'Viewport')} />
            <Checkbox checked={scopeSelection.documentScenes3d} onChange={(e) => setScopeSelection((s) => ({ ...s, documentScenes3d: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.scenes3d', '3D scenes')} />
            <Checkbox checked={scopeSelection.catalogElements} onChange={(e) => setScopeSelection((s) => ({ ...s, catalogElements: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.elements', 'Elements')} />
            <Checkbox checked={scopeSelection.catalogDesigns} onChange={(e) => setScopeSelection((s) => ({ ...s, catalogDesigns: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.designs', 'Designs')} />
            <Checkbox checked={scopeSelection.catalogColors} onChange={(e) => setScopeSelection((s) => ({ ...s, catalogColors: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.colors', 'Colors')} />
            <Checkbox checked={scopeSelection.catalogPrintingMethods} onChange={(e) => setScopeSelection((s) => ({ ...s, catalogPrintingMethods: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.printingMethods', 'Printing methods')} />
            <Checkbox checked={scopeSelection.appearanceDefaults} onChange={(e) => setScopeSelection((s) => ({ ...s, appearanceDefaults: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.defaults', 'Defaults')} />
            <Checkbox checked={scopeSelection.appearanceTheme} onChange={(e) => setScopeSelection((s) => ({ ...s, appearanceTheme: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.theme', 'Theme')} />
            <Checkbox checked={scopeSelection.pricingBasePrice} onChange={(e) => setScopeSelection((s) => ({ ...s, pricingBasePrice: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.pricingBasePrice', 'Base price')} />
            <Checkbox checked={scopeSelection.pricingRules} onChange={(e) => setScopeSelection((s) => ({ ...s, pricingRules: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.pricingRules', 'Pricing rules')} />
            <Checkbox checked={scopeSelection.pricingTotals} onChange={(e) => setScopeSelection((s) => ({ ...s, pricingTotals: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.pricingTotals', 'Pricing totals')} />
            <Checkbox checked={scopeSelection.toolsFixedSlots} onChange={(e) => setScopeSelection((s) => ({ ...s, toolsFixedSlots: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.fixedSlots', 'Markers')} />
            <Checkbox checked={scopeSelection.toolsMagnifier} onChange={(e) => setScopeSelection((s) => ({ ...s, toolsMagnifier: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.magnifier', 'Magnifier')} />
            <Checkbox checked={scopeSelection.toolsRuler} onChange={(e) => setScopeSelection((s) => ({ ...s, toolsRuler: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.ruler', 'Ruler')} />
            <Checkbox checked={scopeSelection.toolsShapes} onChange={(e) => setScopeSelection((s) => ({ ...s, toolsShapes: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.shapes', 'Shapes')} />
            <Checkbox checked={scopeSelection.toolsColorScope} onChange={(e) => setScopeSelection((s) => ({ ...s, toolsColorScope: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.colorScope', 'Color scope')} />
            <Checkbox checked={scopeSelection.toolsSelectionMenu} onChange={(e) => setScopeSelection((s) => ({ ...s, toolsSelectionMenu: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.selectionMenu', 'Selection menu')} />
            <Checkbox checked={scopeSelection.behaviorListeners} onChange={(e) => setScopeSelection((s) => ({ ...s, behaviorListeners: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.listeners', 'Listeners')} />
            <Checkbox checked={scopeSelection.configurationModuleConfig} onChange={(e) => setScopeSelection((s) => ({ ...s, configurationModuleConfig: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.moduleConfig', 'Module config')} />
            <Checkbox checked={scopeSelection.configurationIntegrations} onChange={(e) => setScopeSelection((s) => ({ ...s, configurationIntegrations: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.integrations', 'Integrations')} />
            <Checkbox checked={scopeSelection.configurationFonts} onChange={(e) => setScopeSelection((s) => ({ ...s, configurationFonts: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.fonts', 'Fonts')} />
            <Checkbox checked={scopeSelection.permissions} onChange={(e) => setScopeSelection((s) => ({ ...s, permissions: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.permissions', 'Permissions')} />
            <Checkbox checked={scopeSelection.history} onChange={(e) => setScopeSelection((s) => ({ ...s, history: (e.currentTarget as HTMLInputElement).checked }))} label={t('state.scope.history', 'History')} />
        </div>

        <Field label={t('state.storageKey', 'Storage key')} required>
          <Input required aria-required="true" value={storageKey} onInput={(e) => setStorageKey((e.currentTarget as HTMLInputElement).value)} />
        </Field>

        <input ref={fileRef} type="file" accept="application/json,.json" className="ask-hidden" onChange={onPickFile as any} />

        <div className="ask-flex ask-flex-wrap ask-gap-2">
          <Button onClick={doExport} disabled={!runtimeReady}>{t('common.export', 'Export')}</Button>
          <Button onClick={() => fileRef.current?.click()} disabled={!runtimeReady}>{t('state.importFile', 'Import file')}</Button>
          <Button onClick={() => setIsImportOpen(true)} disabled={!runtimeReady}>{t('common.import', 'Import')}</Button>
          <Button onClick={doSaveToStorage} disabled={!runtimeReady}>{t('state.saveToStorage', 'Save storage')}</Button>
          <Button onClick={doLoadFromStorage} disabled={!runtimeReady}>{t('state.loadFromStorage', 'Load storage')}</Button>
          <Button variant="ghost" onClick={doClearStorage} disabled={!runtimeReady}>{t('state.clearStorage', 'Clear storage')}</Button>
        </div>

        {status ? <div className="ask-text-[11px] ask-text-textMuted">{status}</div> : null}

        {isExportOpen ? (
          <OverlayHost type="modal" title={t('state.export', 'State export')} onClose={() => setIsExportOpen(false)} compactHeader>
            <div className="ask-flex ask-flex-col ask-gap-4">
              <div className="ask-flex ask-gap-2 ask-justify-end">
                <Button onClick={doCopy}>{t('common.copy', 'Copy')}</Button>
                <Button onClick={doDownloadFile}>{t('download.export', 'Download')}</Button>
                <Button variant="ghost" onClick={() => setIsExportOpen(false)}>{t('common.close', 'Close')}</Button>
              </div>
              <textarea
                className="ask-theme-input ask-w-full ask-rounded-[12px] ask-border ask-p-3 ask-text-[11px] ask-font-mono ask-min-h-[280px] ask-max-h-[70vh]"
                value={lastExport}
                readOnly
              />
            </div>
          </OverlayHost>
        ) : null}

        {isImportOpen ? (
          <OverlayHost type="modal" title={t('state.import', 'State import')} onClose={() => setIsImportOpen(false)} compactHeader>
            <div className="ask-flex ask-flex-col ask-gap-4">
              <textarea
                required
                aria-required="true"
                className="ask-theme-input ask-w-full ask-rounded-[12px] ask-border ask-p-3 ask-text-[11px] ask-font-mono ask-min-h-[280px] ask-max-h-[70vh]"
                value={importText}
                onInput={(e) => setImportText((e.currentTarget as HTMLTextAreaElement).value)}
                placeholder={t('state.placeholders.json', 'Paste JSON here')}
              />
              <div className="ask-flex ask-gap-2 ask-justify-end">
                <Button onClick={doImport}>{t('common.import', 'Import')}</Button>
                <Button variant="ghost" onClick={() => setIsImportOpen(false)}>{t('common.cancel', 'Cancel')}</Button>
              </div>
            </div>
          </OverlayHost>
        ) : null}
      </CardContent>
    </Card>
  );
};

registerModule({
  id: 'state',
  label: getI18n().t('modules.state'),
  icon: 'save',
  group: 'dev',
  supportedEngines: ['fabric', '3d'],
  render: StateModule,
});

export default StateModule;
