import React, { useMemo, useState } from 'react';
import { Pressable } from 'react-native';
import { Maximize2, Sparkles } from 'lucide-react-native';

import type { SuperagentToolRendererProps } from '../../types';
import { themedColor, useSuperagentTheme } from '../../theme';
import { ToolWidgetRow } from '../primitives/ToolWidgetRow';
import { buildArtifactPreviewHtml, canPreviewArtifact, isSvgArtifact, previewFailureApplies } from '../artifactPreviewUtils';
import { extractArtifact, getArtifactRenderState } from '../artifactToolUtils';
import { getFailureReason } from '../skillsAndConnectionsUtils';
import { getStringArg, isActionableTurn, parseToolArgs, type ToolWidgetStatus } from '../toolWidgetUtils';
import { ArtifactFullscreenModal, ArtifactInlinePreview } from './ArtifactPreview';

/**
 * artifacts (+ aliases) — native port of the web ArtifactToolUI status row.
 * Settled successful artifacts render a live sandboxed WebView preview (web
 * MessageArtifacts/ArtifactInlineCard parity — see ArtifactPreview) with a
 * fullscreen affordance in the header; when the inline WebView errors, the row
 * shows a preview-failure note (web parity: no metadata/type/source
 * disclosure), while a fullscreen error only closes the modal. Failures are
 * keyed to the failed markup, so a later artifact update retries.
 */
export function ArtifactWidget({ isLastAssistantMessage, toolCall }: SuperagentToolRendererProps) {
  const args = useMemo(() => parseToolArgs(toolCall), [toolCall]);
  const { scheme } = useSuperagentTheme();
  const rawStatus = (toolCall.status || '').toLowerCase();
  const isError = rawStatus === 'error' || rawStatus === 'failed';
  // Extract whenever the call hasn't errored — socket/history updates can
  // leave the status stale ("running"/"pending") after the payload arrived.
  const artifact = isError ? null : extractArtifact(toolCall.client_artifact);
  // Turn-settling (getSettledWidgetStatus parity): once the message is no
  // longer the latest assistant turn, a still-"running" status means the
  // update was lost — a payload-less call settles to 'unavailable' (never to
  // a rendered success; only a delivered payload proves rendering).
  const state = getArtifactRenderState(rawStatus, Boolean(artifact), isActionableTurn(isLastAssistantMessage));

  const title = artifact?._meta?.title || getStringArg(args, ['title']) || 'Artifact';
  const command = getStringArg(args, ['command']) || 'create';
  const statusLabel = state === 'running'
    ? command === 'rewrite' ? 'Updating artifact' : 'Rendering artifact'
    : state === 'failed' ? 'Failed to render artifact'
    : state === 'stopped' ? 'Rendering stopped'
    : state === 'unavailable' ? 'Artifact unavailable'
    : command === 'rewrite' ? 'Updated artifact' : 'Rendered artifact';

  const typeArg = getStringArg(args, ['type']);

  // Failed/stopped render as an error row so they never read as completed
  // (skills/automation widget parity); 'unavailable' keeps the neutral muted
  // icon (ToolWidgetStatus 'stopped') — neither a success check nor an error.
  const rowStatus: ToolWidgetStatus = state === 'failed' || state === 'stopped'
    ? 'error'
    : state === 'running' ? 'running'
    : state === 'unavailable' ? 'stopped'
    : 'success';

  const [inlineFailedFor, setInlineFailedFor] = useState<string | null>(null);
  const [fullscreen, setFullscreen] = useState(false);
  // Preview only DELIVERED markup — the args `content` fallback is never used
  // for execution.
  const previewSource = artifact?.text;
  const previewFailed = previewFailureApplies(inlineFailedFor, previewSource);
  const showPreview = !previewFailed && canPreviewArtifact(rowStatus, previewSource);
  const previewHtml = useMemo(
    () => (showPreview && previewSource
      ? buildArtifactPreviewHtml(previewSource, { isDark: scheme === 'dark', isSvg: isSvgArtifact(typeArg, previewSource) })
      : null),
    [previewSource, scheme, showPreview, typeArg],
  );
  const failInlinePreview = () => {
    setInlineFailedFor(previewSource ?? null);
    setFullscreen(false);
  };

  return (
    <>
      <ToolWidgetRow
        action={showPreview ? (
          <Pressable
            accessibilityLabel="Open artifact fullscreen"
            accessibilityRole="button"
            hitSlop={8}
            onPress={() => setFullscreen(true)}
          >
            <Maximize2 color={themedColor('#8E8E93')} size={15} strokeWidth={2.3} />
          </Pressable>
        ) : undefined}
        chipText={title}
        failureText={isError
          ? getFailureReason('error', toolCall)
          : previewFailed ? 'Artifact preview failed to load' : null}
        icon={Sparkles}
        status={rowStatus}
        title={statusLabel}
      />
      {/* Sibling of ToolWidgetRow, not nested in its indented rowBody — the
          web's MessageArtifacts lifts the live iframe out the same way so it
          gets the widget's full width instead of the body's icon-aligned inset. */}
      {previewHtml ? <ArtifactInlinePreview html={previewHtml} onFail={failInlinePreview} /> : null}
      {previewHtml ? (
        <ArtifactFullscreenModal
          html={previewHtml}
          onClose={() => setFullscreen(false)}
          // A fullscreen-only error falls back to the (healthy) inline
          // preview; reopening remounts a fresh WebView.
          onFail={() => setFullscreen(false)}
          title={title}
          visible={fullscreen}
        />
      ) : null}
    </>
  );
}
