'use client'

import { useState, useTransition, useMemo } from 'react'
import { useRouter } from 'next/navigation'
import Link from 'next/link'
import { propertyStatuses } from '@/lib/validations/property'
import type { PropertyStatus } from '@/lib/validations/property'

const STATUS_LABELS: Record<PropertyStatus, string> = {
  ACTIVE: 'Active',
  RESERVED: 'Reserved',
  NEGOTIATING: 'Negotiating',
  OFFER_PENDING: 'Offer pending',
  SOLD: 'Sold',
  OFF_MARKET: 'Off market',
  ARCHIVED: 'Archived',
}

const COLUMN_COLORS: Record<PropertyStatus, string> = {
  ACTIVE: 'border-green-300 bg-green-50/50',
  RESERVED: 'border-yellow-300 bg-yellow-50/50',
  NEGOTIATING: 'border-orange-300 bg-orange-50/50',
  OFFER_PENDING: 'border-purple-300 bg-purple-50/50',
  SOLD: 'border-blue-300 bg-blue-50/50',
  OFF_MARKET: 'border-gray-300 bg-gray-50/50',
  ARCHIVED: 'border-slate-300 bg-slate-50/50',
}

export interface KanbanProperty {
  id: string
  title: string
  slug: string
  type: string
  priceUsd?: number | null
  cover?: string | null
  status: PropertyStatus
  ingestedAt: string | Date
  updatedAt: string | Date
  agentName?: string
  agentEmail?: string
}

interface Props {
  properties: KanbanProperty[]
  readOnly?: boolean
}

export function PipelineKanban({ properties: initial, readOnly = false }: Props) {
  const router = useRouter()
  const [, startTransition] = useTransition()
  const [items, setItems] = useState(initial)
  const [draggingId, setDraggingId] = useState<string | null>(null)
  const [dragOverStatus, setDragOverStatus] = useState<PropertyStatus | null>(null)
  const [error, setError] = useState('')

  const grouped = useMemo(() => {
    const g: Record<PropertyStatus, KanbanProperty[]> = {
      ACTIVE: [], RESERVED: [], NEGOTIATING: [], OFFER_PENDING: [], SOLD: [], OFF_MARKET: [], ARCHIVED: [],
    }
    for (const p of items) g[p.status].push(p)
    // sort by updatedAt desc within each column
    for (const s of propertyStatuses) {
      g[s].sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())
    }
    return g
  }, [items])

  async function moveTo(propertyId: string, newStatus: PropertyStatus) {
    if (readOnly) return
    const item = items.find((p) => p.id === propertyId)
    if (!item || item.status === newStatus) return

    // Optimistic update
    const prevItems = items
    setItems((cur) => cur.map((p) => (p.id === propertyId ? { ...p, status: newStatus } : p)))
    setError('')

    try {
      const res = await fetch(`/api/admin/properties/${propertyId}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ status: newStatus }),
      })
      if (!res.ok) {
        const err = await res.json().catch(() => ({}))
        throw new Error(err.error || `Update failed (${res.status})`)
      }
      startTransition(() => router.refresh())
    } catch (e) {
      setItems(prevItems) // rollback
      setError(e instanceof Error ? e.message : 'Update failed')
    }
  }

  function onDragStart(e: React.DragEvent, propertyId: string) {
    if (readOnly) {
      e.preventDefault()
      return
    }
    setDraggingId(propertyId)
    e.dataTransfer.effectAllowed = 'move'
    e.dataTransfer.setData('text/plain', propertyId)
  }

  function onDragOver(e: React.DragEvent, status: PropertyStatus) {
    if (readOnly) return
    e.preventDefault()
    setDragOverStatus(status)
  }

  function onDragLeave() {
    setDragOverStatus(null)
  }

  async function onDrop(e: React.DragEvent, status: PropertyStatus) {
    if (readOnly) return
    e.preventDefault()
    setDragOverStatus(null)
    const propertyId = e.dataTransfer.getData('text/plain') || draggingId
    if (propertyId) {
      await moveTo(propertyId, status)
    }
    setDraggingId(null)
  }

  return (
    <div>
      {error && (
        <div className="bg-red-50 text-red-700 p-2 rounded mb-3 text-sm" role="alert">
          {error}
        </div>
      )}
      <div className="flex gap-3 overflow-x-auto pb-4">
        {propertyStatuses.map((status) => {
          const col = grouped[status]
          const isOver = dragOverStatus === status
          return (
            <div
              key={status}
              onDragOver={(e) => onDragOver(e, status)}
              onDragLeave={onDragLeave}
              onDrop={(e) => onDrop(e, status)}
              className={`flex-shrink-0 w-72 border-t-[3px] rounded-lg ${COLUMN_COLORS[status]} ${
                isOver ? 'ring-2 ring-[#374527]' : ''
              }`}
            >
              <div className="px-3 py-2 flex items-center justify-between border-b">
                <h3 className="font-semibold text-sm text-[#1D2019]">{STATUS_LABELS[status]}</h3>
                <span className="text-xs text-gray-600 font-medium bg-white px-2 py-0.5 rounded">
                  {col.length}
                </span>
              </div>
              <div className="p-2 space-y-2 min-h-[200px] max-h-[500px] overflow-y-auto">
                {col.length === 0 ? (
                  <p className="text-xs text-gray-400 text-center py-6">Drop here</p>
                ) : (
                  col.map((p) => (
                    <KanbanCard
                      key={p.id}
                      property={p}
                      readOnly={readOnly}
                      onDragStart={(e) => onDragStart(e, p.id)}
                      isDragging={draggingId === p.id}
                    />
                  ))
                )}
              </div>
            </div>
          )
        })}
      </div>
    </div>
  )
}

function KanbanCard({
  property,
  readOnly,
  onDragStart,
  isDragging,
}: {
  property: KanbanProperty
  readOnly: boolean
  onDragStart: (e: React.DragEvent) => void
  isDragging: boolean
}) {
  const price = property.priceUsd ? Number(property.priceUsd) : null
  const days = Math.floor((Date.now() - new Date(property.updatedAt).getTime()) / 86400000)
  return (
    <div
      draggable={!readOnly}
      onDragStart={onDragStart}
      className={`bg-white rounded shadow-sm border p-2 cursor-grab active:cursor-grabbing ${
        isDragging ? 'opacity-40' : ''
      } ${readOnly ? 'cursor-default' : ''}`}
    >
      {property.cover && (
        // eslint-disable-next-line @next/next/no-img-element
        <img
          src={property.cover}
          alt=""
          className="w-full aspect-video object-cover rounded mb-2"
        />
      )}
      <Link href={`/admin/crm/properties/${property.id}`} className="block hover:underline">
        <p className="text-sm font-medium text-[#1D2019] line-clamp-2">{property.title}</p>
      </Link>
      <p className="text-xs text-gray-500 mt-1">
        {property.type}
        {price !== null && price > 0 ? ` · $${price.toLocaleString()}` : ''}
      </p>
      {property.agentName && (
        <p className="text-xs text-gray-500 truncate">{property.agentName}</p>
      )}
      <p className="text-xs text-gray-400 mt-1">
        {days === 0 ? 'today' : `${days}d ago`}
      </p>
    </div>
  )
}