import { useEffect, useMemo, useRef, useState } from 'react'
import type { Plan, Task, Message, QueueItem } from '../lib/api'
import { api } from '../lib/api'
import { relativeTime, absoluteTime } from '../lib/time'
import { InlineCommentBox } from './InlineCommentBox'
import { EditableComment } from './EditableComment'

function duration(fromIso: string, toIso?: string): string {
  const from = new Date(fromIso).getTime()
  const to = toIso ? new Date(toIso).getTime() : Date.now()
  const sec = Math.max(0, Math.floor((to - from) / 1000))
  if (sec < 60) return `${sec}s`
  const min = Math.floor(sec / 60)
  if (min < 60) return `${min}m ${sec % 60}s`
  const hr = Math.floor(min / 60)
  if (hr < 24) return `${hr}h ${min % 60}m`
  const day = Math.floor(hr / 24)
  return `${day}d ${hr % 24}h`
}

const taskStatusGlyph: Record<string, string> = {
  queued: '○',
  in_progress: '◐',
  blocked: '■',
  complete: '●',
  returned: '↩',
}

const taskStatusColor: Record<string, string> = {
  queued: 'text-gray-400',
  in_progress: 'text-blue-500',
  blocked: 'text-yellow-500',
  complete: 'text-green-500',
  returned: 'text-red-500',
}

const roleColor: Record<string, string> = {
  director: 'text-blue-600 dark:text-blue-400',
  lead: 'text-emerald-600 dark:text-emerald-400',
  agent: 'text-amber-600 dark:text-amber-400',
  system: 'text-gray-500',
}

const priorityBadge: Record<string, string> = {
  critical: 'bg-red-600 text-white',
  '1': 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200',
  '2': 'bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200',
  '3': 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200',
  '4': 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200',
  '5': 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-400',
  backlog: 'bg-gray-50 text-gray-500 dark:bg-gray-800 dark:text-gray-500',
}

function MetaItem({ label, value, title }: { label: string; value: string; title?: string }) {
  return (
    <div className="flex flex-col gap-0.5" title={title}>
      <span className="font-mono text-[9px] uppercase tracking-[0.12em] text-gray-400 dark:text-gray-500">{label}</span>
      <span className="font-mono text-xs tabular text-gray-900 dark:text-gray-100">{value}</span>
    </div>
  )
}

// Wrapper that makes any region click-to-comment with refined hover affordance.
// The whole region is clickable; a "+ comment" chip appears top-right on hover
// as a secondary visual signal. Children stop propagation if they need to.
function Commentable({
  active,
  onActivate,
  children,
  className = '',
  chipLabel = 'comment',
  chipPosition = 'top-right',
}: {
  active: boolean
  onActivate: () => void
  children: React.ReactNode
  className?: string
  chipLabel?: string
  chipPosition?: 'top-right' | 'inline'
}) {
  return (
    <div
      onClick={(e) => {
        if (active) return
        // Don't activate if user is selecting text
        const sel = window.getSelection?.()
        if (sel && sel.toString().length > 0) return
        // Ignore clicks that originated on links or buttons
        const target = e.target as HTMLElement
        if (target.closest('button, a, textarea, input, [data-no-comment]')) return
        onActivate()
      }}
      className={`relative group/c rounded-md transition-colors cursor-text ${
        !active ? 'hover:bg-blue-50/50 dark:hover:bg-blue-950/20' : ''
      } ${className}`}
    >
      {/* Subtle left accent on hover */}
      {!active && (
        <span
          aria-hidden
          className="pointer-events-none absolute left-0 top-1.5 bottom-1.5 w-[2px] rounded-full bg-blue-400/0 group-hover/c:bg-blue-400/60 dark:group-hover/c:bg-blue-500/60 transition-colors"
        />
      )}
      {!active && chipPosition === 'top-right' && (
        <span className="pointer-events-none absolute top-2 right-2 font-mono text-[9px] uppercase tracking-wider text-blue-500/0 group-hover/c:text-blue-500 dark:group-hover/c:text-blue-400 transition-colors">
          + {chipLabel}
        </span>
      )}
      {children}
    </div>
  )
}

// Single message rendered as a card. If it's a director message, the body is editable.
function MessageCard({
  message,
  replies,
  activeReplyTarget,
  setActiveReplyTarget,
  postReply,
  editMessage,
}: {
  message: Message
  replies: Message[]
  activeReplyTarget: string | null
  setActiveReplyTarget: (key: string | null) => void
  postReply: (replyToId: number, text: string) => Promise<void>
  editMessage: (id: number, next: string) => Promise<void>
}) {
  const replyKey = `msg:${message.id}`
  const isOpen = activeReplyTarget === replyKey
  const isDirector = message.from_role === 'director'

  const inner = (
    <div className="border-l-2 border-gray-200 dark:border-gray-700 pl-3 py-1.5 pr-2">
      <div className="flex items-baseline gap-2 mb-1">
        <span className={`font-mono text-[10px] uppercase tracking-wider font-semibold ${roleColor[message.from_role] ?? 'text-gray-700'}`}>
          {message.from_role}
        </span>
        <span className="font-mono text-[10px] text-gray-500 dark:text-gray-400">{message.from_id}</span>
        <span className="font-mono text-[10px] tabular text-gray-400 dark:text-gray-500" title={absoluteTime(message.created_at)}>
          {relativeTime(message.created_at)}
        </span>
        {isDirector && (
          <span className="font-mono text-[9px] uppercase tracking-wider text-gray-400 ml-1">· editable</span>
        )}
      </div>
      {isDirector ? (
        <div className="text-sm text-gray-700 dark:text-gray-300 leading-relaxed">
          <EditableComment text={message.message} onSave={(next) => editMessage(message.id, next)} />
        </div>
      ) : (
        <div className="text-sm text-gray-700 dark:text-gray-300 leading-relaxed whitespace-pre-line">
          {message.message}
        </div>
      )}

      {isOpen && (
        <div data-no-comment>
          <InlineCommentBox
            placeholder="Reply to this message…"
            buttonLabel="reply"
            onCancel={() => setActiveReplyTarget(null)}
            onSubmit={async (text) => {
              await postReply(message.id, text)
              setActiveReplyTarget(null)
            }}
          />
        </div>
      )}
    </div>
  )

  return (
    <div>
      {isDirector ? (
        // Director messages: not click-to-comment (clicking edits via EditableComment)
        // but agents can still be replied to via the structure below.
        <div className="rounded-md">{inner}</div>
      ) : (
        <Commentable
          active={isOpen}
          onActivate={() => setActiveReplyTarget(replyKey)}
          chipLabel="reply"
        >
          {inner}
        </Commentable>
      )}

      {replies.length > 0 && (
        <div className="ml-5 mt-2 space-y-2">
          {replies.map((reply) => (
            <MessageCard
              key={reply.id}
              message={reply}
              replies={[]}
              activeReplyTarget={activeReplyTarget}
              setActiveReplyTarget={setActiveReplyTarget}
              postReply={postReply}
              editMessage={editMessage}
            />
          ))}
        </div>
      )}
    </div>
  )
}

interface PlanDetailProps {
  plan: Plan
  onClose: () => void
  reviewItem?: QueueItem
  onReviewActioned?: () => void
}

export function PlanDetail({ plan: initial, onClose, reviewItem, onReviewActioned }: PlanDetailProps) {
  const [plan, setPlan] = useState(initial)
  const [tasks, setTasks] = useState<Task[]>([])
  const [messages, setMessages] = useState<Message[]>([])
  const [actionBusy, setActionBusy] = useState(false)
  const [sendBackMode, setSendBackMode] = useState(false)
  const [sendBackText, setSendBackText] = useState('')
  const [activeReplyTarget, setActiveReplyTarget] = useState<string | null>(null)
  const verificationRef = useRef<HTMLDivElement>(null)

  function refresh() {
    api.plans.get(initial.id).then(setPlan).catch(() => {})
    api.tasks.list(initial.id).then(setTasks)
    api.messages.list(initial.id).then(setMessages)
  }

  useEffect(() => {
    refresh()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [initial.id])

  useEffect(() => {
    if (reviewItem && verificationRef.current) {
      verificationRef.current.scrollIntoView({ behavior: 'smooth', block: 'center' })
    }
  }, [reviewItem])

  // Esc closes any open inline editor
  useEffect(() => {
    function handler(e: KeyboardEvent) {
      if (e.key === 'Escape' && activeReplyTarget) {
        setActiveReplyTarget(null)
      }
    }
    window.addEventListener('keydown', handler)
    return () => window.removeEventListener('keydown', handler)
  }, [activeReplyTarget])

  const totalDuration = plan.completed_at && plan.started_at
    ? duration(plan.started_at, plan.completed_at)
    : plan.started_at
    ? duration(plan.started_at)
    : null

  const { topLevelMessages, repliesByMessageId, messagesByTaskId, verificationComments } = useMemo(() => {
    const byMsg = new Map<number, Message[]>()
    const byTask = new Map<number, Message[]>()
    const verif: Message[] = []
    const top: Message[] = []
    for (const m of messages) {
      if (m.reply_to_id != null) {
        const arr = byMsg.get(m.reply_to_id) ?? []
        arr.push(m)
        byMsg.set(m.reply_to_id, arr)
      } else if (m.task_id != null) {
        const arr = byTask.get(m.task_id) ?? []
        arr.push(m)
        byTask.set(m.task_id, arr)
      } else if (m.message_type === 'verification_comment') {
        verif.push(m)
      } else {
        top.push(m)
      }
    }
    return {
      topLevelMessages: top,
      repliesByMessageId: byMsg,
      messagesByTaskId: byTask,
      verificationComments: verif,
    }
  }, [messages])

  async function postComment(payload: {
    text: string
    taskId?: number
    replyToId?: number
    messageType?: string
  }) {
    await api.messages.create(plan.id, {
      from_role: 'director',
      from_id: 'joe',
      message: payload.text,
      message_type: payload.messageType ?? 'comment',
      task_id: payload.taskId,
      reply_to_id: payload.replyToId,
    })
    refresh()
  }

  async function editMessage(id: number, next: string) {
    await api.messages.update(id, next)
    refresh()
  }

  async function handleApprove() {
    if (!reviewItem || actionBusy) return
    setActionBusy(true)
    try {
      await api.queue.update(reviewItem.id, { status: 'approved' })
      onReviewActioned?.()
      onClose()
    } catch (err) {
      console.error('approve failed', err)
    } finally {
      setActionBusy(false)
    }
  }

  async function handleSendBack() {
    if (!reviewItem || actionBusy || !sendBackText.trim()) return
    setActionBusy(true)
    try {
      await postComment({ text: `Sent back: ${sendBackText.trim()}` })
      await api.queue.update(reviewItem.id, {
        status: 'redirected',
        director_notes: sendBackText.trim(),
      })
      setSendBackText('')
      setSendBackMode(false)
      onReviewActioned?.()
      onClose()
    } catch (err) {
      console.error('send back failed', err)
    } finally {
      setActionBusy(false)
    }
  }

  return (
    <div className="fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-50 p-4" onClick={onClose}>
      <div
        className="bg-white dark:bg-gray-900 rounded-xl w-full max-w-3xl max-h-[92vh] overflow-auto shadow-2xl border border-gray-200 dark:border-gray-700"
        onClick={(e) => e.stopPropagation()}
      >
        {reviewItem && (
          <div className="bg-gradient-to-r from-blue-50 to-blue-50/50 dark:from-blue-950/30 dark:to-blue-950/10 border-b border-blue-200 dark:border-blue-900 px-7 py-3 sticky top-0 z-10 backdrop-blur-sm">
            <div className="flex items-center gap-2">
              <span className="font-mono text-[10px] uppercase tracking-wider font-semibold text-blue-700 dark:text-blue-400">
                ⊙ Review mode
              </span>
              <span className="font-mono text-[10px] text-blue-600/70 dark:text-blue-400/70">
                · click any item to comment · click your own comments to edit
              </span>
            </div>
          </div>
        )}

        {/* Header */}
        <div className="px-7 pt-6 pb-5 border-b border-gray-200 dark:border-gray-700">
          <div className="flex items-start justify-between gap-4 mb-3">
            <h2 className="font-display text-2xl font-medium leading-tight text-gray-900 dark:text-gray-100">
              {plan.title}
            </h2>
            <div className="flex items-center gap-2 shrink-0">
              <span className={`text-[10px] font-mono font-medium uppercase tracking-wider px-2 py-1 rounded ${priorityBadge[plan.priority] ?? ''}`}>
                {plan.priority === 'critical' ? 'crit' : `p${plan.priority}`}
              </span>
              <button onClick={onClose} className="text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 text-2xl leading-none w-7 h-7 flex items-center justify-center cursor-pointer">&times;</button>
            </div>
          </div>

          <p className="text-sm text-gray-600 dark:text-gray-400 leading-relaxed mb-5">{plan.description}</p>

          <div className="flex flex-wrap gap-x-7 gap-y-3 pt-4 border-t border-gray-100 dark:border-gray-800">
            <MetaItem label="Plan #" value={String(plan.id)} />
            <MetaItem label="Team" value={plan.team} />
            <MetaItem label="Status" value={plan.status.replace(/_/g, ' ')} />
            <MetaItem label="Created" value={relativeTime(plan.created_at)} title={absoluteTime(plan.created_at)} />
            {plan.approved_at && <MetaItem label="Approved" value={relativeTime(plan.approved_at)} title={absoluteTime(plan.approved_at)} />}
            {plan.started_at && <MetaItem label="Picked up" value={relativeTime(plan.started_at)} title={absoluteTime(plan.started_at)} />}
            {plan.completed_at && <MetaItem label="Completed" value={relativeTime(plan.completed_at)} title={absoluteTime(plan.completed_at)} />}
            {totalDuration && <MetaItem label={plan.completed_at ? 'Took' : 'Running'} value={totalDuration} />}
          </div>
        </div>

        {/* Verification (review mode only) */}
        {reviewItem && (
          <div ref={verificationRef} className="px-7 py-5 border-b border-gray-200 dark:border-gray-700 bg-blue-50/30 dark:bg-blue-950/10">
            <div className="flex items-baseline justify-between mb-2">
              <h3 className="font-display text-base font-medium text-gray-900 dark:text-gray-100">Verification</h3>
              <span className="font-mono text-[10px] uppercase tracking-wider text-blue-600 dark:text-blue-400">
                {reviewItem.task_title ? `task: ${reviewItem.task_title}` : 'plan-level'}
              </span>
            </div>
            <Commentable
              active={activeReplyTarget === 'verification'}
              onActivate={() => setActiveReplyTarget('verification')}
              className="-mx-2 px-2 py-1.5"
            >
              {reviewItem.verification_notes ? (
                <div className="text-sm text-gray-700 dark:text-gray-300 leading-relaxed">
                  {reviewItem.verification_notes}
                </div>
              ) : (
                <div className="font-mono text-xs text-gray-500 italic">No verification notes recorded</div>
              )}
              <div className="mt-2 font-mono text-[10px] tabular text-gray-500 dark:text-gray-400">
                submitted {relativeTime(reviewItem.submitted_at)}
              </div>
              {activeReplyTarget === 'verification' && (
                <div data-no-comment>
                  <InlineCommentBox
                    placeholder="Comment on the verification…"
                    buttonLabel="post"
                    onCancel={() => setActiveReplyTarget(null)}
                    onSubmit={async (text) => {
                      await postComment({
                        text,
                        taskId: reviewItem.task_id,
                        messageType: 'verification_comment',
                      })
                      setActiveReplyTarget(null)
                    }}
                  />
                </div>
              )}
            </Commentable>

            {verificationComments.length > 0 && (
              <div className="mt-4 space-y-2">
                {verificationComments.map((c) => (
                  <MessageCard
                    key={c.id}
                    message={c}
                    replies={repliesByMessageId.get(c.id) ?? []}
                    activeReplyTarget={activeReplyTarget}
                    setActiveReplyTarget={setActiveReplyTarget}
                    postReply={async (rid, text) => { await postComment({ text, replyToId: rid }) }}
                    editMessage={editMessage}
                  />
                ))}
              </div>
            )}
          </div>
        )}

        {/* Tasks */}
        <section className="px-7 py-5 border-b border-gray-200 dark:border-gray-700">
          <div className="flex items-baseline justify-between mb-3">
            <h3 className="font-display text-base font-medium text-gray-900 dark:text-gray-100">Tasks</h3>
            <span className="font-mono text-[10px] uppercase tracking-wider text-gray-400">
              {tasks.filter((t) => t.status === 'complete').length} / {tasks.length} complete
            </span>
          </div>

          {tasks.length === 0 ? (
            <p className="font-mono text-xs text-gray-500 italic">No tasks yet — awaiting team lead decomposition</p>
          ) : (
            <div className="space-y-3">
              {tasks.map((task) => {
                const took = task.completed_at && task.started_at
                  ? duration(task.started_at, task.completed_at)
                  : task.started_at
                  ? duration(task.started_at)
                  : null
                const isReviewedTask = task.id === reviewItem?.task_id
                const taskKey = `task:${task.id}`
                const taskComments = messagesByTaskId.get(task.id) ?? []
                return (
                  <div
                    key={task.id}
                    className={isReviewedTask ? 'rounded-md ring-1 ring-blue-200 dark:ring-blue-900 bg-blue-50/40 dark:bg-blue-950/20' : ''}
                  >
                    <Commentable
                      active={activeReplyTarget === taskKey}
                      onActivate={() => setActiveReplyTarget(taskKey)}
                      className="px-3 py-2"
                    >
                      <div className="flex items-start gap-3">
                        <span className={`text-base leading-tight pt-0.5 ${taskStatusColor[task.status] ?? 'text-gray-400'}`} title={task.status}>
                          {taskStatusGlyph[task.status] ?? '○'}
                        </span>
                        <div className="flex-1 min-w-0">
                          <div className="flex items-baseline gap-2">
                            <span className="text-sm text-gray-900 dark:text-gray-100">{task.title}</span>
                            {task.assigned_agent && (
                              <span className="font-mono text-[10px] text-gray-400 dark:text-gray-500">
                                → {task.assigned_agent}
                              </span>
                            )}
                          </div>
                          {task.description && (
                            <div className="text-xs text-gray-500 dark:text-gray-400 mt-0.5 leading-relaxed">{task.description}</div>
                          )}
                          {task.progress_note && (
                            <div className="font-mono text-[10px] text-gray-400 dark:text-gray-500 mt-1 italic">
                              {task.progress_note}
                            </div>
                          )}
                          <div className="flex items-center gap-3 mt-1 font-mono text-[10px] tabular text-gray-400 dark:text-gray-500">
                            {task.started_at && (
                              <span title={absoluteTime(task.started_at)}>started {relativeTime(task.started_at)}</span>
                            )}
                            {took && (
                              <span className={task.completed_at ? 'text-gray-500 dark:text-gray-400' : 'text-blue-500'}>
                                {task.completed_at ? `took ${took}` : `${took} elapsed`}
                              </span>
                            )}
                          </div>

                          {activeReplyTarget === taskKey && (
                            <div data-no-comment>
                              <InlineCommentBox
                                placeholder={`Comment on "${task.title}"…`}
                                buttonLabel="post"
                                onCancel={() => setActiveReplyTarget(null)}
                                onSubmit={async (text) => {
                                  await postComment({ text, taskId: task.id })
                                  setActiveReplyTarget(null)
                                }}
                              />
                            </div>
                          )}

                          {taskComments.length > 0 && (
                            <div className="mt-3 space-y-2 border-l border-gray-200 dark:border-gray-700 pl-3" data-no-comment>
                              {taskComments.map((c) => (
                                <MessageCard
                                  key={c.id}
                                  message={c}
                                  replies={repliesByMessageId.get(c.id) ?? []}
                                  activeReplyTarget={activeReplyTarget}
                                  setActiveReplyTarget={setActiveReplyTarget}
                                  postReply={async (rid, text) => { await postComment({ text, replyToId: rid }) }}
                                  editMessage={editMessage}
                                />
                              ))}
                            </div>
                          )}
                        </div>
                      </div>
                    </Commentable>
                  </div>
                )
              })}
            </div>
          )}
        </section>

        {/* Activity */}
        <section className="px-7 py-5">
          <div className="flex items-baseline justify-between mb-3">
            <h3 className="font-display text-base font-medium text-gray-900 dark:text-gray-100">Activity</h3>
            <span className="font-mono text-[10px] uppercase tracking-wider text-gray-400">
              {messages.length} {messages.length === 1 ? 'message' : 'messages'}
            </span>
          </div>

          {topLevelMessages.length === 0 ? (
            <p className="font-mono text-xs text-gray-500 italic">No plan-level messages</p>
          ) : (
            <div className="space-y-3">
              {topLevelMessages.map((msg) => (
                <MessageCard
                  key={msg.id}
                  message={msg}
                  replies={repliesByMessageId.get(msg.id) ?? []}
                  activeReplyTarget={activeReplyTarget}
                  setActiveReplyTarget={setActiveReplyTarget}
                  postReply={async (rid, text) => { await postComment({ text, replyToId: rid }) }}
                  editMessage={editMessage}
                />
              ))}
            </div>
          )}

          <div className="mt-5 pt-4 border-t border-gray-100 dark:border-gray-800">
            {activeReplyTarget === 'plan' ? (
              <InlineCommentBox
                placeholder="Add a general note to this plan…"
                buttonLabel="post"
                onCancel={() => setActiveReplyTarget(null)}
                onSubmit={async (text) => {
                  await postComment({ text })
                  setActiveReplyTarget(null)
                }}
              />
            ) : (
              <button
                onClick={() => setActiveReplyTarget('plan')}
                className="font-mono text-[10px] uppercase tracking-wider text-gray-500 hover:text-blue-600 dark:hover:text-blue-400 cursor-pointer"
              >
                + add plan-level comment
              </button>
            )}
          </div>
        </section>

        {/* Sticky review actions */}
        {reviewItem && (
          <div className="sticky bottom-0 bg-white/95 dark:bg-gray-900/95 backdrop-blur-sm border-t border-gray-200 dark:border-gray-700 px-7 py-4">
            {sendBackMode ? (
              <div>
                <div className="flex items-baseline gap-2 mb-2">
                  <span className="font-mono text-[10px] uppercase tracking-wider font-semibold text-orange-600 dark:text-orange-400">
                    sending back —
                  </span>
                  <span className="font-mono text-[10px] text-orange-600/70 dark:text-orange-400/70">
                    explain what needs to change
                  </span>
                </div>
                <textarea
                  value={sendBackText}
                  onChange={(e) => setSendBackText(e.target.value)}
                  rows={3}
                  autoFocus
                  placeholder="Required: explain why and what to fix"
                  className="w-full px-3 py-2 rounded border border-orange-300 dark:border-orange-800 bg-white dark:bg-gray-800 text-sm text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-orange-200 dark:focus:ring-orange-900"
                />
                <div className="flex justify-end gap-2 mt-3">
                  <button
                    onClick={() => { setSendBackMode(false); setSendBackText('') }}
                    disabled={actionBusy}
                    className="px-3 py-1.5 rounded text-xs font-mono uppercase tracking-wider text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 cursor-pointer"
                  >
                    cancel
                  </button>
                  <button
                    onClick={handleSendBack}
                    disabled={actionBusy || !sendBackText.trim()}
                    className="px-4 py-1.5 rounded text-xs font-mono uppercase tracking-wider bg-orange-600 hover:bg-orange-700 text-white disabled:opacity-50 cursor-pointer"
                  >
                    {actionBusy ? 'sending…' : 'confirm send back'}
                  </button>
                </div>
              </div>
            ) : (
              <div className="flex items-center justify-between">
                <span className="font-mono text-[10px] text-gray-500 dark:text-gray-400">
                  ready to decide?
                </span>
                <div className="flex items-center gap-2">
                  <button
                    onClick={() => setSendBackMode(true)}
                    disabled={actionBusy}
                    className="px-4 py-1.5 rounded text-xs font-mono uppercase tracking-wider border border-orange-300 dark:border-orange-800 text-orange-700 dark:text-orange-400 hover:bg-orange-50 dark:hover:bg-orange-950/30 cursor-pointer"
                  >
                    send back
                  </button>
                  <button
                    onClick={handleApprove}
                    disabled={actionBusy}
                    className="px-5 py-1.5 rounded text-xs font-mono uppercase tracking-wider bg-emerald-600 hover:bg-emerald-700 text-white disabled:opacity-50 cursor-pointer"
                  >
                    {actionBusy ? 'approving…' : 'approve'}
                  </button>
                </div>
              </div>
            )}
          </div>
        )}
      </div>
    </div>
  )
}
