import type Konva from 'konva';
import { lazy, Suspense, useMemo } from 'react';
import { type Layout, type TextLayer } from '@/types/layout';
import { useActiveLocaleDirection } from './locale';
import { useEditor } from './store';
import { resolveRichRuns } from './richText';

// TipTap is heavy (~370 KB) — load it only when a text layer is actually edited
// (the rich editor mounts), keeping it out of the main editor bundle.
const RichTextInlineEditor = lazy(() =>
    import('./RichTextInlineEditor').then((m) => ({ default: m.RichTextInlineEditor })),
);

type Props = {
    stageRef: React.RefObject<Konva.Stage | null>;
    /** Pass through so a pan/zoom re-render in the parent refreshes us. */
    scale: number;
    /** Active screen's world-space viewport offset. */
    viewportOffset: { x: number; y: number };
    /** Active screen's layout (for canvas dims + finding the layer). */
    layout: Layout;
};

export function InlineTextEditor({ stageRef, scale, viewportOffset, layout }: Props) {
    const editLayerId = useEditor((s) => s.textEditLayerId);
    const updateLayer = useEditor((s) => s.updateLayer);
    const exitTextEdit = useEditor((s) => s.exitTextEdit);
    const activeLocale = useEditor((s) => s.activeLocale);
    const defaultLocale = useEditor((s) => s.defaultLocale);
    const localeDirection = useActiveLocaleDirection();

    const layer = useMemo(() => {
        if (!editLayerId) return null;
        const found = layout.layers.find((l) => l.id === editLayerId);
        return found && found.type === 'text' ? (found as TextLayer) : null;
    }, [editLayerId, layout.layers]);

    if (!layer) return null;
    const isLocaleOverride = activeLocale !== defaultLocale;
    const initialRuns = resolveRichRuns(layer, activeLocale, defaultLocale);

    // Rich (TipTap) editing for EVERY locale — default writes `richRuns`,
    // overrides write `richRunsByLocale[locale]` alongside the per-locale text.
    return (
        <Suspense fallback={null}>
            <RichTextInlineEditor
                key={`${layer.id}:${activeLocale}`}
                layer={layer}
                layout={layout}
                activeLocale={activeLocale}
                initialRuns={initialRuns}
                scale={scale}
                stageRef={stageRef}
                viewportOffset={viewportOffset}
                localeDirection={localeDirection}
                swatches={swatchesForLayout(layout, layer.color)}
                onCommit={(content, runs) => {
                    updateLayer(layer.id, (draft) => {
                        if (draft.type !== 'text') return;
                        if (isLocaleOverride) {
                            draft.content = { ...draft.content, [activeLocale]: content };
                            const map = { ...(draft.richRunsByLocale ?? {}) };
                            if (runs && runs.length) map[activeLocale] = runs;
                            else delete map[activeLocale];
                            draft.richRunsByLocale = Object.keys(map).length ? map : undefined;
                        } else {
                            draft.content = { ...draft.content, default: content };
                            draft.richRuns = runs && runs.length ? runs : undefined;
                        }
                    });
                    exitTextEdit();
                }}
                onCancel={exitTextEdit}
            />
        </Suspense>
    );
}

/** Distinct text colours already used in the layout (surfaces the project's
 *  accent), capped, with the base colour first. */
function swatchesForLayout(layout: Layout, baseColor: string): string[] {
    const set = new Set<string>([baseColor]);
    for (const l of layout.layers) {
        if (l.type === 'text' && typeof l.color === 'string') set.add(l.color);
    }
    return Array.from(set).slice(0, 6);
}


