import { useState, useMemo, useEffect, useRef } from 'react'
import ReactDOM from 'react-dom'
import { useTripStore } from '../../store/tripStore'
import { useCanDo } from '../../store/permissionsStore'
import { useToast } from '../shared/Toast'
import { useTranslation } from '../../i18n'
import { tripsApi } from '../../api/client'
import apiClient from '../../api/client'
import CustomSelect from '../shared/CustomSelect'
import { CustomDatePicker } from '../shared/CustomDateTimePicker'
import { formatDate as fmtDate } from '../../utils/formatters'
import {
  CheckSquare, Square, Plus, ChevronRight, Flag,
  X, Check, Calendar, User, FolderPlus, AlertCircle, ListChecks, Inbox, CheckCheck, Trash2,
} from 'lucide-react'
import type { TodoItem } from '../../types'

const KAT_COLORS = [
  '#3b82f6', '#a855f7', '#ec4899', '#22c55e', '#f97316',
  '#06b6d4', '#ef4444', '#eab308', '#8b5cf6', '#14b8a6',
]

const PRIO_CONFIG: Record<number, { label: string; color: string }> = {
  1: { label: 'P1', color: '#ef4444' },
  2: { label: 'P2', color: '#f59e0b' },
  3: { label: 'P3', color: '#3b82f6' },
}

function katColor(kat: string, allCategories: string[]) {
  const idx = allCategories.indexOf(kat)
  if (idx >= 0) return KAT_COLORS[idx % KAT_COLORS.length]
  let h = 0
  for (let i = 0; i < kat.length; i++) h = ((h << 5) - h + kat.charCodeAt(i)) | 0
  return KAT_COLORS[Math.abs(h) % KAT_COLORS.length]
}

type FilterType = 'all' | 'my' | 'overdue' | 'done' | string

interface Member { id: number; username: string; avatar: string | null }

export default function TodoListPanel({ tripId, items, addItemSignal = 0 }: { tripId: number; items: TodoItem[]; addItemSignal?: number }) {
  const { addTodoItem, updateTodoItem, deleteTodoItem, toggleTodoItem } = useTripStore()
  const canEdit = useCanDo('packing_edit')
  const toast = useToast()
  const { t, locale } = useTranslation()
  const formatDate = (d: string) => fmtDate(d, locale) || d

  const [isMobile, setIsMobile] = useState(() => window.innerWidth < 768)
  useEffect(() => {
    const mq = window.matchMedia('(max-width: 767px)')
    const handler = (e: MediaQueryListEvent) => setIsMobile(e.matches)
    mq.addEventListener('change', handler)
    return () => mq.removeEventListener('change', handler)
  }, [])

  const [filter, setFilter] = useState<FilterType>('all')
  const [selectedId, setSelectedId] = useState<number | null>(null)
  const [isAddingNew, setIsAddingNew] = useState(false)
  const lastHandledAddSignal = useRef(addItemSignal)

  useEffect(() => {
    if (addItemSignal !== lastHandledAddSignal.current && addItemSignal > 0) {
      setSelectedId(null)
      setIsAddingNew(true)
    }
    lastHandledAddSignal.current = addItemSignal
  }, [addItemSignal])
  const [sortByPrio, setSortByPrio] = useState(false)
  const [addingCategory, setAddingCategory] = useState(false)
  const [newCategoryName, setNewCategoryName] = useState('')
  const [members, setMembers] = useState<Member[]>([])
  const [currentUserId, setCurrentUserId] = useState<number | null>(null)

  useEffect(() => {
    apiClient.get(`/trips/${tripId}/members`).then(r => {
      const owner = r.data?.owner
      const mems = r.data?.members || []
      const all = owner ? [owner, ...mems] : mems
      setMembers(all)
      setCurrentUserId(r.data?.current_user_id || null)
    }).catch(() => {})
  }, [tripId])

  const categories = useMemo(() => {
    const cats = new Set<string>()
    items.forEach(i => { if (i.category) cats.add(i.category) })
    return Array.from(cats).sort()
  }, [items])

  const today = new Date().toISOString().split('T')[0]

  const filtered = useMemo(() => {
    let result: TodoItem[]
    if (filter === 'all') result = items.filter(i => !i.checked)
    else if (filter === 'done') result = items.filter(i => !!i.checked)
    else if (filter === 'my') result = items.filter(i => !i.checked && i.assigned_user_id === currentUserId)
    else if (filter === 'overdue') result = items.filter(i => !i.checked && i.due_date && i.due_date < today)
    else result = items.filter(i => i.category === filter)
    if (sortByPrio) result = [...result].sort((a, b) => {
      const ap = a.priority || 99
      const bp = b.priority || 99
      return ap - bp
    })
    return result
  }, [items, filter, currentUserId, today, sortByPrio])

  const selectedItem = items.find(i => i.id === selectedId) || null
  const totalCount = items.length
  const doneCount = items.filter(i => !!i.checked).length
  const overdueCount = items.filter(i => !i.checked && i.due_date && i.due_date < today).length
  const myCount = currentUserId ? items.filter(i => !i.checked && i.assigned_user_id === currentUserId).length : 0

  const addCategory = () => {
    const name = newCategoryName.trim()
    if (!name || categories.includes(name)) { setAddingCategory(false); setNewCategoryName(''); return }
    addTodoItem(tripId, { name: t('todo.newItem'), category: name } as any)
      .then(() => { setAddingCategory(false); setNewCategoryName(''); setFilter(name) })
      .catch(err => toast.error(err instanceof Error ? err.message : t('common.error')))
  }

  // Get category count (non-done items)
  const catCount = (cat: string) => items.filter(i => i.category === cat && !i.checked).length

  // Sidebar filter item
  const SidebarItem = ({ id, icon: Icon, label, count, color }: { id: string; icon: any; label: string; count: number; color?: string }) => (
    <button onClick={() => setFilter(id as FilterType)}
      title={isMobile ? label : undefined}
      style={{
        display: 'flex', alignItems: 'center', justifyContent: isMobile ? 'center' : 'flex-start',
        gap: isMobile ? 0 : 8, width: '100%', padding: isMobile ? '8px 0' : '7px 12px',
        border: 'none', borderRadius: 8, cursor: 'pointer', fontFamily: 'inherit', fontSize: 13,
        background: filter === id ? 'var(--bg-hover)' : 'transparent',
        color: filter === id ? 'var(--text-primary)' : 'var(--text-secondary)',
        fontWeight: filter === id ? 600 : 400, transition: 'all 0.1s',
        position: 'relative',
      }}
      onMouseEnter={e => { if (filter !== id) e.currentTarget.style.background = 'var(--bg-hover)' }}
      onMouseLeave={e => { if (filter !== id) e.currentTarget.style.background = 'transparent' }}>
      {color ? (
        <span style={{ width: isMobile ? 12 : 10, height: isMobile ? 12 : 10, borderRadius: '50%', background: color, flexShrink: 0 }} />
      ) : (
        <Icon size={isMobile ? 18 : 15} style={{ flexShrink: 0, opacity: 0.7 }} />
      )}
      {!isMobile && <span style={{ flex: 1, textAlign: 'left' }}>{label}</span>}
      {!isMobile && count > 0 && (
        <span style={{ fontSize: 11, color: 'var(--text-faint)', background: 'var(--bg-hover)', borderRadius: 10, padding: '1px 7px', minWidth: 20, textAlign: 'center' }}>
          {count}
        </span>
      )}
      {isMobile && count > 0 && (
        <span style={{ position: 'absolute', top: 2, right: 2, fontSize: 8, fontWeight: 700, color: 'var(--bg-primary)', background: 'var(--text-faint)', borderRadius: '50%', width: 14, height: 14, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          {count}
        </span>
      )}
    </button>
  )

  // Filter title
  const filterTitle = (() => {
    if (filter === 'all') return t('todo.filter.all')
    if (filter === 'done') return t('todo.filter.done')
    if (filter === 'my') return t('todo.filter.my')
    if (filter === 'overdue') return t('todo.filter.overdue')
    return filter
  })()

  return (
    <div style={{ display: 'flex', height: 'calc(100vh - 180px)', minHeight: 400 }}>

      {/* ── Left Sidebar ── */}
      <div style={{
        width: isMobile ? 52 : 220, flexShrink: 0, borderRight: '1px solid var(--border-faint)',
        padding: isMobile ? '12px 6px' : '16px 12px 16px 0', display: 'flex', flexDirection: 'column', gap: 2, overflowY: 'auto',
        transition: 'width 0.2s',
      }}>
        {/* Progress Card */}
        {!isMobile && <div style={{
          margin: '0 0 12px', padding: '14px 14px 12px', borderRadius: 14,
          background: 'var(--bg-hover)',
          border: '1px solid var(--border-primary)',
          boxShadow: '0 1px 2px rgba(0,0,0,0.02)',
        }}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 4, marginBottom: 8 }}>
            <span style={{ fontSize: 18, fontWeight: 700, color: 'var(--text-primary)', lineHeight: 1, letterSpacing: '-0.02em' }}>
              {totalCount > 0 ? Math.round((doneCount / totalCount) * 100) : 0}%
            </span>
          </div>
          <div style={{ height: 4, background: 'var(--border-faint)', borderRadius: 2, overflow: 'hidden', marginBottom: 6 }}>
            <div style={{ height: '100%', width: totalCount > 0 ? `${Math.round((doneCount / totalCount) * 100)}%` : '0%', background: '#22c55e', borderRadius: 2, transition: 'width 0.3s' }} />
          </div>
          <div style={{ fontSize: 11, color: 'var(--text-faint)' }}>
            {doneCount} / {totalCount} {t('todo.completed')}
          </div>
        </div>}

        {/* Smart filters */}
        {!isMobile && <div style={{ fontSize: 10, fontWeight: 600, color: 'var(--text-faint)', padding: '8px 12px 4px', textTransform: 'uppercase', letterSpacing: '0.05em' }}>
          {t('todo.sidebar.tasks')}
        </div>}
        <SidebarItem id="all" icon={Inbox} label={t('todo.filter.all')} count={items.filter(i => !i.checked).length} />
        <SidebarItem id="my" icon={User} label={t('todo.filter.my')} count={myCount} />
        <SidebarItem id="overdue" icon={AlertCircle} label={t('todo.filter.overdue')} count={overdueCount} />
        <SidebarItem id="done" icon={CheckCheck} label={t('todo.filter.done')} count={doneCount} />

        {/* Sort by */}
        {!isMobile && <div style={{ fontSize: 10, fontWeight: 600, color: 'var(--text-faint)', padding: '16px 12px 4px', textTransform: 'uppercase', letterSpacing: '0.05em' }}>
          {t('todo.sidebar.sortBy')}
        </div>}
        <button onClick={() => setSortByPrio(v => !v)}
          title={isMobile ? t('todo.priority') : undefined}
          style={{
            display: 'flex', alignItems: 'center', justifyContent: isMobile ? 'center' : 'flex-start',
            gap: isMobile ? 0 : 8, width: '100%', padding: isMobile ? '8px 0' : '7px 12px',
            border: 'none', borderRadius: 8, cursor: 'pointer', fontFamily: 'inherit', fontSize: 13,
            background: sortByPrio ? '#f59e0b12' : 'transparent',
            color: sortByPrio ? '#f59e0b' : 'var(--text-secondary)',
            fontWeight: sortByPrio ? 600 : 400, transition: 'all 0.1s',
          }}
          onMouseEnter={e => { if (!sortByPrio) e.currentTarget.style.background = 'var(--bg-hover)' }}
          onMouseLeave={e => { if (!sortByPrio) e.currentTarget.style.background = 'transparent' }}>
          <Flag size={isMobile ? 18 : 15} style={{ flexShrink: 0, opacity: 0.7 }} />
          {!isMobile && <span style={{ flex: 1, textAlign: 'left' }}>{t('todo.priority')}</span>}
        </button>

        {/* Categories */}
        {!isMobile && <div style={{ fontSize: 10, fontWeight: 600, color: 'var(--text-faint)', padding: '16px 12px 4px', textTransform: 'uppercase', letterSpacing: '0.05em' }}>
          {t('todo.sidebar.categories')}
        </div>}
        {isMobile && <div style={{ height: 1, background: 'var(--border-faint)', margin: '8px 4px' }} />}
        {categories.map(cat => (
          <SidebarItem key={cat} id={cat} icon={null} label={cat} count={catCount(cat)} color={katColor(cat, categories)} />
        ))}

        {canEdit && (
          addingCategory && !isMobile ? (
            <div style={{ display: 'flex', alignItems: 'center', gap: 4, padding: '4px 12px' }}>
              <input autoFocus value={newCategoryName} onChange={e => setNewCategoryName(e.target.value)}
                onKeyDown={e => { if (e.key === 'Enter') addCategory(); if (e.key === 'Escape') { setAddingCategory(false); setNewCategoryName('') } }}
                placeholder={t('todo.newCategory')}
                style={{ flex: 1, fontSize: 12, padding: '4px 6px', border: '1px solid var(--border-primary)', borderRadius: 5, background: 'var(--bg-hover)', color: 'var(--text-primary)', fontFamily: 'inherit', minWidth: 0 }} />
              <button onClick={addCategory} style={{ background: 'none', border: 'none', cursor: 'pointer', color: '#22c55e', padding: 2 }}><Check size={13} /></button>
            </div>
          ) : (
            <button onClick={() => setAddingCategory(true)}
              title={isMobile ? t('todo.addCategory') : undefined}
              style={{ display: 'flex', alignItems: 'center', justifyContent: isMobile ? 'center' : 'flex-start', gap: isMobile ? 0 : 6, padding: isMobile ? '8px 0' : '7px 12px', fontSize: 12, color: 'var(--text-faint)', background: 'none', border: 'none', cursor: 'pointer', fontFamily: 'inherit', width: '100%', textAlign: 'left' }}>
              <Plus size={isMobile ? 18 : 13} /> {!isMobile && t('todo.addCategory')}
            </button>
          )
        )}
      </div>

      {/* ── Middle: Task List ── */}
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0 }}>
        {/* Header */}
        <div style={{ padding: '16px 20px 12px', borderBottom: '1px solid var(--border-faint)' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <h2 style={{ margin: 0, fontSize: 22, fontWeight: 700, color: 'var(--text-primary)', letterSpacing: '-0.02em' }}>
              {filterTitle}
            </h2>
            <span style={{ fontSize: 13, color: 'var(--text-faint)', background: 'var(--bg-hover)', borderRadius: 6, padding: '2px 8px', fontWeight: 600 }}>
              {filtered.length}
            </span>
          </div>
        </div>

        {/* Task list */}
        <div style={{ flex: 1, overflowY: 'auto', padding: '4px 0' }}>
          {filtered.length === 0 ? null : (
            filtered.map(item => {
              const done = !!item.checked
              const assignedUser = members.find(m => m.id === item.assigned_user_id)
              const isOverdue = item.due_date && !done && item.due_date < today
              const isSelected = selectedId === item.id
              const catColor = item.category ? katColor(item.category, categories) : null

              return (
                <div key={item.id}
                  onClick={() => { setSelectedId(isSelected ? null : item.id); setIsAddingNew(false) }}
                  style={{
                    display: 'flex', alignItems: 'center', gap: 10, padding: '10px 20px',
                    borderBottom: '1px solid var(--border-faint)', cursor: 'pointer',
                    background: isSelected ? 'var(--bg-hover)' : 'transparent',
                    transition: 'background 0.1s',
                  }}
                  onMouseEnter={e => { if (!isSelected) e.currentTarget.style.background = 'rgba(0,0,0,0.02)' }}
                  onMouseLeave={e => { if (!isSelected) e.currentTarget.style.background = 'transparent' }}>

                  {/* Checkbox */}
                  <button onClick={e => { e.stopPropagation(); canEdit && toggleTodoItem(tripId, item.id, !done) }}
                    style={{ background: 'none', border: 'none', cursor: canEdit ? 'pointer' : 'default', padding: 0, flexShrink: 0,
                      color: done ? '#22c55e' : 'var(--border-primary)' }}>
                    {done ? <CheckSquare size={18} /> : <Square size={18} />}
                  </button>

                  {/* Content */}
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{
                      fontSize: 14, color: done ? 'var(--text-faint)' : 'var(--text-primary)',
                      textDecoration: done ? 'line-through' : 'none', lineHeight: 1.4,
                      overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                    }}>
                      {item.name}
                    </div>
                    {/* Description preview */}
                    {item.description && (
                      <div style={{ fontSize: 12, color: 'var(--text-faint)', marginTop: 2, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', lineHeight: 1.4 }}>
                        {item.description}
                      </div>
                    )}
                    {/* Inline badges */}
                    {(item.priority || item.due_date || catColor || assignedUser) && (
                    <div style={{ display: 'flex', gap: 5, marginTop: 5, flexWrap: 'wrap' }}>
                      {item.priority > 0 && PRIO_CONFIG[item.priority] && (
                        <span style={{
                          fontSize: 10, display: 'inline-flex', alignItems: 'center', gap: 3,
                          padding: '2px 7px', borderRadius: 5, fontWeight: 600,
                          color: PRIO_CONFIG[item.priority].color,
                          background: `${PRIO_CONFIG[item.priority].color}10`,
                          border: `1px solid ${PRIO_CONFIG[item.priority].color}25`,
                        }}>
                          <Flag size={9} />{PRIO_CONFIG[item.priority].label}
                        </span>
                      )}
                      {item.due_date && (
                        <span style={{
                          fontSize: 10, display: 'inline-flex', alignItems: 'center', gap: 3,
                          padding: '2px 7px', borderRadius: 5, fontWeight: 500,
                          color: isOverdue ? '#ef4444' : 'var(--text-secondary)',
                          background: isOverdue ? 'rgba(239,68,68,0.08)' : 'var(--bg-hover)',
                          border: `1px solid ${isOverdue ? 'rgba(239,68,68,0.15)' : 'var(--border-faint)'}`,
                        }}>
                          <Calendar size={9} />{formatDate(item.due_date)}
                        </span>
                      )}
                      {catColor && (
                        <span style={{
                          fontSize: 10, display: 'inline-flex', alignItems: 'center', gap: 4,
                          padding: '2px 7px', borderRadius: 5, fontWeight: 500,
                          color: 'var(--text-secondary)', background: 'var(--bg-hover)',
                          border: '1px solid var(--border-faint)',
                        }}>
                          <span style={{ width: 6, height: 6, borderRadius: '50%', background: catColor, flexShrink: 0 }} />
                          {item.category}
                        </span>
                      )}
                      {assignedUser && (
                        <span style={{
                          fontSize: 10, display: 'inline-flex', alignItems: 'center', gap: 4,
                          padding: '2px 7px', borderRadius: 5, fontWeight: 500,
                          color: 'var(--text-secondary)', background: 'var(--bg-hover)',
                          border: '1px solid var(--border-faint)',
                        }}>
                          {assignedUser.avatar ? (
                            <img src={`/uploads/avatars/${assignedUser.avatar}`} style={{ width: 13, height: 13, borderRadius: '50%', objectFit: 'cover' }} alt="" />
                          ) : (
                            <span style={{ width: 13, height: 13, borderRadius: '50%', background: 'var(--border-primary)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontSize: 7, color: 'var(--text-faint)', fontWeight: 700 }}>
                              {assignedUser.username.charAt(0).toUpperCase()}
                            </span>
                          )}
                          {assignedUser.username}
                        </span>
                      )}
                    </div>
                    )}
                  </div>

                  {/* Chevron */}
                  <ChevronRight size={16} color="var(--text-faint)" style={{ flexShrink: 0, opacity: 0.4 }} />
                </div>
              )
            })
          )}
        </div>
      </div>

      {/* ── Right: Detail Pane ── */}
      {selectedItem && !isAddingNew && !isMobile && (
        <DetailPane
          item={selectedItem}
          tripId={tripId}
          categories={categories}
          members={members}
          onClose={() => setSelectedId(null)}
        />
      )}
      {selectedItem && !isAddingNew && isMobile && (
        <div onClick={e => { if (e.target === e.currentTarget) setSelectedId(null) }}
          style={{ position: 'fixed', inset: 0, zIndex: 1000, background: 'rgba(0,0,0,0.4)', display: 'flex', justifyContent: 'center', alignItems: 'flex-end', paddingBottom: 'var(--bottom-nav-h)' }}>
          <div style={{ width: '100%', maxHeight: '85vh', borderRadius: '16px 16px 0 0', overflow: 'auto' }}
            ref={el => { if (el) { const child = el.firstElementChild as HTMLElement; if (child) { child.style.width = '100%'; child.style.borderLeft = 'none'; child.style.borderRadius = '16px 16px 0 0' } } }}>
            <DetailPane
              item={selectedItem}
              tripId={tripId}
              categories={categories}
              members={members}
              onClose={() => setSelectedId(null)}
            />
          </div>
        </div>
      )}
      {isAddingNew && !selectedItem && !isMobile && ReactDOM.createPortal(
        <div onClick={e => { if (e.target === e.currentTarget) setIsAddingNew(false) }}
          className="modal-backdrop"
          style={{ position: 'fixed', inset: 0, zIndex: 1000, background: 'rgba(15,23,42,0.5)', display: 'flex', justifyContent: 'center', alignItems: 'flex-start', paddingTop: 'calc(var(--nav-h) + 60px)', paddingBottom: 40 }}>
          <div style={{ width: 'min(520px, 92vw)', maxHeight: 'calc(100vh - var(--nav-h) - 120px)', overflow: 'auto', borderRadius: 16, boxShadow: '0 20px 60px rgba(0,0,0,0.25)' }}
            ref={el => { if (el) { const child = el.firstElementChild as HTMLElement; if (child) { child.style.width = '100%'; child.style.borderLeft = 'none'; child.style.borderRadius = '16px' } } }}>
            <NewTaskPane
              tripId={tripId}
              categories={categories}
              members={members}
              defaultCategory={typeof filter === 'string' && categories.includes(filter) ? filter : null}
              onCreated={(id) => { setIsAddingNew(false); setSelectedId(id) }}
              onClose={() => setIsAddingNew(false)}
            />
          </div>
        </div>,
        document.body
      )}
      {isAddingNew && !selectedItem && isMobile && ReactDOM.createPortal(
        <div onClick={e => { if (e.target === e.currentTarget) setIsAddingNew(false) }}
          className="modal-backdrop"
          style={{ position: 'fixed', inset: 0, zIndex: 1000, background: 'rgba(0,0,0,0.4)', display: 'flex', justifyContent: 'center', alignItems: 'flex-end', paddingBottom: 'var(--bottom-nav-h)' }}>
          <div style={{ width: '100%', maxHeight: '85vh', borderRadius: '16px 16px 0 0', overflow: 'auto' }}
            ref={el => { if (el) { const child = el.firstElementChild as HTMLElement; if (child) { child.style.width = '100%'; child.style.borderLeft = 'none'; child.style.borderRadius = '16px 16px 0 0' } } }}>
            <NewTaskPane
              tripId={tripId}
              categories={categories}
              members={members}
              defaultCategory={typeof filter === 'string' && categories.includes(filter) ? filter : null}
              onCreated={(id) => { setIsAddingNew(false); setSelectedId(id) }}
              onClose={() => setIsAddingNew(false)}
            />
          </div>
        </div>,
        document.body
      )}
    </div>
  )
}

// ── Detail Pane (right side) ──────────────────────────────────────────────

function DetailPane({ item, tripId, categories, members, onClose }: {
  item: TodoItem; tripId: number; categories: string[]; members: Member[];
  onClose: () => void;
}) {
  const { updateTodoItem, deleteTodoItem } = useTripStore()
  const canEdit = useCanDo('packing_edit')
  const toast = useToast()
  const { t } = useTranslation()

  const [name, setName] = useState(item.name)
  const [desc, setDesc] = useState(item.description || '')
  const [dueDate, setDueDate] = useState(item.due_date || '')
  const [category, setCategory] = useState(item.category || '')
  const [assignedUserId, setAssignedUserId] = useState<number | null>(item.assigned_user_id)
  const [priority, setPriority] = useState(item.priority || 0)
  const [saving, setSaving] = useState(false)

  // Sync when selected item changes
  useEffect(() => {
    setName(item.name)
    setDesc(item.description || '')
    setDueDate(item.due_date || '')
    setCategory(item.category || '')
    setAssignedUserId(item.assigned_user_id)
    setPriority(item.priority || 0)
  }, [item.id, item.name, item.description, item.due_date, item.category, item.assigned_user_id, item.priority])

  const hasChanges = name !== item.name || desc !== (item.description || '') ||
    dueDate !== (item.due_date || '') || category !== (item.category || '') ||
    assignedUserId !== item.assigned_user_id || priority !== (item.priority || 0)

  const save = async () => {
    if (!name.trim() || !hasChanges) return
    setSaving(true)
    try {
      await updateTodoItem(tripId, item.id, {
        name: name.trim(), description: desc || null,
        due_date: dueDate || null, category: category || null,
        assigned_user_id: assignedUserId, priority,
      } as any)
    } catch (err: unknown) { toast.error(err instanceof Error ? err.message : t('common.error')) }
    setSaving(false)
  }

  const handleDelete = async () => {
    try {
      await deleteTodoItem(tripId, item.id)
      onClose()
    } catch (err: unknown) { toast.error(err instanceof Error ? err.message : t('common.error')) }
  }

  const labelStyle: React.CSSProperties = { fontSize: 12, fontWeight: 500, color: 'var(--text-secondary)', marginBottom: 4, display: 'block' }
  const inputStyle: React.CSSProperties = {
    width: '100%', fontSize: 13, padding: '8px 10px', border: '1px solid var(--border-primary)',
    borderRadius: 8, background: 'var(--bg-primary)', color: 'var(--text-primary)', fontFamily: 'inherit',
  }

  return (
    <div style={{
      width: 320, flexShrink: 0, borderLeft: '1px solid var(--border-faint)',
      display: 'flex', flexDirection: 'column', background: 'var(--bg-primary)',
    }}>
      {/* Header */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '16px 20px 12px', borderBottom: '1px solid var(--border-faint)' }}>
        <span style={{ fontSize: 14, fontWeight: 700, color: 'var(--text-primary)' }}>{t('todo.detail.title')}</span>
        <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--text-faint)', padding: 4 }}>
          <X size={16} />
        </button>
      </div>

      {/* Form */}
      <div style={{ flex: 1, overflowY: 'auto', padding: '16px 20px', display: 'flex', flexDirection: 'column', gap: 14 }}>
        {/* Name */}
        <div>
          <input value={name} onChange={e => setName(e.target.value)} disabled={!canEdit}
            style={{ ...inputStyle, fontSize: 15, fontWeight: 600, border: 'none', padding: '4px 0', background: 'transparent' }}
            placeholder={t('todo.namePlaceholder')} />
        </div>

        {/* Description */}
        <div>
          <label style={labelStyle}>{t('todo.detail.description')}</label>
          <textarea value={desc} onChange={e => setDesc(e.target.value)} disabled={!canEdit} rows={4}
            placeholder={t('todo.descriptionPlaceholder')}
            style={{ ...inputStyle, resize: 'vertical', minHeight: 80 }} />
        </div>

        {/* Priority */}
        <div>
          <label style={labelStyle}>{t('todo.detail.priority')}</label>
          <div style={{ display: 'flex', gap: 4 }}>
            {[0, 1, 2, 3].map(p => {
              const cfg = PRIO_CONFIG[p]
              const isActive = priority === p
              return (
                <button key={p} onClick={() => canEdit && setPriority(p)}
                  style={{
                    flex: 1, padding: '6px 0', borderRadius: 6, fontSize: 11, fontWeight: 600, cursor: canEdit ? 'pointer' : 'default',
                    fontFamily: 'inherit', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 4,
                    border: `1px solid ${isActive && cfg ? cfg.color + '40' : 'var(--border-primary)'}`,
                    background: isActive && cfg ? cfg.color + '12' : 'transparent',
                    color: isActive && cfg ? cfg.color : isActive ? 'var(--text-primary)' : 'var(--text-faint)',
                    transition: 'all 0.1s',
                  }}>
                  {cfg ? <><Flag size={10} />{cfg.label}</> : t('todo.detail.noPriority')}
                </button>
              )
            })}
          </div>
        </div>

        {/* Category */}
        <div>
          <label style={labelStyle}>{t('todo.detail.category')}</label>
          <CustomSelect
            value={category}
            onChange={v => setCategory(v)}
            options={[
              { value: '', label: t('todo.noCategory') },
              ...categories.map(c => ({
                value: c,
                label: c,
                icon: <span style={{ width: 8, height: 8, borderRadius: '50%', background: katColor(c, categories), display: 'inline-block' }} />,
              })),
            ]}
            placeholder={t('todo.noCategory')}
            size="sm"
            disabled={!canEdit}
          />
        </div>

        {/* Due date */}
        <div>
          <label style={labelStyle}>{t('todo.detail.dueDate')}</label>
          <CustomDatePicker
            value={dueDate}
            onChange={v => setDueDate(v)}
          />
        </div>

        {/* Assigned to */}
        <div>
          <label style={labelStyle}>{t('todo.detail.assignedTo')}</label>
          <CustomSelect
            value={String(assignedUserId ?? '')}
            onChange={v => setAssignedUserId(v ? Number(v) : null)}
            options={[
              { value: '', label: t('todo.unassigned'), icon: <User size={14} style={{ color: 'var(--text-faint)' }} /> },
              ...members.map(m => ({
                value: String(m.id),
                label: m.username,
                icon: m.avatar ? (
                  <img src={`/uploads/avatars/${m.avatar}`} style={{ width: 18, height: 18, borderRadius: '50%', objectFit: 'cover' as const }} alt="" />
                ) : (
                  <span style={{ width: 18, height: 18, borderRadius: '50%', background: 'var(--border-primary)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontSize: 10, color: 'var(--text-faint)', fontWeight: 600 }}>
                    {m.username.charAt(0).toUpperCase()}
                  </span>
                ),
              })),
            ]}
            placeholder={t('todo.unassigned')}
            size="sm"
            disabled={!canEdit}
          />
        </div>
      </div>

      {/* Footer actions */}
      {canEdit && (
        <div style={{ padding: '12px 20px', borderTop: '1px solid var(--border-faint)', display: 'flex', gap: 8 }}>
          <button onClick={handleDelete}
            style={{
              flex: 1, padding: '9px 16px', borderRadius: 8, fontSize: 12, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit',
              border: '1px solid var(--border-primary)', background: 'transparent', color: 'var(--text-secondary)',
              display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 5,
            }}>
            <Trash2 size={13} />
            {t('todo.detail.delete')}
          </button>
          <button onClick={save} disabled={!hasChanges || saving}
            style={{
              flex: 1, padding: '9px 16px', borderRadius: 8, fontSize: 12, fontWeight: 600, cursor: hasChanges ? 'pointer' : 'default', fontFamily: 'inherit',
              border: 'none', background: hasChanges ? 'var(--text-primary)' : 'var(--border-faint)',
              color: hasChanges ? 'var(--bg-primary)' : 'var(--text-faint)',
              transition: 'all 0.15s',
            }}>
            {saving ? '...' : t('todo.detail.save')}
          </button>
        </div>
      )}
    </div>
  )
}

// ── New Task Pane (right side, for creating) ──────────────────────────────

function NewTaskPane({ tripId, categories, members, defaultCategory, onCreated, onClose }: {
  tripId: number; categories: string[]; members: Member[]; defaultCategory: string | null;
  onCreated: (id: number) => void; onClose: () => void;
}) {
  const { addTodoItem } = useTripStore()
  const toast = useToast()
  const { t } = useTranslation()

  const [name, setName] = useState('')
  const [desc, setDesc] = useState('')
  const [dueDate, setDueDate] = useState('')
  const [category, setCategory] = useState(defaultCategory || '')
  const [addingCategory, setAddingCategoryInline] = useState(false)
  const [assignedUserId, setAssignedUserId] = useState<number | null>(null)
  const [priority, setPriority] = useState(0)
  const [saving, setSaving] = useState(false)

  const labelStyle: React.CSSProperties = { fontSize: 12, fontWeight: 500, color: 'var(--text-secondary)', marginBottom: 4, display: 'block' }

  const create = async () => {
    if (!name.trim()) return
    setSaving(true)
    try {
      const trimmedCategory = category.trim()
      const item = await addTodoItem(tripId, {
        name: name.trim(), description: desc || null, priority,
        due_date: dueDate || null, category: trimmedCategory || null,
        assigned_user_id: assignedUserId,
      } as any)
      if (item?.id) onCreated(item.id)
    } catch (err: unknown) { toast.error(err instanceof Error ? err.message : t('common.error')) }
    setSaving(false)
  }

  return (
    <div style={{
      width: 320, flexShrink: 0, borderLeft: '1px solid var(--border-faint)',
      display: 'flex', flexDirection: 'column', background: 'var(--bg-primary)',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '16px 20px 12px', borderBottom: '1px solid var(--border-faint)' }}>
        <span style={{ fontSize: 14, fontWeight: 700, color: 'var(--text-primary)' }}>{t('todo.newItem')}</span>
        <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--text-faint)', padding: 4 }}>
          <X size={16} />
        </button>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '16px 20px', display: 'flex', flexDirection: 'column', gap: 14 }}>
        <div>
          <input autoFocus value={name} onChange={e => setName(e.target.value)}
            onKeyDown={e => { if (e.key === 'Enter' && name.trim()) create() }}
            style={{ width: '100%', fontSize: 15, fontWeight: 600, border: 'none', padding: '4px 0', background: 'transparent', color: 'var(--text-primary)', outline: 'none', fontFamily: 'inherit' }}
            placeholder={t('todo.namePlaceholder')} />
        </div>

        <div>
          <label style={labelStyle}>{t('todo.detail.description')}</label>
          <textarea value={desc} onChange={e => setDesc(e.target.value)} rows={4}
            placeholder={t('todo.descriptionPlaceholder')}
            style={{ width: '100%', fontSize: 13, padding: '8px 10px', border: '1px solid var(--border-primary)', borderRadius: 8, background: 'var(--bg-primary)', color: 'var(--text-primary)', fontFamily: 'inherit', resize: 'vertical', minHeight: 80 }} />
        </div>

        <div>
          <label style={labelStyle}>{t('todo.detail.category')}</label>
          {addingCategory ? (
            <div style={{ display: 'flex', gap: 4 }}>
              <input
                autoFocus
                value={category}
                onChange={e => setCategory(e.target.value)}
                onKeyDown={e => { if (e.key === 'Enter') setAddingCategoryInline(false); if (e.key === 'Escape') { setCategory(''); setAddingCategoryInline(false) } }}
                placeholder={t('todo.newCategory')}
                style={{ flex: 1, fontSize: 13, padding: '8px 10px', border: '1px solid var(--border-primary)', borderRadius: 8, background: 'var(--bg-primary)', color: 'var(--text-primary)', fontFamily: 'inherit', outline: 'none' }}
              />
              <button type="button" onClick={() => setAddingCategoryInline(false)}
                style={{ background: 'var(--bg-hover)', border: '1px solid var(--border-primary)', borderRadius: 8, padding: '0 10px', cursor: 'pointer', color: 'var(--text-primary)' }}>
                <Check size={14} />
              </button>
            </div>
          ) : (
            <div style={{ display: 'flex', gap: 4 }}>
              <div style={{ flex: 1, minWidth: 0 }}>
                <CustomSelect
                  value={category}
                  onChange={v => setCategory(v)}
                  options={[
                    { value: '', label: t('todo.noCategory') },
                    ...categories.map(c => ({
                      value: c, label: c,
                      icon: <span style={{ width: 8, height: 8, borderRadius: '50%', background: katColor(c, categories), display: 'inline-block' }} />,
                    })),
                    ...(category && !categories.includes(category) ? [{
                      value: category, label: `${category} (${t('todo.newCategoryLabel') || 'new'})`,
                      icon: <span style={{ width: 8, height: 8, borderRadius: '50%', background: '#9ca3af', display: 'inline-block' }} />,
                    }] : []),
                  ]}
                  placeholder={t('todo.noCategory')}
                  size="sm"
                />
              </div>
              <button type="button" onClick={() => { setCategory(''); setAddingCategoryInline(true) }}
                title={t('todo.newCategory')}
                style={{ background: 'var(--bg-hover)', border: '1px solid var(--border-primary)', borderRadius: 8, padding: '0 10px', cursor: 'pointer', color: 'var(--text-muted)', fontFamily: 'inherit' }}>
                <Plus size={14} />
              </button>
            </div>
          )}
        </div>

        <div>
          <label style={labelStyle}>{t('todo.detail.priority')}</label>
          <div style={{ display: 'flex', gap: 4 }}>
            {[0, 1, 2, 3].map(p => {
              const cfg = PRIO_CONFIG[p]
              const isActive = priority === p
              return (
                <button key={p} onClick={() => setPriority(p)}
                  style={{
                    flex: 1, padding: '6px 0', borderRadius: 6, fontSize: 11, fontWeight: 600, cursor: 'pointer',
                    fontFamily: 'inherit', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 4,
                    border: `1px solid ${isActive && cfg ? cfg.color + '40' : 'var(--border-primary)'}`,
                    background: isActive && cfg ? cfg.color + '12' : 'transparent',
                    color: isActive && cfg ? cfg.color : isActive ? 'var(--text-primary)' : 'var(--text-faint)',
                    transition: 'all 0.1s',
                  }}>
                  {cfg ? <><Flag size={10} />{cfg.label}</> : t('todo.detail.noPriority')}
                </button>
              )
            })}
          </div>
        </div>

        <div>
          <label style={labelStyle}>{t('todo.detail.dueDate')}</label>
          <CustomDatePicker value={dueDate} onChange={v => setDueDate(v)} />
        </div>

        <div>
          <label style={labelStyle}>{t('todo.detail.assignedTo')}</label>
          <CustomSelect
            value={String(assignedUserId ?? '')}
            onChange={v => setAssignedUserId(v ? Number(v) : null)}
            options={[
              { value: '', label: t('todo.unassigned'), icon: <User size={14} style={{ color: 'var(--text-faint)' }} /> },
              ...members.map(m => ({
                value: String(m.id), label: m.username,
                icon: m.avatar ? (
                  <img src={`/uploads/avatars/${m.avatar}`} style={{ width: 18, height: 18, borderRadius: '50%', objectFit: 'cover' as const }} alt="" />
                ) : (
                  <span style={{ width: 18, height: 18, borderRadius: '50%', background: 'var(--border-primary)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontSize: 10, color: 'var(--text-faint)', fontWeight: 600 }}>
                    {m.username.charAt(0).toUpperCase()}
                  </span>
                ),
              })),
            ]}
            placeholder={t('todo.unassigned')}
            size="sm"
          />
        </div>
      </div>

      <div style={{ padding: '12px 20px', borderTop: '1px solid var(--border-faint)' }}>
        <button onClick={create} disabled={!name.trim() || saving}
          style={{
            width: '100%', padding: '9px 16px', borderRadius: 8, fontSize: 12, fontWeight: 600, cursor: name.trim() ? 'pointer' : 'default', fontFamily: 'inherit',
            border: 'none', background: name.trim() ? 'var(--text-primary)' : 'var(--border-faint)',
            color: name.trim() ? 'var(--bg-primary)' : 'var(--text-faint)', transition: 'all 0.15s',
          }}>
          {saving ? '...' : t('todo.detail.create')}
        </button>
      </div>
    </div>
  )
}
