import type { ThreadMessage, ArtifactAction, ProposedContentRef, Artifact } from '@janhq/core'
import { useArtifacts } from '@/hooks/useArtifacts'
import { useEffect, useState } from 'react'
import { getServiceHub } from '@/hooks/useServiceHub'
import { InlineArtifactCard } from './InlineArtifactCard'

type ArtifactActionMessageProps = {
  message: ThreadMessage
}

/**
 * Extract artifact_action from message metadata or content
 * Claude-style: AI embeds JSON in message content, we parse it
 */
function extractArtifactAction(message: ThreadMessage): ArtifactAction | undefined {
  // First check metadata (preferred)
  if (message.metadata?.artifact_action) {
    return message.metadata.artifact_action as ArtifactAction
  }

  // Fallback: parse from message content
  if (typeof message.content === 'string') {
    try {
      // Look for JSON blocks in the message
      const jsonMatch = message.content.match(/```json\s*(\{[\s\S]*?\})\s*```/)
      if (jsonMatch) {
        const parsed = JSON.parse(jsonMatch[1])
        if (parsed.artifact_action) {
          return parsed.artifact_action as ArtifactAction
        }
      }
      
      // Also try direct JSON parsing (in case AI outputs raw JSON)
      const artifactMatch = message.content.match(/\{\s*"artifact_action"[\s\S]*?\}/)
      if (artifactMatch) {
        const parsed = JSON.parse(artifactMatch[0])
        if (parsed.artifact_action) {
          return parsed.artifact_action as ArtifactAction
        }
      }
    } catch (err) {
      // Not valid JSON, ignore
    }
  }

  return undefined
}

export function ArtifactActionMessage({ message }: ArtifactActionMessageProps) {
  const artifacts = useArtifacts()
  const artifactAction = extractArtifactAction(message)
  const [loadingProposal, setLoadingProposal] = useState(false)
  const [artifactCreated, setArtifactCreated] = useState(false)

  if (!artifactAction) return null

  // Auto-create artifact when message with create action is received
  useEffect(() => {
    if (
      artifactAction.type === 'create' &&
      message.thread_id &&
      !artifactCreated
    ) {
      const { name, content_type, language, preview } = artifactAction.artifact
      const content = preview || '' // Use preview as initial content

      artifacts.createArtifact(message.thread_id, name, content_type, language, content)
        .then(() => {
          setArtifactCreated(true)
        })
        .catch((err) => {
          console.error('Failed to auto-create artifact:', err)
        })
    }
  }, [artifactAction, message.thread_id, artifactCreated])

  // Load proposal content if it exists
  useEffect(() => {
    if (artifactAction.type === 'update' && artifactAction.proposed_content_ref && message.thread_id) {
      const ref = artifactAction.proposed_content_ref as ProposedContentRef
      
      // Check if we already have this proposal loaded
      const existingProposal = artifacts.pendingProposals[artifactAction.artifact_id]
      if (existingProposal) return

      setLoadingProposal(true)

      // Handle inline content vs file reference
      if (ref.storage === 'inline' && ref.content) {
        // Content is provided inline
        artifacts.proposeUpdate(message.thread_id, artifactAction.artifact_id, ref.content)
          .catch((err) => {
            console.error('Failed to load inline proposal:', err)
          })
          .finally(() => {
            setLoadingProposal(false)
          })
      } else if (ref.storage === 'temp' && ref.path) {
        // Read the proposed content from the temp file
        getServiceHub()
          .artifacts()
          .getArtifactContent(message.thread_id, ref.path)
          .then((content) => {
            if (content && message.thread_id) {
              // Create a proposal
              return artifacts.proposeUpdate(message.thread_id, artifactAction.artifact_id, content)
            }
          })
          .catch((err) => {
            console.error('Failed to load proposal:', err)
          })
          .finally(() => {
            setLoadingProposal(false)
          })
      } else {
        setLoadingProposal(false)
      }
    }
  }, [artifactAction, message.thread_id])

  const handleOpenArtifact = () => {
    if (artifactAction.type === 'create' && message.thread_id) {
      // For create actions, the artifact should already be created
      // Just open the split view
      artifacts.toggleSplitView(message.thread_id)
    } else if (artifactAction.type === 'update' && message.thread_id) {
      // For update actions, show the diff or open the artifact
      if (!artifacts.splitViewOpen[message.thread_id]) {
        artifacts.toggleSplitView(message.thread_id)
      }
      artifacts.setActiveArtifact(message.thread_id, artifactAction.artifact_id)
    }
  }

  if (artifactAction.type === 'create') {
    // Convert ArtifactAction to Artifact for the card
    const artifactForCard: Artifact & { content: string } = {
      id: artifactAction.artifact_id || 'pending',
      name: artifactAction.artifact.name,
      slug: artifactAction.artifact.name.toLowerCase().replace(/\s+/g, '-'),
      content_type: artifactAction.artifact.content_type,
      language: artifactAction.artifact.language,
      content: artifactAction.artifact.preview || '',
      file_path: `${artifactAction.artifact.name}.${artifactAction.artifact.language || 'txt'}`,
      version: 1,
      hash: '',
      bytes: 0,
      created_at: Date.now(),
      updated_at: Date.now(),
      read_only: false,
      extensions: {},
      metadata: {
        archived: false,
        tags: [],
      },
    }

    return <InlineArtifactCard artifact={artifactForCard} threadId={message.thread_id || ''} isCreating={!artifactCreated} />
  }

  if (artifactAction.type === 'update') {
    return (
      <div className="flex items-start gap-3 p-3 my-2 rounded-lg bg-blue-500/10 border border-blue-500/20">
        <div className="flex-shrink-0 mt-0.5">
          <svg
            width="20"
            height="20"
            viewBox="0 0 20 20"
            fill="none"
            className="text-blue-500"
          >
            <path
              d="M13.5858 3.58579C14.3668 2.80474 15.6332 2.80474 16.4142 3.58579C17.1953 4.36683 17.1953 5.63316 16.4142 6.41421L6.41421 16.4142C6.03914 16.7893 5.53043 17 5 17H3C2.44772 17 2 16.5523 2 16V14C2 13.4696 2.21071 12.9609 2.58579 12.5858L12.5858 2.58579C13.3668 1.80474 14.6332 1.80474 15.4142 2.58579Z"
              stroke="currentColor"
              strokeWidth="1.5"
              fill="none"
            />
          </svg>
        </div>
        <div className="flex-1 min-w-0">
          <div className="text-sm font-medium text-main-view-fg">
            Updated artifact
          </div>
          <div className="text-xs text-main-view-fg/60 mt-1">
            {artifactAction.changes.description}
          </div>
          {artifactAction.changes.diff_preview && (
            <div className="text-xs text-main-view-fg/50 mt-2 font-mono truncate">
              {artifactAction.changes.diff_preview}
            </div>
          )}
        </div>
        <button
          onClick={handleOpenArtifact}
          disabled={loadingProposal}
          className="flex-shrink-0 px-3 py-1.5 text-xs font-medium rounded-md bg-blue-500/20 hover:bg-blue-500/30 transition-colors disabled:opacity-50"
        >
          {loadingProposal ? 'Loading...' : 'View Changes'}
        </button>
      </div>
    )
  }

  return null
}

