import { useState, useEffect, useRef } from 'react'
import { Loader2, GitFork } from 'lucide-react'
import { useStore } from '../store/useStore'
import { fetchSchemaGraph } from '../lib/api'
import type { SchemaTable, SchemaRelationship } from '../lib/types'

// ─── Table card ───────────────────────────────────────────────────

function TableCard({ table, x, y }: { table: SchemaTable; x: number; y: number }) {
  return (
    <g transform={`translate(${x},${y})`}>
      {/* Card bg */}
      <rect
        width={180}
        height={28 + table.columns.length * 20}
        rx={8}
        fill="#0e0e16"
        stroke="rgba(255,255,255,0.08)"
        strokeWidth={1}
      />
      {/* Header */}
      <rect width={180} height={28} rx={8} fill="rgba(139,92,246,0.15)" />
      <rect y={20} width={180} height={8} fill="rgba(139,92,246,0.15)" />
      <text
        x={10}
        y={18}
        fill="#a78bfa"
        fontSize={11}
        fontWeight="bold"
        fontFamily="ui-monospace,monospace"
      >
        {table.name}
      </text>

      {/* Columns */}
      {table.columns.map((col, i) => (
        <g key={col.name} transform={`translate(0,${28 + i * 20})`}>
          <rect
            width={180}
            height={20}
            fill={i % 2 === 0 ? 'rgba(255,255,255,0.01)' : 'transparent'}
          />
          <text
            x={10}
            y={14}
            fill={col.pk ? '#60a5fa' : col.fk ? '#34d399' : 'rgba(255,255,255,0.5)'}
            fontSize={10}
            fontFamily="ui-monospace,monospace"
          >
            {col.pk ? '🔑 ' : col.fk ? '🔗 ' : '   '}
            {col.name}
          </text>
          <text
            x={170}
            y={14}
            fill="rgba(255,255,255,0.2)"
            fontSize={9}
            fontFamily="ui-monospace,monospace"
            textAnchor="end"
          >
            {col.type}
          </text>
        </g>
      ))}
    </g>
  )
}

// ─── Layout helpers ───────────────────────────────────────────────

function layoutTables(tables: SchemaTable[]) {
  const CARD_W = 180
  const CARD_H_BASE = 28
  const COL_H = 20
  const GAP_X = 40
  const GAP_Y = 30
  const COLS_PER_ROW = 3

  const positions: Record<string, { x: number; y: number; w: number; h: number }> = {}
  let maxRowH = 0

  tables.forEach((t, i) => {
    const col = i % COLS_PER_ROW
    const row = Math.floor(i / COLS_PER_ROW)
    const h = CARD_H_BASE + t.columns.length * COL_H

    if (row === Math.floor(i / COLS_PER_ROW) && col === 0) maxRowH = 0
    maxRowH = Math.max(maxRowH, h)

    const prevRowsH = tables
      .slice(0, row * COLS_PER_ROW)
      .reduce((acc, _, idx) => {
        if (idx % COLS_PER_ROW === 0) {
          const rowH = tables.slice(idx, idx + COLS_PER_ROW).reduce(
            (m, rt) => Math.max(m, CARD_H_BASE + rt.columns.length * COL_H),
            0
          )
          return acc + rowH + GAP_Y
        }
        return acc
      }, 0)

    positions[t.name] = {
      x: col * (CARD_W + GAP_X) + 20,
      y: prevRowsH + 20,
      w: CARD_W,
      h,
    }
  })

  return positions
}

function RelationshipLine({
  from,
  to,
  positions,
}: {
  from: string
  to: string
  positions: Record<string, { x: number; y: number; w: number; h: number }>
}) {
  const a = positions[from]
  const b = positions[to]
  if (!a || !b) return null

  const x1 = a.x + a.w
  const y1 = a.y + 14
  const x2 = b.x
  const y2 = b.y + 14
  const cx = (x1 + x2) / 2

  return (
    <path
      d={`M${x1},${y1} C${cx},${y1} ${cx},${y2} ${x2},${y2}`}
      stroke="rgba(139,92,246,0.3)"
      strokeWidth={1.5}
      fill="none"
      strokeDasharray="4 3"
    />
  )
}

// ─── ER Diagram component ─────────────────────────────────────────

export function ERDiagram() {
  const { schemaGraph, setSchemaGraph } = useStore()
  const [loading, setLoading] = useState(false)
  const svgRef = useRef<SVGSVGElement>(null)

  const load = async () => {
    setLoading(true)
    try {
      const data = await fetchSchemaGraph()
      setSchemaGraph(data)
    } catch {
      // noop
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    if (!schemaGraph) void load()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  if (loading) {
    return (
      <div className="flex items-center justify-center h-full gap-2 text-gray-500">
        <Loader2 size={16} className="animate-spin" />
        <span className="text-sm">Loading schema...</span>
      </div>
    )
  }

  if (!schemaGraph || schemaGraph.tables.length === 0) {
    return (
      <div className="flex flex-col items-center justify-center h-full gap-3 text-gray-600">
        <GitFork size={32} className="text-gray-700" />
        <p className="text-sm">Schema will appear after database connects</p>
        <button
          onClick={() => void load()}
          className="text-xs text-violet-400 hover:text-violet-300 transition-colors"
        >
          Retry
        </button>
      </div>
    )
  }

  const { tables, relationships } = schemaGraph
  const positions = layoutTables(tables)

  const allX = Object.values(positions).map((p) => p.x + p.w)
  const allY = Object.values(positions).map((p) => p.y + p.h)
  const svgW = Math.max(...allX) + 40
  const svgH = Math.max(...allY) + 40

  return (
    <div className="h-full overflow-auto p-4">
      <div className="text-[10px] text-gray-500 uppercase tracking-widest mb-3 flex items-center gap-1.5">
        <GitFork size={10} className="text-violet-400" />
        Entity Relationship Diagram
        <span className="text-gray-700">· {tables.length} tables</span>
      </div>
      <svg
        ref={svgRef}
        width={svgW}
        height={svgH}
        style={{ minWidth: svgW }}
      >
        {/* FK lines */}
        {(relationships as SchemaRelationship[]).map((rel, i) => (
          <RelationshipLine
            key={i}
            from={rel.from}
            to={rel.to}
            positions={positions}
          />
        ))}
        {/* Tables */}
        {tables.map((t: SchemaTable) => (
          <TableCard
            key={t.name}
            table={t}
            x={positions[t.name]?.x ?? 0}
            y={positions[t.name]?.y ?? 0}
          />
        ))}
      </svg>
    </div>
  )
}
