'use client'

import { useState } from 'react'
import { CheckSquare, Square } from 'lucide-react'
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from '@/components/ui/tooltip'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { PanelNavBar } from '@/components/shared/panel-nav-bar'
import { useShallow } from 'zustand/react/shallow'
import { useUserSettingsStore } from '@/stores/user-settings/store'
import { useProductWorkspaceStore } from '@/stores/product-workspace/store'
import {
  selectStoriesForActivePbi,
  selectStoryIsBlocked,
} from '@/stores/product-workspace/selectors'
import type { BacklogStory as WorkspaceStory } from '@/stores/product-workspace/types'
import { StoryDialog, type StoryDialogState } from './story-dialog'
import { debugProps } from '@/lib/debug'
import { BacklogCard } from './backlog-card'
import { EmptyPanel } from './empty-panel'
import { DemoTooltip } from '@/components/shared/demo-tooltip'
import { cn } from '@/lib/utils'

type SortMode = 'priority' | 'code' | 'date'
const STATUS_COLORS: Record<string, string> = {
  OPEN: 'bg-status-todo/15 text-status-todo border-status-todo/30',
  IN_SPRINT: '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> = {
  OPEN: 'Open',
  IN_SPRINT: 'In Sprint',
  DONE: 'Klaar',
}

export interface Story {
  id: string
  code: string | null
  title: string
  description: string | null
  acceptance_criteria: string | null
  priority: number
  sort_order: number
  status: string
  pbi_id: string
  sprint_id: string | null
  created_at: Date
}

interface StoryPanelProps {
  productId: string
  isDemo: boolean
  activeSprintId?: string | null
}

function StoryBlock({
  story,
  isSelected,
  cherrypick,
  onSelect,
  onEdit,
}: {
  story: Story
  isSelected: boolean
  cherrypick: {
    checked: boolean
    blocked: { sprintName: string } | null
    onToggle: () => void
  } | null
  onSelect: () => void
  onEdit: () => void
}) {
  return (
    <BacklogCard
      title={story.title}
      code={story.code}
      priority={story.priority}
      isSelected={isSelected}
      onClick={onSelect}
      badge={
        <Badge className={cn('text-[10px] px-1.5 py-0 border', STATUS_COLORS[story.status])}>
          {STATUS_LABELS[story.status] ?? story.status}
        </Badge>
      }
      actions={
        <div className="flex items-center gap-1">
          {cherrypick && <StoryCherrypickButton {...cherrypick} />}
          <button
            onClick={(e) => { e.stopPropagation(); onEdit() }}
            className="inline-flex items-center justify-center min-h-7 min-w-7 text-muted-foreground hover:text-foreground rounded transition-colors"
            aria-label="Story bewerken"
          >
            <svg className="size-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
              <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
            </svg>
          </button>
        </div>
      }
    />
  )
}

function StoryCherrypickButton({
  checked,
  blocked,
  onToggle,
}: {
  checked: boolean
  blocked: { sprintName: string } | null
  onToggle: () => void
}) {
  const icon = checked ? (
    <CheckSquare size={16} className="text-primary" />
  ) : (
    <Square size={16} />
  )
  if (blocked) {
    return (
      <TooltipProvider>
        <Tooltip>
          <TooltipTrigger
            data-disabled="true"
            aria-disabled="true"
            onClick={(e) => e.stopPropagation()}
            className="inline-flex items-center justify-center min-h-7 min-w-7 rounded opacity-40 cursor-not-allowed text-muted-foreground"
          >
            {icon}
          </TooltipTrigger>
          <TooltipContent>Zit in sprint {blocked.sprintName}</TooltipContent>
        </Tooltip>
      </TooltipProvider>
    )
  }
  return (
    <button
      onClick={(e) => {
        e.stopPropagation()
        onToggle()
      }}
      aria-pressed={checked}
      aria-label={
        checked ? 'Story uit sprint halen' : 'Story aan sprint toevoegen'
      }
      className={cn(
        'inline-flex items-center justify-center min-h-7 min-w-7 rounded transition-colors',
        'text-muted-foreground hover:text-foreground',
      )}
    >
      {icon}
    </button>
  )
}

// --- Main component ---
export function StoryPanel({ productId, isDemo, activeSprintId = null }: StoryPanelProps) {
  const selectedPbiId = useProductWorkspaceStore((s) => s.context.activePbiId)
  const selectedStoryId = useProductWorkspaceStore((s) => s.context.activeStoryId)
  const rawStories = useProductWorkspaceStore(useShallow(selectStoriesForActivePbi)) as WorkspaceStory[]
  const [filterStatus, setFilterStatus] = useState<string | null>(null)
  const [filterPriority, setFilterPriority] = useState<number | null>(null)
  const sortMode: SortMode = useUserSettingsStore(
    (s) => s.entities.settings.views?.storyPanel?.sort ?? 'priority',
  )
  const setPref = useUserSettingsStore((s) => s.setPref)
  const setSortMode = (v: SortMode) => void setPref(['views', 'storyPanel', 'sort'], v)
  const [storyDialogState, setStoryDialogState] = useState<StoryDialogState | null>(null)

  const base = rawStories
    .filter(s => !filterStatus || s.status === filterStatus)
    .filter(s => !filterPriority || s.priority === filterPriority)

  const filtered = [...base].sort((a, b) => {
    if (sortMode === 'code') {
      return (a.code ?? '').localeCompare(b.code ?? '', 'nl', { numeric: true })
    }
    if (sortMode === 'date') {
      return new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
    }
    return a.priority !== b.priority ? a.priority - b.priority : 0
  })

  const hasActiveFilters = filterStatus !== null || filterPriority !== null

  return (
    <div className="flex flex-col h-full" {...debugProps('story-panel', 'StoryPanel', 'components/backlog/story-panel.tsx')}>
      <PanelNavBar
        title="Stories"
        actions={
          <>
            {hasActiveFilters && (
              <button onClick={() => { setFilterStatus(null); setFilterPriority(null) }} className="text-xs text-primary hover:underline">
                Filter wissen ×
              </button>
            )}
            <Select value={sortMode} onValueChange={(v) => setSortMode(v as SortMode)}>
              <SelectTrigger className="h-7 w-28 text-xs">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="priority">Prioriteit</SelectItem>
                <SelectItem value="code">Code</SelectItem>
                <SelectItem value="date">Datum</SelectItem>
              </SelectContent>
            </Select>
            <Select
              value={filterStatus ?? 'all'}
              onValueChange={(v) => setFilterStatus(!v || v === 'all' ? null : v)}
            >
              <SelectTrigger className="h-7 w-24 text-xs">
                <SelectValue placeholder="Status" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">Alle</SelectItem>
                <SelectItem value="OPEN">Open</SelectItem>
                <SelectItem value="IN_SPRINT">In Sprint</SelectItem>
                <SelectItem value="DONE">Klaar</SelectItem>
              </SelectContent>
            </Select>
            {selectedPbiId && (
              <DemoTooltip show={isDemo}>
                <Button
                  size="sm"
                  className="h-7 text-xs"
                  disabled={isDemo}
                  onClick={() => !isDemo && setStoryDialogState({ mode: 'create', pbiId: selectedPbiId, productId, defaultPriority: 2 })}
                >
                  + Story
                </Button>
              </DemoTooltip>
            )}
          </>
        }
      />

      <div className="flex-1 overflow-y-auto p-4" {...debugProps('story-panel__tasks')}>
        {selectedPbiId === null ? (
          <EmptyPanel message="Selecteer een PBI om de stories te bekijken." />
        ) : rawStories.length === 0 ? (
          <EmptyPanel
            message="Nog geen stories voor dit PBI."
            action={{ label: 'Maak je eerste story aan', onClick: () => setStoryDialogState({ mode: 'create', pbiId: selectedPbiId, productId, defaultPriority: 2 }), disabled: isDemo }}
          />
        ) : (
          <div className="grid grid-cols-3 gap-2">
            {filtered.map(story => (
              <StoryBlockWithCherrypick
                key={story.id}
                story={story}
                productId={productId}
                activeSprintId={activeSprintId}
                isSelected={selectedStoryId === story.id}
                onSelect={() => useProductWorkspaceStore.getState().setActiveStory(story.id)}
                onEdit={() => setStoryDialogState({ mode: 'edit', story, productId })}
              />
            ))}
          </div>
        )}
      </div>

      <StoryDialog
        state={storyDialogState}
        onClose={() => setStoryDialogState(null)}
        isDemo={isDemo}
      />
    </div>
  )
}

// PBI-79 / ST-1337: wrapper rond StoryBlock met cherrypick-handling.
function StoryBlockWithCherrypick({
  story,
  productId,
  activeSprintId,
  isSelected,
  onSelect,
  onEdit,
}: {
  story: Story
  productId: string
  activeSprintId: string | null
  isSelected: boolean
  onSelect: () => void
  onEdit: () => void
}) {
  const draft = useUserSettingsStore(
    (s) => s.entities.settings.workflow?.pendingSprintDraft?.[productId],
  )
  const upsertStoryOverride = useUserSettingsStore((s) => s.upsertStoryOverride)
  const toggleStorySprintMembership = useProductWorkspaceStore(
    (s) => s.toggleStorySprintMembership,
  )
  const pending = useProductWorkspaceStore((s) => s.sprintMembership.pending)
  const blocked = useProductWorkspaceStore((s) =>
    selectStoryIsBlocked(s, story.id),
  )

  let cherrypick: {
    checked: boolean
    blocked: { sprintName: string } | null
    onToggle: () => void
  } | null = null

  if (draft) {
    const intent = draft.pbiIntent[story.pbi_id] ?? 'none'
    const override = draft.storyOverrides[story.pbi_id] ?? {
      add: [],
      remove: [],
    }
    const checked =
      (intent === 'all' && !override.remove.includes(story.id)) ||
      override.add.includes(story.id)
    cherrypick = {
      checked,
      blocked: blocked ? { sprintName: blocked.sprintName } : null,
      onToggle: () => {
        if (intent === 'all') {
          void upsertStoryOverride(
            productId,
            story.pbi_id,
            story.id,
            checked ? 'remove' : 'clear',
          )
        } else {
          void upsertStoryOverride(
            productId,
            story.pbi_id,
            story.id,
            checked ? 'clear' : 'add',
          )
        }
      },
    }
  } else if (activeSprintId) {
    const inSprintDb = story.sprint_id === activeSprintId
    const inAdds = pending.adds.includes(story.id)
    const inRemoves = pending.removes.includes(story.id)
    const checked = inAdds || (inSprintDb && !inRemoves)
    cherrypick = {
      checked,
      blocked: blocked ? { sprintName: blocked.sprintName } : null,
      onToggle: () => {
        toggleStorySprintMembership(story.id, inSprintDb)
      },
    }
  }

  return (
    <StoryBlock
      story={story}
      isSelected={isSelected}
      cherrypick={cherrypick}
      onSelect={onSelect}
      onEdit={onEdit}
    />
  )
}
