import { useState, useEffect, useRef } from 'react'
import DrawCanvas, { type DrawCanvasHandle } from '../components/DrawCanvas'
import BlurhashCanvas from '../components/BlurhashCanvas'
import Topbar from '../components/Topbar'
import {
  getDbPictures,
  getDbObjects,
  getDbObjectPairs,
  createDbPair,
  directusAssetUrl,
} from '../api'
import { useAuth } from '../context/AuthContext'
import type { DbPicture, DbObject, DbPair, CanvasObject } from '../types'

const ChevronLeftIcon = () => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
    <polyline points="15 18 9 12 15 6" />
  </svg>
)
const ChevronRightIcon = () => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
    <polyline points="9 18 15 12 9 6" />
  </svg>
)

// ── PairForm ──────────────────────────────────────────────────────────────────

interface PendingWord {
  titel_de: string
  level: number
}

interface PairFormProps {
  objectId: string
  token: string
  onSaved: () => void
  onCancel: () => void
}

function PairForm({ objectId, token, onSaved, onCancel }: PairFormProps) {
  const [level, setLevel] = useState(5)
  const [questionDe, setQuestionDe] = useState('')
  const [statementDe, setStatementDe] = useState('')
  const [words, setWords] = useState<PendingWord[]>([])
  const [wordInput, setWordInput] = useState('')
  const [wordLevel, setWordLevel] = useState(50)
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState('')
  const wordInputRef = useRef<HTMLInputElement>(null)

  const addWord = () => {
    const t = wordInput.trim()
    if (!t || words.some(w => w.titel_de === t)) { setWordInput(''); return }
    setWords(prev => [...prev, { titel_de: t, level: wordLevel }])
    setWordInput('')
    setWordLevel(50)
    wordInputRef.current?.focus()
  }

  const handleSave = async () => {
    if (!statementDe.trim()) { setError('Aussage (statement_de) ist Pflicht.'); return }
    setSaving(true)
    setError('')
    try {
      await createDbPair(objectId, {
        question_de: questionDe.trim() || undefined,
        statement_de: statementDe.trim(),
        level,
        words,
      }, token)
      onSaved()
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Fehler beim Speichern')
    } finally {
      setSaving(false)
    }
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 10, padding: '10px 0' }}>
      {/* Level slider */}
      <div>
        <label style={{ fontSize: 11, color: 'var(--text-2)', display: 'block', marginBottom: 4 }}>
          Level: <strong>{level}</strong>
        </label>
        <input
          type="range" min={1} max={10} value={level}
          onChange={e => setLevel(Number(e.target.value))}
          style={{ width: '100%' }}
        />
      </div>

      {/* Question (optional) */}
      <div>
        <label style={{ fontSize: 11, color: 'var(--text-2)', display: 'block', marginBottom: 4 }}>
          Frage (optional)
        </label>
        <textarea
          value={questionDe}
          onChange={e => setQuestionDe(e.target.value)}
          rows={2}
          placeholder="question_de…"
          style={{
            width: '100%', resize: 'vertical', padding: '6px 8px',
            borderRadius: 'var(--r-sm)', border: '1px solid var(--border)',
            background: 'var(--surface-2)', color: 'var(--text-1)',
            fontFamily: 'var(--font)', fontSize: 12, boxSizing: 'border-box',
          }}
        />
      </div>

      {/* Statement (required) */}
      <div>
        <label style={{ fontSize: 11, color: 'var(--text-2)', display: 'block', marginBottom: 4 }}>
          Aussage <span style={{ color: 'var(--danger)' }}>*</span>
        </label>
        <textarea
          value={statementDe}
          onChange={e => setStatementDe(e.target.value)}
          rows={2}
          placeholder="statement_de…"
          style={{
            width: '100%', resize: 'vertical', padding: '6px 8px',
            borderRadius: 'var(--r-sm)', border: `1px solid ${statementDe.trim() ? 'var(--border)' : 'var(--danger)'}`,
            background: 'var(--surface-2)', color: 'var(--text-1)',
            fontFamily: 'var(--font)', fontSize: 12, boxSizing: 'border-box',
          }}
        />
      </div>

      {/* Words input */}
      <div>
        <label style={{ fontSize: 11, color: 'var(--text-2)', display: 'block', marginBottom: 4 }}>
          Wörter (werden an Frage + Aussage verknüpft)
        </label>
        <div style={{ display: 'flex', gap: 4, marginBottom: 4 }}>
          <input
            ref={wordInputRef}
            value={wordInput}
            onChange={e => setWordInput(e.target.value)}
            onKeyDown={e => { if (e.key === 'Enter') addWord() }}
            placeholder="titel_de…"
            style={{
              flex: 1, padding: '4px 8px', borderRadius: 'var(--r-sm)',
              border: '1px solid var(--border)', background: 'var(--surface-2)',
              color: 'var(--text-1)', fontFamily: 'var(--font)', fontSize: 12,
            }}
          />
          <input
            type="number" min={1} max={100} value={wordLevel}
            onChange={e => setWordLevel(Math.min(100, Math.max(1, Number(e.target.value))))}
            style={{
              width: 50, padding: '4px 4px', borderRadius: 'var(--r-sm)',
              border: '1px solid var(--border)', background: 'var(--surface-2)',
              color: 'var(--text-1)', fontFamily: 'var(--font)', fontSize: 12, textAlign: 'center',
            }}
          />
          <button className="btn-ghost btn-sm" onClick={addWord}>+</button>
        </div>
        {/* Word chips */}
        {words.length > 0 && (
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>
            {words.map((w, i) => (
              <span key={i} style={{
                display: 'inline-flex', alignItems: 'center', gap: 3,
                padding: '2px 6px', borderRadius: 'var(--r-full)',
                background: 'var(--primary-muted)', border: '1px solid color-mix(in srgb, var(--primary) 30%, transparent)',
                fontSize: 11, color: 'var(--primary)',
              }}>
                {w.titel_de} <span style={{ color: 'var(--text-2)', fontSize: 10 }}>L{w.level}</span>
                <button
                  onClick={() => setWords(prev => prev.filter((_, j) => j !== i))}
                  style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--primary)', padding: 0, lineHeight: 1, fontSize: 12 }}
                >×</button>
              </span>
            ))}
          </div>
        )}
      </div>

      {error && <div style={{ fontSize: 11, color: 'var(--danger)' }}>{error}</div>}

      <div style={{ display: 'flex', gap: 6 }}>
        <button
          className="btn-primary btn-sm"
          style={{ flex: 1 }}
          onClick={handleSave}
          disabled={saving || !statementDe.trim()}
        >
          {saving ? 'Speichere…' : 'Speichern'}
        </button>
        <button className="btn-ghost btn-sm" onClick={onCancel}>Abbrechen</button>
      </div>
    </div>
  )
}

// ── PairsList ─────────────────────────────────────────────────────────────────

interface PairsListProps {
  pairs: DbPair[]
  loading: boolean
  objectId: string | null
  token: string
  onRefresh: () => void
}

function PairsList({ pairs, loading, objectId, token, onRefresh }: PairsListProps) {
  const [showForm, setShowForm] = useState(false)

  const handleSaved = () => {
    setShowForm(false)
    onRefresh()
  }

  if (loading) return <div className="empty-state">Lade…</div>

  if (!objectId) return <div className="empty-state">Kein Objekt gewählt.</div>

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
      {pairs.length === 0 && !showForm && (
        <div style={{ padding: '12px 0', textAlign: 'center' }}>
          <div className="empty-state" style={{ marginBottom: 8 }}>Noch keine Pairs.</div>
          <button className="btn-ghost btn-sm" onClick={() => setShowForm(true)}>+ Pair hinzufügen</button>
        </div>
      )}

      {pairs.map(pair => (
        <div key={pair.id} style={{ padding: '8px 0', borderBottom: '1px solid var(--border)' }}>
          {/* Level badge */}
          <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 4 }}>
            <span style={{
              fontSize: 10, fontWeight: 700, color: 'var(--primary)',
              background: 'var(--primary-muted)', borderRadius: 'var(--r-full)',
              padding: '1px 6px', border: '1px solid color-mix(in srgb, var(--primary) 30%, transparent)',
            }}>L{pair.level}</span>
            <span style={{ fontSize: 10, color: 'var(--text-2)' }}>{pair.status}</span>
          </div>

          {/* Statements */}
          {pair.statements.map(s => (
            <div key={s.id} style={{ fontSize: 12, color: 'var(--text-1)', marginBottom: 3, paddingLeft: 4 }}>
              <span style={{ fontSize: 10, color: 'var(--text-2)', marginRight: 4 }}>Aussage:</span>
              {s.statement_de}
            </div>
          ))}

          {/* Questions */}
          {pair.questions.map(q => (
            <div key={q.id} style={{ fontSize: 12, color: 'var(--text-2)', fontStyle: 'italic', paddingLeft: 4 }}>
              <span style={{ fontSize: 10, marginRight: 4, fontStyle: 'normal' }}>Frage:</span>
              {q.question_de}
            </div>
          ))}
        </div>
      ))}

      {!showForm && pairs.length > 0 && (
        <div style={{ paddingTop: 8 }}>
          <button className="btn-ghost btn-sm btn-block" onClick={() => setShowForm(true)}>+ Pair hinzufügen</button>
        </div>
      )}

      {showForm && objectId && (
        <div style={{ paddingTop: 8 }}>
          <PairForm
            objectId={objectId}
            token={token}
            onSaved={handleSaved}
            onCancel={() => setShowForm(false)}
          />
        </div>
      )}
    </div>
  )
}

// ── GenerateIt ────────────────────────────────────────────────────────────────

export default function GenerateIt() {
  const { token } = useAuth()
  const canvasRef = useRef<DrawCanvasHandle>(null)

  const [pictureList, setPictureList] = useState<DbPicture[]>([])
  const [currentIndex, setCurrentIndex] = useState(-1)
  const [dbObjects, setDbObjects] = useState<DbObject[]>([])
  const [selectedObjId, setSelectedObjId] = useState<string | null>(null)
  const [imageLoaded, setImageLoaded] = useState(false)
  const [pairs, setPairs] = useState<DbPair[]>([])
  const [pairsLoading, setPairsLoading] = useState(false)

  const currentPicture: DbPicture | null =
    currentIndex >= 0 && currentIndex < pictureList.length ? pictureList[currentIndex] : null

  const canvasObjects: CanvasObject[] = dbObjects.map((obj, i) => ({
    id: obj.id,
    visible: true,
    selections: obj.selections,
    index: i + 1,
    hierarchy: 1,
  }))

  // Load db_pictures with status=objects_created
  useEffect(() => {
    if (!token) return
    getDbPictures(token, 'objects_created')
      .then(pics => { setPictureList(pics); setCurrentIndex(pics.length > 0 ? 0 : -1) })
      .catch(console.error)
  }, [token])

  // Load db_objects when picture changes
  useEffect(() => {
    if (!currentPicture || !token) {
      setDbObjects([]); setSelectedObjId(null); setPairs([]); setImageLoaded(false)
      return
    }
    getDbObjects(currentPicture.id, token)
      .then(objs => {
        setDbObjects(objs)
        setSelectedObjId(objs.length > 0 ? objs[0].id : null)
      })
      .catch(console.error)
  }, [currentPicture?.id, token])

  // Load pairs when selected object changes
  useEffect(() => {
    if (!selectedObjId || !token) { setPairs([]); return }
    setPairsLoading(true)
    getDbObjectPairs(selectedObjId, token)
      .then(setPairs)
      .catch(console.error)
      .finally(() => setPairsLoading(false))
  }, [selectedObjId, token])

  const refreshPairs = () => {
    if (!selectedObjId || !token) return
    setPairsLoading(true)
    getDbObjectPairs(selectedObjId, token)
      .then(setPairs)
      .catch(console.error)
      .finally(() => setPairsLoading(false))
  }

  const imageNav = (
    <div className="image-nav">
      <button className="btn-icon" onClick={() => setCurrentIndex(i => i - 1)} disabled={currentIndex <= 0}>
        <ChevronLeftIcon />
      </button>
      <span className="image-counter">
        {pictureList.length > 0 ? (
          <>
            <span className="image-counter-num">{currentIndex + 1}</span>
            <span className="image-counter-sep">/</span>
            <span className="image-counter-total">{pictureList.length}</span>
          </>
        ) : (
          <span className="image-counter-empty">Keine Bilder</span>
        )}
      </span>
      <button className="btn-icon" onClick={() => setCurrentIndex(i => i + 1)} disabled={currentIndex >= pictureList.length - 1}>
        <ChevronRightIcon />
      </button>
    </div>
  )

  return (
    <div className="app-shell">
      <Topbar page="generate" center={imageNav} />

      <div className="workspace">
        {/* Left: Objects */}
        <aside className="sidebar">
          <div className="sidebar-panel" style={{ flex: 1 }}>
            <h3 className="sidebar-heading">
              Objekte
              {dbObjects.length > 0 && <span className="badge">{dbObjects.length}</span>}
            </h3>
            {dbObjects.length === 0 ? (
              <div className="empty-state">Keine Objekte.</div>
            ) : (
              <div className="objects-list">
                {dbObjects.map((obj, i) => (
                  <div
                    key={obj.id}
                    className={`object-item${selectedObjId === obj.id ? ' selected' : ''}`}
                    onClick={() => setSelectedObjId(obj.id)}
                  >
                    <div className="object-item-header">
                      <div className="object-item-text">
                        <strong>Objekt {i + 1}</strong>
                        <span>{obj.selections?.length ? `${obj.selections.length} Auswahl(en)` : '–'}</span>
                      </div>
                    </div>
                    {obj.user_notes && (
                      <div style={{ padding: '4px 8px 6px 12px', fontSize: 11.5, color: 'var(--text-2)', lineHeight: 1.4, borderTop: '1px solid var(--border)' }}>
                        {obj.user_notes}
                      </div>
                    )}
                  </div>
                ))}
              </div>
            )}
          </div>
        </aside>

        {/* Center: Canvas */}
        <main className="canvas-area">
          <div className="canvas-frame" style={{ position: 'relative', background: 'var(--surface-2)' }}>
            {/* Blurhash-Platzhalter: sichtbar solange das echte Bild noch lädt */}
            {currentPicture?.blurhash && !imageLoaded && (
              <BlurhashCanvas
                hash={currentPicture.blurhash}
                width={32}
                height={32}
                style={{ zIndex: 1 }}
              />
            )}
            <DrawCanvas
              ref={canvasRef}
              imageSrc={currentPicture && token ? directusAssetUrl(currentPicture.picture, token) : null}
              objects={canvasObjects}
              selectedObjectId={selectedObjId}
              mode="rect"
              onHasSelection={() => {}}
              onImageLoad={() => setImageLoaded(true)}
              readOnly
            />
          </div>
        </main>

        {/* Right: QA Pairs */}
        <aside className="sidebar sidebar--right" style={{ width: 300, minWidth: 240 }}>
          <div className="sidebar-panel" style={{ flex: 1, overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
            <h3 className="sidebar-heading" style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
              QA Pairs
              {pairs.length > 0 && <span className="badge">{pairs.length}</span>}
              {selectedObjId && (
                <button
                  onClick={refreshPairs}
                  style={{ marginLeft: 'auto', background: 'none', border: 'none', cursor: 'pointer', fontSize: 13, color: 'var(--muted)', padding: '0 2px' }}
                  title="Neu laden"
                >↺</button>
              )}
            </h3>
            <div style={{ overflowY: 'auto', flex: 1 }}>
              <PairsList
                pairs={pairs}
                loading={pairsLoading}
                objectId={selectedObjId}
                token={token ?? ''}
                onRefresh={refreshPairs}
              />
            </div>
          </div>
        </aside>
      </div>
    </div>
  )
}
