'use client'

import { useRef, useState, useTransition } from 'react'
import Link from 'next/link'
import { toast } from 'sonner'
import { Markdown } from '@/components/markdown'
import { Dialog, DialogContent, DialogTitle } from '@/components/ui/dialog'
import {
  entityDialogBodyClasses,
  entityDialogContentClasses,
  entityDialogFooterClasses,
} from '@/components/shared/entity-dialog-layout'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Textarea } from '@/components/ui/textarea'
import { DemoTooltip } from '@/components/shared/demo-tooltip'
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
import { useSoloStore } from '@/stores/solo-store'
import { enqueueClaudeJobAction, cancelClaudeJobAction } from '@/actions/claude-jobs'
import { cn } from '@/lib/utils'
import { getBranchUrl } from '@/lib/job-status-url'
import { debugProps } from '@/lib/debug'
import type { SoloTask } from './solo-board'

const STATUS_COLORS: Record<string, string> = {
  TO_DO: 'bg-status-todo/15 text-status-todo border-status-todo/30',
  IN_PROGRESS: 'bg-status-in-progress/15 text-status-in-progress border-status-in-progress/30',
  REVIEW: 'bg-status-in-progress/15 text-status-in-progress border-status-in-progress/30',
  DONE: 'bg-status-done/15 text-status-done border-status-done/30',
}

const STATUS_LABELS: Record<string, string> = {
  TO_DO: 'To Do',
  IN_PROGRESS: 'Bezig',
  REVIEW: 'Review',
  DONE: 'Klaar',
}

interface TaskDetailDialogProps {
  task: SoloTask | null
  productId: string
  isDemo: boolean
  repoUrl?: string | null
  onClose: () => void
}

interface TaskDetailContentProps {
  task: SoloTask
  productId: string
  isDemo: boolean
  repoUrl?: string | null
  onClose: () => void
}

const VERIFY_RESULT_CONFIG: Record<string, { label: string; className: string }> = {
  aligned:   { label: 'Aligned',   className: 'text-status-done' },
  partial:   { label: 'Gedeeltelijk', className: 'text-warning' },
  divergent: { label: 'Divergent', className: 'text-error' },
  empty:     { label: 'Geen wijzigingen', className: 'text-muted-foreground' },
}

type SaveState = 'idle' | 'saving' | 'saved'

const VERIFY_REQUIRED_LABELS: Record<string, string> = {
  ALIGNED: 'Strikt — alleen ALIGNED',
  ALIGNED_OR_PARTIAL: 'Standaard — ALIGNED of PARTIAL met uitleg',
  ANY: 'Vrij — geen verify-eis',
}

function TaskDetailContent({ task, productId, isDemo, repoUrl, onClose }: TaskDetailContentProps) {
  const { updatePlan, updateVerifyOnly, updateVerifyRequired } = useSoloStore()
  const job = useSoloStore(s => s.claudeJobsByTaskId[task.id])
  const connectedWorkers = useSoloStore(s => s.connectedWorkers)
  const [localPlan, setLocalPlan] = useState(task.implementation_plan ?? '')
  const [localVerifyOnly, setLocalVerifyOnly] = useState(task.verify_only)
  const [localVerifyRequired, setLocalVerifyRequired] = useState(task.verify_required)
  const [saveState, setSaveState] = useState<SaveState>('idle')
  const [, startTransition] = useTransition()
  const [jobPending, startJobTransition] = useTransition()
  const [verifyOnlyPending, startVerifyOnlyTransition] = useTransition()
  const [verifyRequiredPending, startVerifyRequiredTransition] = useTransition()
  const fadeTimer = useRef<ReturnType<typeof setTimeout> | null>(null)
  const savedPlanRef = useRef(task.implementation_plan ?? '')

  function handleEnqueue() {
    startJobTransition(async () => {
      const result = await enqueueClaudeJobAction(task.id)
      if ('error' in result) {
        toast.error(result.error)
      } else {
        toast.success('Agent ingeschakeld')
      }
    })
  }

  function handleCancel() {
    if (!job) return
    startJobTransition(async () => {
      const result = await cancelClaudeJobAction(job.job_id)
      if ('error' in result) toast.error(result.error)
    })
  }

  function handleBlur() {
    if (isDemo || localPlan === savedPlanRef.current) return

    setSaveState('saving')
    if (fadeTimer.current) clearTimeout(fadeTimer.current)

    // fetch naar Route Handler i.p.v. Server Action — Server Actions
    // kappen anders de open SSE-stream van het Solo Paneel af. Zie
    // notitie in solo-board.tsx handleDragEnd.
    startTransition(async () => {
      try {
        const res = await fetch(`/api/tasks/${task.id}`, {
          method: 'PATCH',
          headers: { 'Content-Type': 'application/json' },
          credentials: 'include',
          body: JSON.stringify({ implementation_plan: localPlan }),
        })
        if (!res.ok) {
          setSaveState('idle')
          toast.error('Implementatieplan opslaan mislukt')
          return
        }
        savedPlanRef.current = localPlan
        updatePlan(task.id, localPlan || null)
        setSaveState('saved')
        fadeTimer.current = setTimeout(() => setSaveState('idle'), 2000)
      } catch {
        setSaveState('idle')
        toast.error('Implementatieplan opslaan mislukt')
      }
    })
  }

  function handleVerifyOnlyToggle() {
    if (isDemo) return
    const newValue = !localVerifyOnly
    setLocalVerifyOnly(newValue)
    startVerifyOnlyTransition(async () => {
      try {
        const res = await fetch(`/api/tasks/${task.id}`, {
          method: 'PATCH',
          headers: { 'Content-Type': 'application/json' },
          credentials: 'include',
          body: JSON.stringify({ verify_only: newValue }),
        })
        if (!res.ok) {
          setLocalVerifyOnly(!newValue)
          toast.error('Verify-only bijwerken mislukt')
          return
        }
        updateVerifyOnly(task.id, newValue)
      } catch {
        setLocalVerifyOnly(!newValue)
        toast.error('Verify-only bijwerken mislukt')
      }
    })
  }

  function handleVerifyRequiredChange(e: React.ChangeEvent<HTMLSelectElement>) {
    if (isDemo) return
    const newValue = e.target.value as typeof localVerifyRequired
    const prevValue = localVerifyRequired
    setLocalVerifyRequired(newValue)
    startVerifyRequiredTransition(async () => {
      try {
        const res = await fetch(`/api/tasks/${task.id}`, {
          method: 'PATCH',
          headers: { 'Content-Type': 'application/json' },
          credentials: 'include',
          body: JSON.stringify({ verify_required: newValue }),
        })
        if (!res.ok) {
          setLocalVerifyRequired(prevValue)
          toast.error('Verify-required bijwerken mislukt')
          return
        }
        updateVerifyRequired(task.id, newValue)
      } catch {
        setLocalVerifyRequired(prevValue)
        toast.error('Verify-required bijwerken mislukt')
      }
    })
  }

  return (
    <>
      <div className="flex flex-col gap-1 px-6 pt-5 pb-4 border-b border-outline-variant shrink-0">
        <div className="flex items-start gap-3">
          <DialogTitle className="text-sm font-medium leading-snug flex-1">
            {task.title}
          </DialogTitle>
          {task.task_code && (
            <span className="font-mono text-[11px] text-muted-foreground border border-border rounded-md bg-surface-container px-1.5 py-0.5 shrink-0">
              {task.task_code}
            </span>
          )}
          <Badge className={cn('text-xs border shrink-0', STATUS_COLORS[task.status])}>
            {STATUS_LABELS[task.status]}
          </Badge>
        </div>
        <p className="text-xs text-muted-foreground">
          {task.story_code && <span className="font-mono mr-1">{task.story_code}</span>}
          {task.story_title}
        </p>
      </div>

      <div className={entityDialogBodyClasses} data-debug-id="task-detail-dialog__content">
        {task.description && (
          <div>
            <p className="text-xs font-medium text-muted-foreground mb-1.5">Beschrijving</p>
            <Markdown className="text-foreground">{task.description}</Markdown>
          </div>
        )}

        <div>
          <p className="text-xs font-medium text-muted-foreground mb-1.5">Implementatieplan</p>
          <DemoTooltip show={isDemo}>
            <Textarea
              value={localPlan}
              onChange={(e) => setLocalPlan(e.target.value)}
              onBlur={handleBlur}
              placeholder="Voeg een implementatieplan toe…"
              className="resize-none text-sm min-h-[120px] max-h-[40vh]"
              readOnly={isDemo}
            />
          </DemoTooltip>
          <div className="flex justify-end mt-1 h-4">
            {saveState === 'saving' && (
              <span className="text-xs text-muted-foreground">Bezig met opslaan…</span>
            )}
            {saveState === 'saved' && (
              <span className="text-xs text-status-done">Opgeslagen</span>
            )}
          </div>
        </div>

        <div className="flex items-center gap-2">
          <DemoTooltip show={isDemo}>
            <button
              type="button"
              role="checkbox"
              aria-checked={localVerifyOnly}
              onClick={handleVerifyOnlyToggle}
              disabled={isDemo || verifyOnlyPending}
              className={cn(
                'h-4 w-4 rounded border border-border flex items-center justify-center shrink-0',
                'disabled:cursor-not-allowed disabled:opacity-50',
                localVerifyOnly && 'bg-primary border-primary',
              )}
            >
              {localVerifyOnly && (
                <svg className="h-3 w-3 text-primary-foreground" viewBox="0 0 12 12" fill="none">
                  <path d="M2 6l3 3 5-5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              )}
            </button>
          </DemoTooltip>
          <span className="text-xs text-muted-foreground">Alleen verifiëren (niet implementeren)</span>
        </div>

        <div className="flex items-center gap-2">
          <span className="text-xs text-muted-foreground shrink-0">Verify-gate:</span>
          <DemoTooltip show={isDemo}>
            <select
              value={localVerifyRequired}
              onChange={handleVerifyRequiredChange}
              disabled={isDemo || verifyRequiredPending}
              className="text-xs rounded-md border border-border bg-surface-container px-2 py-1 text-foreground focus:outline-none focus:ring-1 focus:ring-primary disabled:cursor-not-allowed disabled:opacity-50"
            >
              {(['ALIGNED', 'ALIGNED_OR_PARTIAL', 'ANY'] as const).map(v => (
                <option key={v} value={v}>{VERIFY_REQUIRED_LABELS[v]}</option>
              ))}
            </select>
          </DemoTooltip>
        </div>
      </div>

      <div className={cn(entityDialogFooterClasses, 'flex flex-wrap items-center gap-2')}>
        <Link
          href={`/products/${productId}/sprint/planning`}
          className="text-xs text-primary hover:underline mr-auto"
          onClick={onClose}
        >
          Open in Sprint Board ↗
        </Link>

        {!isDemo && !job && (
          <TooltipProvider>
            <Tooltip>
              <TooltipTrigger
                render={
                  <Button
                    size="sm"
                    className="h-7 text-xs"
                    onClick={handleEnqueue}
                    disabled={jobPending || connectedWorkers === 0}
                  >
                    Voer uit
                  </Button>
                }
              />
              {connectedWorkers === 0 && (
                <TooltipContent side="top" className="max-w-xs text-xs">
                  Geen Claude Code-sessie verbonden. Start claude lokaal en zeg &apos;wacht op jobs&apos;.
                </TooltipContent>
              )}
            </Tooltip>
          </TooltipProvider>
        )}

        {job?.status === 'queued' && (
          <span className="text-xs text-muted-foreground">Wacht op agent…</span>
        )}

        {(job?.status === 'claimed' || job?.status === 'running') && (
          <>
            <span className="text-xs text-muted-foreground">Bezig: {job.summary ?? '…'}</span>
            <Button size="sm" variant="outline" className="h-7 text-xs" onClick={handleCancel} disabled={jobPending}>
              Annuleer
            </Button>
          </>
        )}

        {job?.status === 'done' && (
          <span className="text-xs text-status-done flex items-center gap-2 flex-wrap">
            Klaar{job.branch && !job.pushed_at ? ` — branch ${job.branch}` : ''}
            {job.pr_url && (
              <a
                href={job.pr_url}
                target="_blank"
                rel="noopener noreferrer"
                className="underline text-primary hover:text-primary/80"
              >
                Open PR
              </a>
            )}
            {!job.pr_url && job.pushed_at && job.branch && repoUrl && (
              <a
                href={getBranchUrl(repoUrl, job.branch)}
                target="_blank"
                rel="noopener noreferrer"
                className="underline text-primary hover:text-primary/80"
              >
                Open op GitHub
              </a>
            )}
            {job.verify_result && (() => {
              const cfg = VERIFY_RESULT_CONFIG[job.verify_result]
              return cfg ? (
                <TooltipProvider>
                  <Tooltip>
                    <TooltipTrigger render={
                      <span className={cn('font-medium cursor-default', cfg.className)}>
                        ▸ {cfg.label}
                      </span>
                    } />
                    <TooltipContent side="top" className="max-w-xs text-xs">
                      {job.verify_result === 'aligned' && 'De implementatie komt overeen met het plan.'}
                      {job.verify_result === 'partial' && 'De implementatie wijkt gedeeltelijk af van het plan.'}
                      {job.verify_result === 'divergent' && 'De implementatie wijkt significant af van het plan.'}
                      {job.verify_result === 'empty' && 'Er zijn geen codewijzigingen gedetecteerd.'}
                    </TooltipContent>
                  </Tooltip>
                </TooltipProvider>
              ) : null
            })()}
          </span>
        )}

        {job?.status === 'failed' && (
          <span className="text-xs text-error">Mislukt: {job.error}</span>
        )}
      </div>
    </>
  )
}

export function TaskDetailDialog({ task, productId, isDemo, repoUrl, onClose }: TaskDetailDialogProps) {
  return (
    <Dialog open={!!task} onOpenChange={(open) => { if (!open) onClose() }}>
      <DialogContent showCloseButton={false} className={entityDialogContentClasses} {...debugProps('task-detail-dialog', 'TaskDetailDialog', 'components/solo/task-detail-dialog.tsx')}>
        {task && (
          <TaskDetailContent
            key={task.id}
            task={task}
            productId={productId}
            isDemo={isDemo}
            repoUrl={repoUrl}
            onClose={onClose}
          />
        )}
      </DialogContent>
    </Dialog>
  )
}
