import React, { useEffect, useRef, useState } from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faQuoteLeft, faExternalLinkAlt, faPlane, faSpinner, faHighlighter, faTrash, faEllipsisH, faMobileAlt } from '@fortawesome/free-solid-svg-icons'
import { faComments } from '@fortawesome/free-regular-svg-icons'
import { Highlight } from '../types/highlights'
import { useEventModel } from 'applesauce-react/hooks'
import { Models, IEventStore } from 'applesauce-core'
import { RelayPool } from 'applesauce-relay'
import { Hooks } from 'applesauce-react'
import { onSyncStateChange, isEventSyncing } from '../services/offlineSyncService'
import { RELAYS } from '../config/relays'
import { areAllRelaysLocal } from '../utils/helpers'
import { nip19 } from 'nostr-tools'
import { formatDateCompact } from '../utils/bookmarkUtils'
import { createDeletionRequest } from '../services/deletionService'
import ConfirmDialog from './ConfirmDialog'
import { getNostrUrl } from '../config/nostrGateways'
import CompactButton from './CompactButton'
import { HighlightCitation } from './HighlightCitation'

// Helper to detect if a URL is an image
const isImageUrl = (url: string): boolean => {
  try {
    const urlObj = new URL(url)
    const pathname = urlObj.pathname.toLowerCase()
    return /\.(jpg|jpeg|png|gif|webp|svg|bmp|ico)(\?.*)?$/.test(pathname)
  } catch {
    return false
  }
}

// Helper to render a nostr identifier
const renderNostrId = (nostrUri: string, index: number): JSX.Element => {
  try {
    // Remove nostr: prefix
    const identifier = nostrUri.replace(/^nostr:/, '')
    const decoded = nip19.decode(identifier)
    
    switch (decoded.type) {
      case 'npub': {
        const pubkey = decoded.data
        return (
          <a
            key={index}
            href={`/p/${nip19.npubEncode(pubkey)}`}
            className="highlight-comment-link"
            onClick={(e) => e.stopPropagation()}
          >
            @{pubkey.slice(0, 8)}...
          </a>
        )
      }
      case 'nprofile': {
        const { pubkey } = decoded.data
        const npub = nip19.npubEncode(pubkey)
        return (
          <a
            key={index}
            href={`/p/${npub}`}
            className="highlight-comment-link"
            onClick={(e) => e.stopPropagation()}
          >
            @{pubkey.slice(0, 8)}...
          </a>
        )
      }
      case 'naddr': {
        const { kind, pubkey, identifier } = decoded.data
        // Check if it's a blog post (kind:30023)
        if (kind === 30023) {
          const naddr = nip19.naddrEncode({ kind, pubkey, identifier })
          return (
            <a
              key={index}
              href={`/a/${naddr}`}
              className="highlight-comment-link"
              onClick={(e) => e.stopPropagation()}
            >
              {identifier || 'Article'}
            </a>
          )
        }
        // For other kinds, show shortened identifier
        return (
          <span key={index} className="highlight-comment-nostr-id">
            nostr:{identifier.slice(0, 12)}...
          </span>
        )
      }
      case 'note': {
        const eventId = decoded.data
        return (
          <span key={index} className="highlight-comment-nostr-id">
            note:{eventId.slice(0, 12)}...
          </span>
        )
      }
      case 'nevent': {
        const { id } = decoded.data
        return (
          <span key={index} className="highlight-comment-nostr-id">
            event:{id.slice(0, 12)}...
          </span>
        )
      }
      default:
        // Fallback for unrecognized types
        return (
          <span key={index} className="highlight-comment-nostr-id">
            {identifier.slice(0, 20)}...
          </span>
        )
    }
  } catch (error) {
    // If decoding fails, show shortened identifier
    const identifier = nostrUri.replace(/^nostr:/, '')
    return (
      <span key={index} className="highlight-comment-nostr-id">
        {identifier.slice(0, 20)}...
      </span>
    )
  }
}

// Component to render comment with links, inline images, and nostr identifiers
const CommentContent: React.FC<{ text: string }> = ({ text }) => {
  // Pattern to match both http(s) URLs and nostr: URIs
  const urlPattern = /((?:https?:\/\/|nostr:)[^\s]+)/g
  const parts = text.split(urlPattern)
  
  return (
    <>
      {parts.map((part, index) => {
        // Handle nostr: URIs
        if (part.startsWith('nostr:')) {
          return renderNostrId(part, index)
        }
        
        // Handle http(s) URLs
        if (part.match(/^https?:\/\//)) {
          if (isImageUrl(part)) {
            return (
              <img
                key={index}
                src={part}
                alt="Comment attachment"
                className="highlight-comment-image"
                loading="lazy"
              />
            )
          } else {
            return (
              <a
                key={index}
                href={part}
                target="_blank"
                rel="noopener noreferrer"
                className="highlight-comment-link"
                onClick={(e) => e.stopPropagation()}
              >
                {part}
              </a>
            )
          }
        }
        
        return <span key={index}>{part}</span>
      })}
    </>
  )
}

interface HighlightWithLevel extends Highlight {
  level?: 'mine' | 'friends' | 'nostrverse'
}

interface HighlightItemProps {
  highlight: HighlightWithLevel
  onSelectUrl?: (url: string) => void
  isSelected?: boolean
  onHighlightClick?: (highlightId: string) => void
  relayPool?: RelayPool | null
  eventStore?: IEventStore | null
  onHighlightUpdate?: (highlight: Highlight) => void
  onHighlightDelete?: (highlightId: string) => void
  showCitation?: boolean
}

export const HighlightItem: React.FC<HighlightItemProps> = ({ 
  highlight, 
  // onSelectUrl is not used but kept in props for API compatibility
  isSelected, 
  onHighlightClick,
  relayPool,
  eventStore,
  onHighlightUpdate,
  onHighlightDelete,
  showCitation = true
}) => {
  const itemRef = useRef<HTMLDivElement>(null)
  const menuRef = useRef<HTMLDivElement>(null)
  const [isSyncing, setIsSyncing] = useState(() => isEventSyncing(highlight.id))
  const [showOfflineIndicator, setShowOfflineIndicator] = useState(() => highlight.isOfflineCreated && !isSyncing)
  const [isRebroadcasting, setIsRebroadcasting] = useState(false)
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false)
  const [isDeleting, setIsDeleting] = useState(false)
  const [showMenu, setShowMenu] = useState(false)
  
  const activeAccount = Hooks.useActiveAccount()
  
  // Resolve the profile of the user who made the highlight
  const profile = useEventModel(Models.ProfileModel, [highlight.pubkey])
  
  // Get display name for the user
  const getUserDisplayName = () => {
    if (profile?.name) return profile.name
    if (profile?.display_name) return profile.display_name
    return `${highlight.pubkey.slice(0, 8)}...` // fallback to short pubkey
  }
  
  // Update offline indicator when highlight prop changes
  useEffect(() => {
    if (highlight.isOfflineCreated && !isSyncing) {
      setShowOfflineIndicator(true)
    }
  }, [highlight.isOfflineCreated, isSyncing])
  
  // Listen to sync state changes
  useEffect(() => {
    const unsubscribe = onSyncStateChange((eventId, syncingState) => {
      if (eventId === highlight.id) {
        setIsSyncing(syncingState)
        // When sync completes successfully, update highlight to show all relays
        if (!syncingState) {
          setShowOfflineIndicator(false)
          
          // Update the highlight with all relays after successful sync
          if (onHighlightUpdate && highlight.isLocalOnly) {
            const updatedHighlight = {
              ...highlight,
              publishedRelays: RELAYS,
              isLocalOnly: false,
              isOfflineCreated: false
            }
            onHighlightUpdate(updatedHighlight)
          }
        }
      }
    })
    
    return unsubscribe
  }, [highlight, onHighlightUpdate])
  
  useEffect(() => {
    if (isSelected && itemRef.current) {
      itemRef.current.scrollIntoView({ behavior: 'smooth', block: 'center' })
    }
  }, [isSelected])
  
  // Close menu when clicking outside
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
        setShowMenu(false)
      }
    }
    
    if (showMenu) {
      document.addEventListener('mousedown', handleClickOutside)
      return () => {
        document.removeEventListener('mousedown', handleClickOutside)
      }
    }
  }, [showMenu])
  
  const handleItemClick = () => {
    if (onHighlightClick) {
      onHighlightClick(highlight.id)
    }
  }
  
  const getHighlightLinks = () => {
    // Encode the highlight event itself (kind 9802) as a nevent
    // Get non-local relays for the hint
    const relayHints = RELAYS.filter(r => 
      !r.includes('localhost') && !r.includes('127.0.0.1')
    ).slice(0, 3) // Include up to 3 relay hints
    
    const nevent = nip19.neventEncode({
      id: highlight.id,
      relays: relayHints,
      author: highlight.pubkey,
      kind: 9802
    })
    
    return {
      portal: getNostrUrl(nevent),
      native: `nostr:${nevent}`
    }
  }
  
  const highlightLinks = getHighlightLinks()
  
  // Handle rebroadcast to all relays
  const handleRebroadcast = async (e: React.MouseEvent) => {
    e.stopPropagation() // Prevent triggering highlight selection
    
    if (!relayPool || !eventStore || isRebroadcasting) return
    
    setIsRebroadcasting(true)
    
    try {
      // Get the event from the event store
      const event = eventStore.getEvent(highlight.id)
      if (!event) {
        console.error('Event not found in store:', highlight.id)
        return
      }
      
      // Publish to all configured relays - let the relay pool handle connection state
      const targetRelays = RELAYS
      
      console.log('📡 Rebroadcasting highlight to', targetRelays.length, 'relay(s):', targetRelays)
      
      await relayPool.publish(targetRelays, event)
      
      console.log('✅ Rebroadcast successful!')
      
      // Update the highlight with new relay info
      const isLocalOnly = areAllRelaysLocal(targetRelays)
      const updatedHighlight = {
        ...highlight,
        publishedRelays: targetRelays,
        isLocalOnly,
        isOfflineCreated: false
      }
      
      // Notify parent of the update
      if (onHighlightUpdate) {
        onHighlightUpdate(updatedHighlight)
      }
      
      // Update local state
      setShowOfflineIndicator(false)
      
    } catch (error) {
      console.error('❌ Failed to rebroadcast:', error)
    } finally {
      setIsRebroadcasting(false)
    }
  }
  
  // Determine relay indicator icon and tooltip
  const getRelayIndicatorInfo = () => {
    // Show spinner if manually rebroadcasting OR auto-syncing
    if (isRebroadcasting || isSyncing) {
      return {
        icon: faSpinner,
        tooltip: isRebroadcasting ? 'rebroadcasting...' : 'syncing...',
        spin: true
      }
    }
    
    // Always show relay list, use plane icon for local-only
    const isLocalOrOffline = highlight.isLocalOnly || showOfflineIndicator
    
    // Show highlighter icon with relay info if available
    if (highlight.publishedRelays && highlight.publishedRelays.length > 0) {
      const relayNames = highlight.publishedRelays.map(url => 
        url.replace(/^wss?:\/\//, '').replace(/\/$/, '')
      )
      return {
        icon: isLocalOrOffline ? faPlane : faHighlighter,
        tooltip: relayNames.join('\n'),
        spin: false
      }
    }
    
    if (highlight.seenOnRelays && highlight.seenOnRelays.length > 0) {
      const relayNames = highlight.seenOnRelays.map(url => 
        url.replace(/^wss?:\/\//, '').replace(/\/$/, '')
      )
      return {
        icon: faHighlighter,
        tooltip: relayNames.join('\n'),
        spin: false
      }
    }
    
    // Fallback: show all relays we queried (where this was likely fetched from)
    const relayNames = RELAYS.map(url => 
      url.replace(/^wss?:\/\//, '').replace(/\/$/, '')
    )
    return {
      icon: faHighlighter,
      tooltip: relayNames.join('\n'),
      spin: false
    }
  }
  
  const relayIndicator = getRelayIndicatorInfo()
  
  // Check if current user can delete this highlight
  const canDelete = activeAccount && highlight.pubkey === activeAccount.pubkey
  
  const handleConfirmDelete = async () => {
    if (!activeAccount || !relayPool) {
      console.warn('Cannot delete: no account or relay pool')
      return
    }
    
    setIsDeleting(true)
    setShowDeleteConfirm(false)
    
    try {
      await createDeletionRequest(
        highlight.id,
        9802, // kind for highlights
        'Deleted by user',
        activeAccount,
        relayPool
      )
      
      console.log('✅ Highlight deletion request published')
      
      // Notify parent to remove this highlight from the list
      if (onHighlightDelete) {
        onHighlightDelete(highlight.id)
      }
    } catch (error) {
      console.error('Failed to delete highlight:', error)
    } finally {
      setIsDeleting(false)
    }
  }
  
  const handleCancelDelete = () => {
    setShowDeleteConfirm(false)
  }
  
  const handleMenuToggle = (e: React.MouseEvent) => {
    e.stopPropagation()
    setShowMenu(!showMenu)
  }
  
  const handleOpenPortal = (e: React.MouseEvent) => {
    e.stopPropagation()
    window.open(highlightLinks.portal, '_blank', 'noopener,noreferrer')
    setShowMenu(false)
  }

  const handleOpenNative = (e: React.MouseEvent) => {
    e.stopPropagation()
    window.location.href = highlightLinks.native
    setShowMenu(false)
  }
  
  const handleMenuDeleteClick = (e: React.MouseEvent) => {
    e.stopPropagation()
    setShowMenu(false)
    setShowDeleteConfirm(true)
  }
  
  return (
    <>
    <div 
      ref={itemRef} 
      className={`highlight-item ${isSelected ? 'selected' : ''} ${highlight.level ? `level-${highlight.level}` : ''}`} 
      data-highlight-id={highlight.id}
      onClick={handleItemClick}
      style={{ cursor: onHighlightClick ? 'pointer' : 'default' }}
    >
      <div className="highlight-header">
        <CompactButton
          className="highlight-timestamp"
          title={new Date(highlight.created_at * 1000).toLocaleString()}
          onClick={(e) => {
            e.stopPropagation()
            window.location.href = highlightLinks.native
          }}
        >
          {formatDateCompact(highlight.created_at)}
        </CompactButton>
      </div>
      
      <CompactButton
        className="highlight-quote-button"
        icon={faQuoteLeft}
        title="Quote"
        onClick={(e) => e.stopPropagation()}
      />
      
      {/* relay indicator lives in footer for consistent padding/alignment */}
      
      <div className="highlight-content">
        <blockquote className="highlight-text">
          {highlight.content}
        </blockquote>
        
        {showCitation && (
          <HighlightCitation
            highlight={highlight}
            relayPool={relayPool}
          />
        )}
        
        {highlight.comment && (
          <div className="highlight-comment">
            <FontAwesomeIcon icon={faComments} flip="horizontal" className="highlight-comment-icon" />
            <div className="highlight-comment-text">
              <CommentContent text={highlight.comment} />
            </div>
          </div>
        )}
        
        
        <div className="highlight-footer">
          <div className="highlight-footer-left">
            {relayIndicator && (
              <CompactButton
                className="highlight-relay-indicator"
                icon={relayIndicator.icon}
                spin={relayIndicator.spin}
                title={relayIndicator.tooltip}
                onClick={handleRebroadcast}
                disabled={!relayPool || !eventStore}
              />
            )}
            
            <span className="highlight-author">
              {getUserDisplayName()}
            </span>
          </div>
          
          <div className="highlight-menu-wrapper" ref={menuRef}>
            <CompactButton
              icon={faEllipsisH}
              onClick={handleMenuToggle}
              title="More options"
            />
            
            {showMenu && (
              <div className="highlight-menu">
                <button
                  className="highlight-menu-item"
                  onClick={handleOpenPortal}
                >
                  <FontAwesomeIcon icon={faExternalLinkAlt} />
                  <span>Open on Nostr</span>
                </button>
                <button
                  className="highlight-menu-item"
                  onClick={handleOpenNative}
                >
                  <FontAwesomeIcon icon={faMobileAlt} />
                  <span>Open with Native App</span>
                </button>
                {canDelete && (
                  <button
                    className="highlight-menu-item highlight-menu-item-danger"
                    onClick={handleMenuDeleteClick}
                    disabled={isDeleting}
                  >
                    <FontAwesomeIcon icon={isDeleting ? faSpinner : faTrash} spin={isDeleting} />
                    <span>Delete</span>
                  </button>
                )}
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
    
    <ConfirmDialog
      isOpen={showDeleteConfirm}
      title="Delete Highlight?"
      message="This will request deletion of your highlight. It may still be visible on some relays that don't honor deletion requests."
      confirmText="Delete"
      cancelText="Cancel"
      variant="danger"
      onConfirm={handleConfirmDelete}
      onCancel={handleCancelDelete}
    />
    </>
  )
}

