import { useEffect, useState } from "react";
import { createRoot, type Root } from "react-dom/client";
import { Markdown } from "@thortiq/plugin-react";
import type {
  JsonValue,
  NativePluginApiV1,
  NativePluginViewContext,
  PluginActivationApiV1,
} from "@thortiq/plugin-api";

const VIEW = Object.freeze({ id: "panel", title: "Thortiq Example React Native View panel", icon: "sparkles" });
const COMMAND = Object.freeze({ id: "refresh", title: "Refresh Thortiq Example React Native View" });

/**
 * React native activation. The bundled entry ships its own React runtime; React
 * is never a host external. No Thortiq internals, filesystem handles, or live
 * vault paths are imported.
 */
export function activate(api: PluginActivationApiV1): void {
  if (api.runtime !== "native") {
    throw new Error("Thortiq Example React Native View requires the declared native runtime.");
  }
  api.commands.register(COMMAND, async () => {
    // Manual refresh: re-read bounded admitted data here.
  });

  api.views.register({
    ...VIEW,
    create(context, container) {
      const native = api as NativePluginApiV1;
      const root = createRoot(container);
      root.render(<Panel api={native} context={context} />);
      context.setTitle(VIEW.title);
      return Object.freeze({
        getState(): JsonValue {
          return Object.freeze({ view: "panel" });
        },
        destroy() {
          root.unmount();
        },
      });
    },
  });
}

function readNoteId(state: JsonValue | null): string | null {
  if (state && typeof state === "object" && !Array.isArray(state)) {
    const value = (state as Record<string, JsonValue>).noteId;
    if (typeof value === "string") return value;
  }
  return null;
}

function Panel({ api, context }: {
  readonly api: NativePluginApiV1;
  readonly context: NativePluginViewContext;
}) {
  const [label, setLabel] = useState<string>(VIEW.title);
  const [iconUrl, setIconUrl] = useState<string | null>(null);
  const noteId = readNoteId(context.initialState);

  useEffect(() => {
    let active = true;
    const render = async () => {
      const configured = await api.settings.get("label");
      if (active) {
        setLabel(typeof configured === "string" && configured.length > 0 ? configured : VIEW.title);
      }
    };
    void render();
    // Package assets are addressed through the host, never a relative runtime URL.
    void api.packageAssets.getUrl("assets/icon.svg").then(url => {
      if (active) setIconUrl(url);
    });
    const subscription = api.settings.subscribe(keys => {
      if (keys.includes("label")) void render();
    });
    return () => {
      active = false;
      subscription.dispose();
    };
  }, [api]);

  return (
    <section className="thortiq-example-react-native-view-panel">
      <h2>
        {iconUrl ? <img src={iconUrl} alt="" width={16} height={16} /> : null}
        {label}
      </h2>
      {noteId ? (
        <Markdown
          api={api}
          options={{ markdown: "Synthetic preview.", sourceNoteId: noteId, interactive: false }}
        />
      ) : (
        <p>Open this panel for a note to see its rendered preview.</p>
      )}
    </section>
  );
}

export default Object.freeze({ activate });

// Re-exported so bundlers keep the type without importing an unused value.
export type { Root };
