import { useEffect, useRef, useState } from 'react'
import type { ThreadSnap } from './model'
import type { CollabUser } from '../collab/user'

function timeAgo(ts: number): string {
  const s = Math.floor((Date.now() - ts) / 1000)
  if (s < 60) return 'just now'
  const m = Math.floor(s / 60)
  if (m < 60) return `${m}m`
  const h = Math.floor(m / 60)
  if (h < 24) return `${h}h`
  return `${Math.floor(h / 24)}d`
}

export interface NewComment {
  quote: string
}

export function CommentsPanel({
  threads,
  me,
  activeId,
  composing,
  onSubmitNew,
  onCancelNew,
  onReply,
  onResolve,
  onDelete,
  onFocus,
  onClose,
}: {
  threads: ThreadSnap[]
  me: CollabUser
  activeId: string | null
  composing: NewComment | null
  onSubmitNew: (text: string) => void
  onCancelNew: () => void
  onReply: (threadId: string, text: string) => void
  onResolve: (threadId: string, resolved: boolean) => void
  onDelete: (threadId: string) => void
  onFocus: (thread: ThreadSnap) => void
  onClose: () => void
}) {
  const open = threads.filter((t) => !t.resolved)
  const resolved = threads.filter((t) => t.resolved)
  open.sort((a, b) => (a.from ?? Infinity) - (b.from ?? Infinity))

  return (
    <aside className="comments">
      <div className="comments-head">
        <strong>Comments</strong>
        <span className="muted">{open.length} open</span>
        <span className="spacer" />
        <button className="icon-btn" onClick={onClose} title="Close">
          ✕
        </button>
      </div>

      <div className="comments-body">
        {composing && (
          <NewCommentCard composing={composing} onSubmit={onSubmitNew} onCancel={onCancelNew} />
        )}

        {open.length === 0 && !composing && (
          <p className="muted comments-empty">
            Select text in the editor and click <b>＋ Comment</b> to start a thread.
          </p>
        )}

        {open.map((t) => (
          <ThreadCard
            key={t.id}
            thread={t}
            me={me}
            active={t.id === activeId}
            onReply={onReply}
            onResolve={onResolve}
            onDelete={onDelete}
            onFocus={onFocus}
          />
        ))}

        {resolved.length > 0 && (
          <details className="resolved-group">
            <summary>Resolved ({resolved.length})</summary>
            {resolved.map((t) => (
              <ThreadCard
                key={t.id}
                thread={t}
                me={me}
                active={t.id === activeId}
                onReply={onReply}
                onResolve={onResolve}
                onDelete={onDelete}
                onFocus={onFocus}
              />
            ))}
          </details>
        )}
      </div>
    </aside>
  )
}

function NewCommentCard({
  composing,
  onSubmit,
  onCancel,
}: {
  composing: NewComment
  onSubmit: (text: string) => void
  onCancel: () => void
}) {
  const [text, setText] = useState('')
  const ref = useRef<HTMLTextAreaElement>(null)
  useEffect(() => ref.current?.focus(), [])
  return (
    <div className="thread-card composing">
      {composing.quote && <div className="quote">“{composing.quote}”</div>}
      <textarea
        ref={ref}
        className="reply-input"
        placeholder="Add a comment…"
        value={text}
        onChange={(e) => setText(e.target.value)}
        onKeyDown={(e) => {
          if (e.key === 'Enter' && (e.metaKey || e.ctrlKey) && text.trim()) onSubmit(text.trim())
        }}
      />
      <div className="thread-actions">
        <button className="btn-primary" disabled={!text.trim()} onClick={() => onSubmit(text.trim())}>
          Comment
        </button>
        <button className="btn-ghost" onClick={onCancel}>
          Cancel
        </button>
      </div>
    </div>
  )
}

function ThreadCard({
  thread,
  me,
  active,
  onReply,
  onResolve,
  onDelete,
  onFocus,
}: {
  thread: ThreadSnap
  me: CollabUser
  active: boolean
  onReply: (threadId: string, text: string) => void
  onResolve: (threadId: string, resolved: boolean) => void
  onDelete: (threadId: string) => void
  onFocus: (thread: ThreadSnap) => void
}) {
  const [text, setText] = useState('')
  const ref = useRef<HTMLDivElement>(null)
  useEffect(() => {
    if (active) ref.current?.scrollIntoView({ block: 'nearest', behavior: 'smooth' })
  }, [active])

  return (
    <div
      ref={ref}
      className={`thread-card${active ? ' active' : ''}${thread.resolved ? ' resolved' : ''}`}
    >
      <div className="quote" onClick={() => onFocus(thread)} title="Jump to text">
        {thread.from == null ? <span className="muted">(text removed)</span> : `“${thread.quote}”`}
      </div>

      {thread.replies.map((r) => (
        <div key={r.id} className="reply">
          <div className="reply-meta">
            <span className="dot" style={{ background: r.color }} />
            <span className="author">{r.author}</span>
            <span className="muted">{timeAgo(r.ts)}</span>
          </div>
          <div className="reply-text">{r.text}</div>
        </div>
      ))}

      <div className="reply-compose">
        <input
          className="reply-input one-line"
          placeholder="Reply…"
          value={text}
          onChange={(e) => setText(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === 'Enter' && text.trim()) {
              onReply(thread.id, text.trim())
              setText('')
            }
          }}
        />
      </div>

      <div className="thread-actions">
        <button className="btn-ghost" onClick={() => onResolve(thread.id, !thread.resolved)}>
          {thread.resolved ? 'Reopen' : 'Resolve'}
        </button>
        <button className="btn-ghost danger" onClick={() => onDelete(thread.id)}>
          Delete
        </button>
        <span className="spacer" />
        <span className="muted you-tag">{me.name}</span>
      </div>
    </div>
  )
}
