import type {
  AsukaCanvas2DTextPatch,
  AsukaCanvas2DTextSelection,
  AsukaRenderEngine,
} from './renderEngine';
import { ensureFontFamilyLoaded } from './fontRegistry';

export function getSelectedRendererText(engine: AsukaRenderEngine | null | undefined): AsukaCanvas2DTextSelection | null {
  if (!engine) return null;
  if (engine.canvas2d) return engine.canvas2d.getSelectedText();
  const selected: any = engine.selection.list()[0] ?? null;
  const kind = String(selected?.kind ?? selected?.metadata?.type ?? '').toLowerCase();
  if (!selected || kind !== 'text') return null;
  const source = selected?.metadata?.source && typeof selected.metadata.source === 'object'
    ? selected.metadata.source
    : {};
  return {
    objectId: String(selected.id ?? ''),
    text: String(source.text ?? selected.label ?? 'Text'),
    fontFamily: String(source.fontFamily ?? 'Arial'),
    fontSize: Math.max(8, Number(source.fontSize ?? 72) || 72),
    fontWeight: String(source.fontWeight ?? 'normal'),
    fontStyle: String(source.fontStyle ?? 'normal'),
    underline: source.underline === true,
    lineHeight: Number(source.lineHeight ?? 1.2) || 1.2,
    charSpacing: Number(source.charSpacing ?? 0) || 0,
    textAlign: String(source.textAlign ?? 'center') as any,
    fill: String(source.color ?? selected?.metadata?.color ?? '#111827'),
    curved: false,
    allowedFonts: Array.isArray(source.allowedFonts) ? source.allowedFonts : undefined,
  };
}

export async function updateSelectedRendererText(
  engine: AsukaRenderEngine | null | undefined,
  patch: AsukaCanvas2DTextPatch,
  options: { source?: string; commit?: boolean } = {},
): Promise<void> {
  if (!engine) return;
  if (typeof patch.fontFamily === 'string' && patch.fontFamily.trim()) {
    await ensureFontFamilyLoaded(patch.fontFamily);
  }
  if (engine.canvas2d) {
    await engine.canvas2d.updateSelectedText(patch, options);
    return;
  }
  const selected: any = engine.selection.list()[0] ?? null;
  const id = String(selected?.id ?? '').trim();
  if (!id || String(selected?.kind ?? '').toLowerCase() !== 'text') return;
  const previousSource = selected?.metadata?.source && typeof selected.metadata.source === 'object'
    ? selected.metadata.source
    : {};
  const nextSource: Record<string, unknown> = { ...previousSource, ...patch };
  if (typeof patch.fill === 'string') {
    nextSource.color = patch.fill;
    delete nextSource.fill;
  }
  await engine.objects.update(id, {
    ...(typeof patch.fill === 'string' ? { color: patch.fill } : null),
    source: nextSource,
    metadata: { textFormattingSource: options.source ?? 'renderer-text-selection' },
  } as any);
}
