import { useState, useEffect, useRef } from 'react'
import DrawCanvas, { type DrawCanvasHandle } from '../components/DrawCanvas'
import GenerateObjectsList from '../components/GenerateObjectsList'

import Topbar from '../components/Topbar'
import {
  getDirectusPictures,
  directusAssetUrl,
  type DirectusPicture,
  getDirectusObjects,
  generateQuestions,
  publishQuestions,
  type GenerateStats,
} from '../api'
import { useAuth } from '../context/AuthContext'
import type { DirectusObject, 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>
)

const GenerateIcon = () => (
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <path d="M12 2l2.4 7.4H22l-6.2 4.5 2.4 7.4L12 17l-6.2 4.3 2.4-7.4L2 9.4h7.6z" />
  </svg>
)

const PublishIcon = () => (
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <path d="M12 19V5M5 12l7-7 7 7" />
  </svg>
)

const SaveIcon = () => (
  <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" />
    <polyline points="17 21 17 13 7 13 7 21" />
    <polyline points="7 3 7 8 15 8" />
  </svg>
)

// ── Prompt layout system ──────────────────────────────────────────────────────

const DEFAULT_PROMPT = `Du bist ein erfahrener Sprachlernexperte. Du erhältst die Beschreibung eines Objekts aus einem Bild (Titel, Position, Zustand, Aktion) sowie ggf. dessen Elternobjekt als Kontext. Deine Aufgabe: Erstelle ausschließlich für das genannte Objekt (nicht für das Elternobjekt) Sprachlernfragen auf 10 Niveaustufen (1–10):

* Stufe 1–2 (Anfänger): Einfachste Erkennungs- oder Ja/Nein-Fragen, z.B. „Kannst du den Hund sehen?"
* Stufe 3–5 (Grundstufe): Beschreibende Fragen zu Farbe, Form, Position
* Stufe 6–8 (Mittelstufe): Fragen zu Funktion, Vergleich oder Kontext
* Stufe 9–10 (Fortgeschritten): Sprachlich anspruchsvolle, kreative oder erklärende Fragen – die Komplexität liegt in Grammatik, Wortschatz und Satzbau, nicht im abstrakten Denken

Regeln:

* Jede Frage muss sich direkt auf das Objekt beziehen
* \`words\`: Enthält alle einzigartigen Tokens aus Frage UND Antwort zusammen (Satzzeichen ausgenommen, keine Duplikate)
* \`short_answer\`: Ein einzelnes treffendes Wort als Kurzantwort (z.B. „Ja", „schwarz", „wendig")
* \`distractor_words\`: Genau 5 Wörter, die thematisch passen, aber NICHT in Frage oder Antwort vorkommen und NICHT die Antwort sind
* Gib ausschließlich valides JSON aus – kein Text, kein Markdown

Ausgabeformat:
{
  "levels": [
    {
      "level": 1,
      "question": "Kannst du den Hund sehen?",
      "answer": "Ja, ich kann den Hund sehen.",
      "short_answer": "Ja",
      "words": ["Kannst", "du", "den", "Hund", "sehen", "Ja", "ich", "kann"],
      "distractor_words": ["Nein", "vielleicht", "Katze", "hören", "groß"]
    }
  ]
}

Informationen: {user-notes_object}
Elternobjekt: {user-notes_parentobject}`

interface PromptLayout {
  name: string
  prompt: string
}

const STORAGE_KEY = 'cm_prompt_layouts'

function loadLayouts(): PromptLayout[] {
  const defaultLayout: PromptLayout = { name: 'Standard', prompt: DEFAULT_PROMPT }
  try {
    const stored = localStorage.getItem(STORAGE_KEY)
    if (!stored) return [defaultLayout]
    const parsed = JSON.parse(stored) as PromptLayout[]
    const hasDefault = parsed.some(l => l.name === 'Standard')
    return hasDefault ? parsed : [defaultLayout, ...parsed]
  } catch {
    return [defaultLayout]
  }
}

function persistLayouts(layouts: PromptLayout[]): void {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(layouts))
}


// ── Component ─────────────────────────────────────────────────────────────────

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

  const [pictureList, setPictureList] = useState<DirectusPicture[]>([])
  const [currentIndex, setCurrentIndex] = useState(-1)
  const [directusObjects, setDirectusObjects] = useState<DirectusObject[]>([])
  const [selectedObjId, setSelectedObjId] = useState<string | null>(null)
  const [isGenerating, setIsGenerating] = useState(false)
  const [isPublishing, setIsPublishing] = useState(false)
  const [generateResult, setGenerateResult] = useState<GenerateStats | null>(null)
  const [generateError, setGenerateError] = useState<string | null>(null)
  const [publishResult, setPublishResult] = useState<{ q: number; w: number } | null>(null)

  // Prompt layouts
  const [layouts, setLayouts] = useState<PromptLayout[]>(loadLayouts)
  const [selectedLayoutName, setSelectedLayoutName] = useState('Standard')
  const [promptText, setPromptText] = useState(() => loadLayouts()[0]?.prompt ?? DEFAULT_PROMPT)
  const [showSaveDialog, setShowSaveDialog] = useState(false)
  const [newLayoutName, setNewLayoutName] = useState('')
  const [promptOpen, setPromptOpen] = useState(false)

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

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

  useEffect(() => {
    if (!token) return
    getDirectusPictures(token, 'drawing_created')
      .then(pics => { setPictureList(pics); setCurrentIndex(pics.length > 0 ? 0 : -1) })
      .catch(console.error)
  }, [token])

  useEffect(() => {
    if (!currentPicture || !token) {
      setDirectusObjects([]); setSelectedObjId(null)
      setGenerateResult(null); setPublishResult(null); setGenerateError(null)
      return
    }
    getDirectusObjects(currentPicture.id, token)
      .then(objs => {
        setDirectusObjects(objs)
        if (objs.length > 0) setSelectedObjId(objs[0].id)
        else setSelectedObjId(null)
      })
      .catch(console.error)
  }, [currentPicture?.id, token])

  const handleGenerate = async () => {
    if (!selectedObjId || !token) return
    setIsGenerating(true)
    setGenerateResult(null)
    setGenerateError(null)
    setPublishResult(null)
    try {
      const res = await generateQuestions(selectedObjId, promptText, token)
      setGenerateResult(res.stats)
    } catch (e) {
      setGenerateError(e instanceof Error ? e.message : 'Fehler beim Generieren')
    } finally {
      setIsGenerating(false)
    }
  }

  const handlePublish = async () => {
    if (!selectedObjId || !token) return
    setIsPublishing(true)
    setPublishResult(null)
    try {
      const res = await publishQuestions(selectedObjId, token)
      setPublishResult({ q: res.published_questions, w: res.published_words })
    } catch (e) {
      setGenerateError(e instanceof Error ? e.message : 'Fehler beim Veröffentlichen')
    } finally {
      setIsPublishing(false)
    }
  }

  // Layout handlers
  const handleSelectLayout = (name: string) => {
    const layout = layouts.find(l => l.name === name)
    if (layout) { setSelectedLayoutName(name); setPromptText(layout.prompt) }
  }

  const handleSaveLayout = () => {
    const trimmed = newLayoutName.trim()
    if (!trimmed) return
    const newLayout: PromptLayout = { name: trimmed, prompt: promptText }
    const updated = [...layouts.filter(l => l.name !== trimmed), newLayout]
    setLayouts(updated)
    persistLayouts(updated)
    setSelectedLayoutName(trimmed)
    setNewLayoutName('')
    setShowSaveDialog(false)
  }

  const handleDeleteLayout = (name: string) => {
    if (name === 'Standard') return
    const updated = layouts.filter(l => l.name !== name)
    setLayouts(updated)
    persistLayouts(updated)
    if (selectedLayoutName === name) {
      const first = updated[0]
      setSelectedLayoutName(first.name)
      setPromptText(first.prompt)
    }
  }

  const imageNav = (
    <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
      <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>

      <div style={{ width: 1, height: 24, background: 'var(--border)' }} />

      <button
        className="btn-ghost btn-sm"
        onClick={handleGenerate}
        disabled={isGenerating || isPublishing || !selectedObjId}
        style={isGenerating ? { opacity: 0.7 } : undefined}
      >
        <GenerateIcon />
        {isGenerating ? 'Generiere…' : 'Generate it'}
      </button>
      <button
        className="btn-ghost btn-sm"
        onClick={handlePublish}
        disabled={isPublishing || isGenerating || !selectedObjId || !generateResult}
        title={!generateResult ? 'Erst Generate it ausführen' : undefined}
      >
        <PublishIcon />
        {isPublishing ? 'Veröffentliche…' : 'Publish it'}
      </button>

      {generateResult && !isGenerating && (
        <span style={{ fontSize: 11, color: 'var(--success)', background: 'var(--success-bg)', border: '1px solid var(--success)', borderRadius: 'var(--r-full)', padding: '2px 8px' }}>
          ✓ {generateResult.questions_created}F +{generateResult.words_created}W neu
        </span>
      )}
      {publishResult && (
        <span style={{ fontSize: 11, color: 'var(--primary-muted-fg)', background: 'var(--primary-muted)', border: '1px solid var(--primary)', borderRadius: 'var(--r-full)', padding: '2px 8px' }}>
          ↑ {publishResult.q}F {publishResult.w}W
        </span>
      )}
      {generateError && (
        <span style={{ fontSize: 11, color: 'var(--danger)', background: 'var(--danger-bg)', border: '1px solid var(--danger)', borderRadius: 'var(--r-full)', padding: '2px 8px', maxWidth: 200, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
          {generateError}
        </span>
      )}
    </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
              {directusObjects.length > 0 && <span className="badge">{directusObjects.length}</span>}
            </h3>
            <GenerateObjectsList
              objects={directusObjects}
              selectedId={selectedObjId}
              onSelect={id => setSelectedObjId(id)}
            />
          </div>
        </aside>

        {/* Center: Canvas + Prompt Bar */}
        <main className="canvas-area canvas-area--relative">
          <div className="canvas-frame">
            <DrawCanvas
              ref={canvasRef}
              imageSrc={currentPicture && token ? directusAssetUrl(currentPicture.media, token) : null}
              objects={canvasObjects}
              selectedObjectId={selectedObjId}
              mode="rect"
              onHasSelection={() => {}}
              readOnly
            />
          </div>

          {/* Collapsible Prompt Bar */}
          <div className={`prompt-bar${promptOpen ? ' prompt-bar--open' : ''}`}>
            <div className="prompt-bar-header" onClick={() => setPromptOpen(o => !o)}>
              <span className="prompt-bar-chevron">{promptOpen ? '▾' : '▸'}</span>
              <span className="prompt-bar-title">Prompt</span>
              <span className="prompt-bar-layout-name">{selectedLayoutName}</span>
              <div className="prompt-bar-actions" onClick={e => e.stopPropagation()}>
                <select
                  className="prompt-layout-select"
                  value={selectedLayoutName}
                  onChange={e => handleSelectLayout(e.target.value)}
                >
                  {layouts.map(l => (
                    <option key={l.name} value={l.name}>{l.name}</option>
                  ))}
                </select>
                {selectedLayoutName !== 'Standard' && (
                  <button
                    className="btn-ghost btn-sm btn-danger"
                    onClick={() => handleDeleteLayout(selectedLayoutName)}
                    title="Layout löschen"
                  >✕</button>
                )}
                <button
                  className="btn-ghost btn-sm"
                  onClick={() => { setNewLayoutName(''); setShowSaveDialog(s => !s) }}
                >
                  <SaveIcon />
                  Speichern
                </button>
              </div>
            </div>

            {promptOpen && (
              <div className="prompt-bar-body">
                {showSaveDialog && (
                  <div className="prompt-save-dialog">
                    <input
                      type="text"
                      placeholder="Layout-Name"
                      value={newLayoutName}
                      onChange={e => setNewLayoutName(e.target.value)}
                      onKeyDown={e => { if (e.key === 'Enter') handleSaveLayout(); if (e.key === 'Escape') setShowSaveDialog(false) }}
                      autoFocus
                    />
                    <button className="btn-ghost btn-sm" onClick={handleSaveLayout} disabled={!newLayoutName.trim()}>
                      Speichern
                    </button>
                    <button className="btn-ghost btn-sm" onClick={() => setShowSaveDialog(false)}>
                      Abbrechen
                    </button>
                  </div>
                )}
                <textarea
                  className="prompt-textarea"
                  value={promptText}
                  onChange={e => setPromptText(e.target.value)}
                  placeholder="Prompt eingeben…"
                />
              </div>
            )}
          </div>
        </main>

        {/* Right: Generate results */}
        <aside className="sidebar sidebar--right">
          <div className="sidebar-panel" style={{ flex: 1 }}>
            <h3 className="sidebar-heading">Ergebnis</h3>
            {generateResult ? (
              <div style={{ padding: '8px 12px', fontSize: 13, display: 'flex', flexDirection: 'column', gap: 6 }}>
                <div><strong>{generateResult.questions_created}</strong> Fragen erstellt</div>
                <div><strong>{generateResult.questions_linked}</strong> Fragen verknüpft</div>
                <div><strong>{generateResult.words_created}</strong> Wörter erstellt</div>
                <div><strong>{generateResult.words_linked}</strong> Wörter verknüpft</div>
              </div>
            ) : (
              <div className="empty-state">Klicke „Generate it".</div>
            )}
            {publishResult && (
              <div style={{ padding: '0 12px 8px', fontSize: 13, display: 'flex', flexDirection: 'column', gap: 6, color: 'var(--primary)' }}>
                <div>↑ {publishResult.q} Fragen veröffentlicht</div>
                <div>↑ {publishResult.w} Wörter veröffentlicht</div>
              </div>
            )}
          </div>
        </aside>
      </div>
    </div>
  )
}
