import { useState, useEffect, useRef, useCallback } from 'react'
import {
  Copy, Check, SkipForward, Terminal, ChevronDown, ChevronUp,
  Send, Clipboard, Loader2, PanelRightClose, MessageCircleQuestion, Eye,
} from 'lucide-react'
import { cn } from '@/lib/utils'
import { toast } from '@/lib/toast'
import { aiSessionsApi } from '@/api/aiSessions'
import type { ActionItem, QuestionItem } from '@/types/ai-session'

// ── Types ──

type TaskState = 'pending' | 'active' | 'done' | 'skipped'

interface QuestionResponse {
  type: 'question'
  text: string
  context?: string
  state: TaskState
  value: string
}

interface ActionResponse {
  type: 'action'
  label: string
  command?: string | null
  description: string
  state: TaskState
  value: string
}

type TaskResponse = QuestionResponse | ActionResponse

interface TaskLaneProps {
  questions: QuestionItem[]
  actions: ActionItem[]
  sessionId?: string | null
  onSubmit: (responses: TaskResponse[]) => void
  onClose: () => void
  loading?: boolean
}

// ── Storage helpers ──

const TASK_LANE_STORAGE_KEY = 'rf-tasklane-state'

function saveTaskState(sessionId: string, tasks: TaskResponse[]) {
  try {
    sessionStorage.setItem(`${TASK_LANE_STORAGE_KEY}:${sessionId}`, JSON.stringify(tasks))
  } catch { /* quota exceeded — ignore */ }
}

function loadTaskState(sessionId: string): TaskResponse[] | null {
  try {
    const stored = sessionStorage.getItem(`${TASK_LANE_STORAGE_KEY}:${sessionId}`)
    return stored ? JSON.parse(stored) : null
  } catch { return null }
}

// eslint-disable-next-line react-refresh/only-export-components
export function clearTaskState(sessionId: string) {
  try { sessionStorage.removeItem(`${TASK_LANE_STORAGE_KEY}:${sessionId}`) } catch { /* ignore */ }
}

// ── Component ──

export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loading }: TaskLaneProps) {
  const [tasks, setTasks] = useState<TaskResponse[]>(() => {
    // Try to restore saved state for this session (preserves user's in-progress answers)
    if (sessionId) {
      const saved = loadTaskState(sessionId)
      if (saved && saved.length > 0) return saved
    }
    return [
      ...questions.map((q): QuestionResponse => ({
        type: 'question', text: q.text, context: q.context, state: 'pending', value: '',
      })),
      ...actions.map((a): ActionResponse => ({
        type: 'action', label: a.label, command: a.command, description: a.description, state: 'pending', value: '',
      })),
    ]
  })
  const [submitting, setSubmitting] = useState(false)
  const [showRunAll, setShowRunAll] = useState(false)
  const [showPreview, setShowPreview] = useState(false)

  // ── Resize state ──
  const DEFAULT_WIDTH = 340
  const MIN_WIDTH = 280
  const MAX_WIDTH_RATIO = 0.5 // 50vw

  const [panelWidth, setPanelWidth] = useState<number>(() => {
    const stored = localStorage.getItem('rf-tasklane-width')
    return stored ? Math.max(MIN_WIDTH, parseInt(stored, 10) || DEFAULT_WIDTH) : DEFAULT_WIDTH
  })
  const isDragging = useRef(false)
  const startX = useRef(0)
  const startWidth = useRef(0)

  const handleMouseMove = useCallback((e: MouseEvent) => {
    if (!isDragging.current) return
    const maxWidth = window.innerWidth * MAX_WIDTH_RATIO
    const deltaX = startX.current - e.clientX
    const newWidth = Math.min(maxWidth, Math.max(MIN_WIDTH, startWidth.current + deltaX))
    setPanelWidth(newWidth)
  }, [])

  const handleMouseUp = useCallback(() => {
    if (!isDragging.current) return
    isDragging.current = false
    document.body.style.cursor = ''
    document.body.style.userSelect = ''
    localStorage.setItem('rf-tasklane-width', String(Math.round(panelWidth)))
  }, [panelWidth])

  const handleMouseDown = useCallback((e: React.MouseEvent) => {
    e.preventDefault()
    isDragging.current = true
    startX.current = e.clientX
    startWidth.current = panelWidth
    document.body.style.cursor = 'col-resize'
    document.body.style.userSelect = 'none'
  }, [panelWidth])

  useEffect(() => {
    document.addEventListener('mousemove', handleMouseMove)
    document.addEventListener('mouseup', handleMouseUp)
    return () => {
      document.removeEventListener('mousemove', handleMouseMove)
      document.removeEventListener('mouseup', handleMouseUp)
    }
  }, [handleMouseMove, handleMouseUp])

  // Refs so the debounced save always uses the latest questions/actions/tasks
  const questionsRef = useRef(questions)
  const actionsRef = useRef(actions)
  const tasksRef = useRef(tasks)
  useEffect(() => { questionsRef.current = questions }, [questions])
  useEffect(() => { actionsRef.current = actions }, [actions])
  useEffect(() => { tasksRef.current = tasks }, [tasks])

  // Save task state to sessionStorage on every change + debounce to backend
  const saveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
  useEffect(() => {
    if (!sessionId) return
    saveTaskState(sessionId, tasks)
    // Debounce save to backend (2s after last change)
    if (saveTimerRef.current) clearTimeout(saveTimerRef.current)
    saveTimerRef.current = setTimeout(() => {
      aiSessionsApi.saveTaskLane(sessionId, {
        questions: questionsRef.current.map(q => ({ text: q.text, context: q.context })),
        actions: actionsRef.current.map(a => ({ label: a.label, command: a.command, description: a.description })),
        responses: tasksRef.current as unknown as Array<Record<string, unknown>>,
      }).catch(() => { /* silent — best-effort save */ })
    }, 2000)
    return () => { if (saveTimerRef.current) clearTimeout(saveTimerRef.current) }
  }, [sessionId, tasks]) // eslint-disable-line react-hooks/exhaustive-deps

  // Reset when new tasks come in from AI response — but preserve saved state
  useEffect(() => {
    if (sessionId) {
      const saved = loadTaskState(sessionId)
      if (saved && saved.length > 0) {
        // eslint-disable-next-line react-hooks/set-state-in-effect -- intentional: syncs derived state from prop changes
        setTasks(saved)
        return
      }
    }
    // eslint-disable-next-line react-hooks/set-state-in-effect -- intentional: syncs derived state from prop changes
    setTasks([
      ...questions.map((q): QuestionResponse => ({
        type: 'question', text: q.text, context: q.context, state: 'pending', value: '',
      })),
      ...actions.map((a): ActionResponse => ({
        type: 'action', label: a.label, command: a.command, description: a.description, state: 'pending', value: '',
      })),
    ])
  }, [questions, actions]) // eslint-disable-line react-hooks/exhaustive-deps

  const updateTask = (idx: number, updates: Partial<TaskResponse>) => {
    setTasks(prev => prev.map((t, i) => i === idx ? { ...t, ...updates } as TaskResponse : t))
  }

  const questionTasks = tasks.filter(t => t.type === 'question')
  const actionTasks = tasks.filter(t => t.type === 'action') as ActionResponse[]
  const allHandled = tasks.every(t => t.state === 'done' || t.state === 'skipped')
  const anyHandled = tasks.some(t => t.state === 'done' || t.state === 'skipped')
  const handledCount = tasks.filter(t => t.state === 'done' || t.state === 'skipped').length
  const doneCount = tasks.filter(t => t.state === 'done').length
  const totalCount = tasks.length

  const commandActions = actionTasks.filter(a => a.command)
  const combinedScript = commandActions.map((a, i) => (
    `# ── ${i + 1}. ${a.label} ──\n${a.command}`
  )).join('\n\n')

  const handleCopy = (text: string) => {
    navigator.clipboard.writeText(text)
    toast.success('Copied to clipboard')
  }

  const buildPreviewText = (): string => {
    const parts: string[] = []
    for (const t of tasks) {
      if (t.type === 'question') {
        const q = t as QuestionResponse
        const name = `Q: ${q.text}`
        if (q.state === 'done' && q.value.trim()) {
          parts.push(`**${name}:**\n\`\`\`\n${q.value.trim()}\n\`\`\``)
        } else if (q.state === 'skipped') {
          parts.push(`**${name}:** _(skipped)_`)
        }
      } else {
        const a = t as ActionResponse
        const name = a.label || 'Check'
        if (a.state === 'done' && a.value.trim()) {
          parts.push(`**${name}:**\n\`\`\`\n${a.value.trim()}\n\`\`\``)
        } else if (a.state === 'skipped') {
          parts.push(`**${name}:** _(skipped)_`)
        }
      }
    }
    return parts.join('\n\n') || '(No responses yet)'
  }

  const handleSubmit = () => {
    setSubmitting(true)
    onSubmit(tasks)
    // Don't self-hide — parent controls visibility via showTaskLane.
    // The AI response will either send updated tasks (replacing these)
    // or send none (parent hides the lane).
    setSubmitting(false)
  }

  return (
    <div
      className="relative border-l border-default flex flex-col shrink-0 animate-slide-in-right"
      style={{ background: 'var(--color-bg-page)', width: panelWidth }}
    >
      {/* Resize grip handle */}
      <div
        onMouseDown={handleMouseDown}
        className="absolute left-0 top-0 bottom-0 w-[6px] cursor-col-resize z-20 flex items-center justify-center group hover:bg-accent/10 transition-colors"
      >
        <div className="flex flex-col gap-[3px] opacity-0 group-hover:opacity-100 transition-opacity">
          {Array.from({ length: 6 }).map((_, i) => (
            <div key={i} className="w-[3px] h-[3px] rounded-full bg-muted-foreground" />
          ))}
        </div>
      </div>
      {/* Header */}
      <div className="px-4 py-3 border-b border-default flex items-center justify-between shrink-0" style={{ borderTop: '2px solid var(--color-accent)' }}>
        <h3 className="font-heading text-sm font-bold text-heading flex items-center gap-2">
          Tasks
          <span className={cn(
            'text-[10px] font-semibold px-2 py-0.5 rounded-full',
            allHandled
              ? 'bg-success-dim text-success'
              : 'bg-accent-dim text-accent-text'
          )}>
            {allHandled ? '✓ Ready' : `${doneCount}/${totalCount}`}
          </span>
        </h3>
        <button onClick={onClose} className="text-muted-foreground hover:text-heading transition-colors p-1" title="Collapse tasks">
          <PanelRightClose size={16} />
        </button>
      </div>

      {/* Body */}
      <div className="flex-1 overflow-y-auto p-3 space-y-4">

        {/* ── Questions Section ── */}
        {questionTasks.length > 0 && (
          <section>
            <div className="sticky top-0 z-10 pb-2" style={{ background: 'var(--color-bg-page)' }}>
              <div className="flex items-center gap-2 text-[10px] font-semibold uppercase tracking-[1.2px] text-muted-foreground pl-0.5">
                <span className="w-1.5 h-1.5 rounded-full bg-accent" />
                Questions
                {questionTasks.every(q => q.state === 'done' || q.state === 'skipped') && (
                  <Check size={10} className="text-success" />
                )}
              </div>
            </div>

            {tasks.map((task, idx) => {
              if (task.type !== 'question') return null
              const q = task as QuestionResponse

              if (q.state === 'done') {
                return (
                  <div key={idx} className="rounded-lg border-l-[3px] border-l-success border border-success/25 bg-success-dim/30 p-3 mb-2 cursor-pointer hover:border-success/40 transition-colors" onClick={() => updateTask(idx, { state: 'active' })}>
                    <div className="flex items-center gap-1.5">
                      <Check size={12} className="text-success shrink-0" />
                      <span className="text-[0.8125rem] text-foreground">{q.text}</span>
                    </div>
                    <div className="text-[0.75rem] text-muted-foreground mt-1 pl-5 italic truncate">"{q.value}"</div>
                  </div>
                )
              }

              if (q.state === 'skipped') {
                return (
                  <div key={idx} className="rounded-lg border border-default/50 bg-elevated/20 p-3 mb-2 opacity-60 cursor-pointer hover:opacity-80 hover:border-default transition-all" onClick={() => updateTask(idx, { state: 'pending' })} title="Click to restore">
                    <div className="flex justify-between">
                      <div className="text-[0.8125rem] text-muted-foreground line-through">{q.text}</div>
                      <span className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">Skipped</span>
                    </div>
                  </div>
                )
              }

              return (
                <div key={idx} className="rounded-lg border border-default bg-card p-3 mb-2">
                  <div className="text-[0.8125rem] text-heading leading-relaxed">{q.text}</div>
                  {q.context && (
                    <div className="text-[0.6875rem] text-muted-foreground mt-1">{q.context}</div>
                  )}
                  {q.state === 'active' ? (
                    <div className="mt-2">
                      <textarea
                        autoFocus
                        value={q.value}
                        onChange={e => updateTask(idx, { value: e.target.value })}
                        placeholder="Type your answer..."
                        className="w-full rounded-md border border-default bg-input px-3 py-2 text-[0.8125rem] text-heading placeholder:text-muted-foreground resize-y min-h-[48px] max-h-[150px] focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent/30"
                        rows={2}
                      />
                      <div className="mt-1.5 flex items-center gap-2">
                        <button
                          onClick={() => updateTask(idx, { state: 'done' })}
                          disabled={!q.value.trim()}
                          className="flex items-center gap-1 rounded-md bg-accent px-2.5 py-1 text-[0.75rem] font-medium text-white disabled:opacity-40 hover:bg-accent-hover transition-colors"
                        >
                          <Check size={11} /> Answer
                        </button>
                        <button
                          onClick={() => updateTask(idx, { state: 'pending', value: '' })}
                          className="text-[0.75rem] text-muted-foreground hover:text-heading"
                        >
                          Cancel
                        </button>
                      </div>
                    </div>
                  ) : (
                    <div className="mt-2 flex items-center gap-2">
                      <button
                        onClick={() => updateTask(idx, { state: 'active' })}
                        className="flex items-center gap-1 rounded-md border border-accent/40 bg-accent-dim/30 px-2.5 py-1.5 text-[0.75rem] font-medium text-accent-text hover:bg-accent-dim/50 transition-colors"
                      >
                        <MessageCircleQuestion size={11} /> Answer
                      </button>
                      <button
                        onClick={() => updateTask(idx, { state: 'skipped' })}
                        className="p-1.5 rounded-md text-muted-foreground hover:text-heading hover:bg-elevated/50 transition-colors"
                        title="Skip this question"
                      >
                        <SkipForward size={13} />
                      </button>
                    </div>
                  )}
                </div>
              )
            })}
          </section>
        )}

        {/* ── Checks Section ── */}
        {actionTasks.length > 0 && (
          <section>
            <div className="sticky top-0 z-10 pb-2" style={{ background: 'var(--color-bg-page)' }}>
              <div className="flex items-center gap-2 text-[10px] font-semibold uppercase tracking-[1.2px] text-muted-foreground pl-0.5">
                <span className="w-1.5 h-1.5 rounded-full bg-accent" />
                Diagnostic Checks
                {actionTasks.every(a => a.state === 'done' || a.state === 'skipped') && (
                  <Check size={10} className="text-success" />
                )}
              </div>
            </div>

            {/* Run All */}
            {commandActions.length > 1 && (
              <div className="mb-2">
                <button
                  onClick={() => setShowRunAll(!showRunAll)}
                  className="flex items-center gap-1.5 text-[0.75rem] font-medium text-accent-text hover:text-accent transition-colors pl-0.5"
                >
                  <Terminal size={12} />
                  Run All ({commandActions.length} commands)
                  {showRunAll ? <ChevronUp size={12} /> : <ChevronDown size={12} />}
                </button>
                {showRunAll && (
                  <div className="mt-2 rounded-lg border border-default bg-code p-3">
                    <div className="flex items-center justify-between mb-2">
                      <span className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">Combined script</span>
                      <button
                        onClick={() => handleCopy(combinedScript)}
                        className="flex items-center gap-1 text-[0.75rem] text-muted-foreground hover:text-heading"
                      >
                        <Copy size={11} /> Copy
                      </button>
                    </div>
                    <pre className="text-[0.75rem] font-mono text-heading whitespace-pre-wrap overflow-x-auto">{combinedScript}</pre>
                  </div>
                )}
              </div>
            )}

            {tasks.map((task, idx) => {
              if (task.type !== 'action') return null
              const a = task as ActionResponse

              if (a.state === 'done') {
                return (
                  <div key={idx} className="rounded-lg border-l-[3px] border-l-success border border-success/25 bg-success-dim/30 p-3 mb-2 cursor-pointer hover:border-success/40 transition-colors" onClick={() => updateTask(idx, { state: 'active' })}>
                    <div className="flex items-center gap-1.5">
                      <Check size={12} className="text-success shrink-0" />
                      <span className="text-[0.8125rem] font-medium text-foreground flex-1">{a.label}</span>
                    </div>
                  </div>
                )
              }

              if (a.state === 'skipped') {
                return (
                  <div key={idx} className="rounded-lg border border-default/50 bg-elevated/20 p-3 mb-2 opacity-60 cursor-pointer hover:opacity-80 hover:border-default transition-all" onClick={() => updateTask(idx, { state: 'pending' })} title="Click to restore">
                    <div className="flex justify-between">
                      <div className="text-[0.8125rem] text-muted-foreground line-through">{a.label}</div>
                      <span className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">Skipped</span>
                    </div>
                  </div>
                )
              }

              return (
                <div key={idx} className="rounded-lg border border-default bg-card p-3 mb-2 hover:border-hover transition-colors">
                  <div className="text-[0.8125rem] font-medium text-heading">{a.label}</div>
                  {a.description && (
                    <div className="text-[0.6875rem] text-muted-foreground mt-0.5 leading-relaxed">{a.description}</div>
                  )}

                  {a.command && (
                    <div className="mt-2 flex items-center gap-2 rounded bg-code px-2.5 py-1.5">
                      <code className="flex-1 text-[0.6875rem] font-mono text-heading truncate">{a.command}</code>
                      <button onClick={() => handleCopy(a.command!)} className="shrink-0 text-muted-foreground hover:text-heading" title="Copy">
                        <Copy size={11} />
                      </button>
                    </div>
                  )}

                  {a.state === 'active' ? (
                    <div className="mt-2">
                      <textarea
                        autoFocus
                        value={a.value}
                        onChange={e => updateTask(idx, { value: e.target.value })}
                        placeholder="Paste command output here..."
                        className="w-full rounded-md border border-default bg-input px-3 py-2 text-[0.8125rem] text-heading placeholder:text-muted-foreground font-mono resize-y min-h-[60px] max-h-[200px] overflow-y-auto focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent/30"
                        rows={3}
                      />
                      <div className="mt-1.5 flex items-center gap-2">
                        <button
                          onClick={() => updateTask(idx, { state: 'done' })}
                          disabled={!a.value.trim()}
                          className="flex items-center gap-1 rounded-md bg-accent px-2.5 py-1 text-[0.75rem] font-medium text-white disabled:opacity-40 hover:bg-accent-hover transition-colors"
                        >
                          <Check size={11} /> Done
                        </button>
                        <button
                          onClick={() => updateTask(idx, { state: 'pending', value: '' })}
                          className="text-[0.75rem] text-muted-foreground hover:text-heading"
                        >
                          Cancel
                        </button>
                      </div>
                    </div>
                  ) : (
                    <div className="mt-2 flex items-center gap-2">
                      <button
                        onClick={() => updateTask(idx, { state: 'active' })}
                        className="flex items-center gap-1 rounded-md border border-accent/40 bg-accent-dim/30 px-2.5 py-1.5 text-[0.75rem] font-medium text-accent-text hover:bg-accent-dim/50 transition-colors"
                      >
                        <Clipboard size={11} /> {a.command ? 'Paste Output' : 'Answer'}
                      </button>
                      <button
                        onClick={() => updateTask(idx, { state: 'skipped' })}
                        className="p-1.5 rounded-md text-muted-foreground hover:text-heading hover:bg-elevated/50 transition-colors"
                        title="Skip this check"
                      >
                        <SkipForward size={13} />
                      </button>
                    </div>
                  )}
                </div>
              )
            })}
          </section>
        )}
      </div>

      {/* Footer */}
      <div className="p-3 border-t border-default shrink-0">
        {/* Progress bar */}
        <div className="flex items-center gap-2 mb-2">
          <div className="flex gap-1 flex-1">
            {tasks.map((t, i) => (
              <div
                key={i}
                className={cn(
                  'flex-1 h-[5px] rounded-full transition-colors',
                  t.state === 'done' ? 'bg-success' :
                  t.state === 'skipped' ? 'bg-muted-foreground/30' :
                  t.state === 'active' ? 'bg-accent' :
                  'bg-border-default'
                )}
              />
            ))}
          </div>
          <span className="text-[0.625rem] font-medium text-muted-foreground tabular-nums shrink-0">
            {handledCount}/{totalCount}
          </span>
        </div>
        {/* Collapsible preview */}
        {anyHandled && (
          <div className="mb-2">
            <button
              onClick={() => setShowPreview(!showPreview)}
              className="flex items-center gap-1.5 text-[0.75rem] font-medium text-muted-foreground hover:text-heading transition-colors mb-1"
            >
              <Eye size={12} />
              Preview ({handledCount}/{totalCount} done)
              {showPreview ? <ChevronUp size={12} /> : <ChevronDown size={12} />}
            </button>
            {showPreview && (
              <div className="rounded-lg border border-default bg-code p-2.5 max-h-[150px] overflow-y-auto">
                <pre className="text-[0.6875rem] font-mono text-heading whitespace-pre-wrap">{buildPreviewText()}</pre>
              </div>
            )}
          </div>
        )}
        <button
          onClick={handleSubmit}
          disabled={!anyHandled || loading || submitting}
          className={cn(
            'w-full flex items-center justify-center gap-1.5 rounded-lg px-4 py-2.5 text-[0.8125rem] font-semibold transition-colors',
            anyHandled && !submitting
              ? 'bg-accent text-white hover:bg-accent-hover'
              : 'bg-elevated text-muted-foreground border border-default cursor-not-allowed'
          )}
        >
          {submitting ? (
            <><Loader2 size={14} className="animate-spin" /> Sending...</>
          ) : (
            <><Send size={14} /> {allHandled ? 'Send All Responses' : `Send ${handledCount} of ${totalCount} Responses`}</>
          )}
        </button>
      </div>
    </div>
  )
}
