'use client'

import { useState } from 'react'
import { AlertTriangle, ArrowLeft } from 'lucide-react'
import { Drawer, ExternalLink } from '@/components/ui'
import { trufflehogDisplayFields } from '@/lib/trufflehogDisplay'
import { GraphNode } from '../../types'
import { badgeColors, getNodeColor, getNodeUrl } from '../../utils'
import { renderPropertyValue } from '../../utils/renderPropertyValue'
import { ClusterNodeList } from './ClusterNodeList'
import styles from './NodeDrawer.module.css'
import clusterStyles from './ClusterNodeList.module.css'

interface NodeDrawerProps {
  node: GraphNode | null
  isOpen: boolean
  onClose: () => void
  onDeleteNode?: (nodeId: string) => Promise<void>
  expandedChild?: GraphNode | null
  onExpandChild?: (child: GraphNode) => void
  onCollapseChild?: () => void
}

export function NodeDrawer({
  node,
  isOpen,
  onClose,
  onDeleteNode,
  expandedChild,
  onExpandChild,
  onCollapseChild,
}: NodeDrawerProps) {
  const [isDeleting, setIsDeleting] = useState(false)
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false)

  const handleDeleteClick = () => {
    setShowDeleteConfirm(true)
  }

  // Determine what to display:
  // - Root is a cluster with nothing expanded → show its child list
  // - Root is a cluster with expanded node that is ALSO a cluster → show that cluster's list (nested)
  // - Root is a cluster with expanded leaf node → show that leaf's properties
  // - Root is a regular node → show its properties
  const isCluster = !!node?.isCluster
  const topOfStack = expandedChild ?? null
  const showList = (isCluster && !topOfStack) || !!topOfStack?.isCluster
  const listCluster: GraphNode | null = topOfStack?.isCluster ? topOfStack : (isCluster ? node : null)
  const displayNode: GraphNode | null = showList ? null : (topOfStack ?? node)

  const handleDeleteConfirm = async () => {
    if (!displayNode || !onDeleteNode) return
    setIsDeleting(true)
    try {
      await onDeleteNode(displayNode.id)
      setShowDeleteConfirm(false)
      onClose()
    } finally {
      setIsDeleting(false)
    }
  }

  const handleDeleteCancel = () => {
    setShowDeleteConfirm(false)
  }

  const hiddenKeys = ['project_id', 'user_id']
  const sortedProperties = displayNode
    ? Object.entries(displayNode.properties || {})
        .filter(([key]) => !hiddenKeys.includes(key))
        .sort(([a], [b]) => {
          const bottomKeys = ['created_at', 'updated_at']
          const aIsBottom = bottomKeys.includes(a)
          const bIsBottom = bottomKeys.includes(b)
          if (aIsBottom && !bIsBottom) return 1
          if (!aIsBottom && bIsBottom) return -1
          if (aIsBottom && bIsBottom) return bottomKeys.indexOf(a) - bottomKeys.indexOf(b)
          return 0
        })
    : []

  const trufflehogFields = displayNode?.type === 'MultiscannerFinding'
    ? trufflehogDisplayFields((displayNode.properties ?? {}) as Record<string, unknown>)
    : []

  const drawerTitle = node
    ? showList && listCluster
      ? `Cluster: ${listCluster.clusterChildType ?? ''}`
      : displayNode
        ? `${displayNode.type}: ${displayNode.name}`
        : undefined
    : undefined

  return (
    <Drawer
      isOpen={isOpen}
      onClose={onClose}
      position="left"
      mode="overlay"
      title={drawerTitle}
    >
      {showList && listCluster && (
        <>
          {topOfStack && onCollapseChild && (
            <button
              className={clusterStyles.backBtn}
              onClick={onCollapseChild}
            >
              <ArrowLeft size={14} />
              Back
            </button>
          )}
          <ClusterNodeList
            cluster={listCluster}
            onSelectChild={(child) => onExpandChild?.(child)}
          />
        </>
      )}

      {displayNode && !showList && (
        <>
          {isCluster && onCollapseChild && (
            <button
              className={clusterStyles.backBtn}
              onClick={onCollapseChild}
            >
              <ArrowLeft size={14} />
              Back to list
            </button>
          )}

          <div className={styles.section}>
            <div className={styles.sectionHeader}>
              <h3 className={styles.sectionTitleBasicInfo}>Basic Info</h3>
              {displayNode.type !== 'Domain' && displayNode.type !== 'Subdomain' && onDeleteNode && (
                <button
                  className={styles.deleteButton}
                  onClick={handleDeleteClick}
                  disabled={isDeleting}
                  title="Delete node"
                >
                  {isDeleting ? '...' : '\uD83D\uDDD1'}
                </button>
              )}
            </div>
            <div className={styles.propertyRow}>
              <span className={styles.propertyKey}>Type</span>
              <span
                className={styles.propertyBadge}
                style={badgeColors(getNodeColor(displayNode))}
              >
                {displayNode.type}
              </span>
            </div>
            <div className={styles.propertyRow}>
              <span className={styles.propertyKey}>ID</span>
              <span className={styles.propertyValue}>{displayNode.id}</span>
            </div>
            <div className={styles.propertyRow}>
              <span className={styles.propertyKey}>Name</span>
              <span className={styles.propertyValue}>
                {(() => {
                  const url = getNodeUrl(displayNode)
                  return url
                    ? <ExternalLink href={url}>{displayNode.name}</ExternalLink>
                    : displayNode.name
                })()}
              </span>
            </div>
          </div>

          {/* A Secret Multiscanner finding's asset/location/extra_data are generic on the
              node — they must hold a repo AND an image AND a bucket. The
              per-source display registry says what they MEAN, so the drawer
              shows "Image / Layer / Tag" for a docker finding rather than three
              unlabelled strings and a JSON blob. */}
          {trufflehogFields.length > 0 && (
            <div className={styles.section}>
              <h3 className={styles.sectionTitleProperties}>Finding</h3>
              {trufflehogFields.map(({ label, value }) => (
                <div key={label} className={styles.propertyRow}>
                  <span className={styles.propertyKey}>{label}</span>
                  <span className={styles.propertyValue}>{value}</span>
                </div>
              ))}
            </div>
          )}

          <div className={styles.section}>
            <h3 className={styles.sectionTitleProperties}>Properties</h3>
            {sortedProperties.map(([key, value]) => {
              const nodeUrl = key === 'name' ? getNodeUrl(displayNode) : null
              return (
                <div key={key} className={styles.propertyRow}>
                  <span className={styles.propertyKey}>{key}</span>
                  <span className={styles.propertyValue}>
                    {nodeUrl
                      ? <ExternalLink href={nodeUrl}>{String(value)}</ExternalLink>
                      : renderPropertyValue(value)}
                  </span>
                </div>
              )
            })}
            {sortedProperties.length === 0 && (
              <p className={styles.emptyProperties}>No additional properties</p>
            )}
          </div>

          {/* Delete confirmation modal */}
          {showDeleteConfirm && (
            <div className={styles.confirmOverlay} onClick={handleDeleteCancel}>
              <div className={styles.confirmModal} onClick={(e) => e.stopPropagation()}>
                <div className={styles.confirmIcon}>
                  <AlertTriangle size={28} />
                </div>
                <h4 className={styles.confirmTitle}>Delete Node</h4>
                <p className={styles.confirmText}>
                  Deleting <strong>{displayNode.type}: {displayNode.name}</strong> will permanently remove
                  this node and all its relationships from the graph.
                </p>
                <p className={styles.confirmWarning}>
                  This may break the connectivity of the graph and affect
                  the agent&apos;s ability to interpret the attack chain context.
                </p>
                <div className={styles.confirmActions}>
                  <button
                    className={styles.confirmCancelBtn}
                    onClick={handleDeleteCancel}
                  >
                    Cancel
                  </button>
                  <button
                    className={styles.confirmDeleteBtn}
                    onClick={handleDeleteConfirm}
                    disabled={isDeleting}
                  >
                    {isDeleting ? 'Deleting...' : 'Delete'}
                  </button>
                </div>
              </div>
            </div>
          )}
        </>
      )}
    </Drawer>
  )
}
