// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2026 Karim Gabriele Varano
import { useState, useEffect, useMemo } from 'react'
import Icon from './components/Icon'
import ContextMenu from './components/ContextMenu'
import { t } from './i18n/index.js'
import {
  onMessage, notifyReady,
  listAusschnitte, saveAusschnitt, updateAusschnitt,
  restoreAusschnitt, applyAusschnittToDetail,
  renameAusschnitt, deleteAusschnitt,
  setAusschnittFolder, setAusschnittScale,
  duplicateAusschnitt, addAusschnittFolder, removeAusschnittFolder,
  openAusschnittSettings,
} from './lib/rhinoBridge'

function EditableInline({ value, onCommit, autoEdit, style, fontSize }) {
  const [editing, setEditing] = useState(autoEdit || false)
  const [val, setVal] = useState(value)
  useEffect(() => { setVal(value) }, [value])
  useEffect(() => { if (autoEdit) setEditing(true) }, [autoEdit])

  const commit = () => {
    const trimmed = (val ?? '').trim()
    if (trimmed && trimmed !== value) onCommit(trimmed)
    else setVal(value)
    setEditing(false)
  }
  if (editing) {
    return (
      <input
        value={val}
        autoFocus
        onChange={(ev) => setVal(ev.target.value)}
        onBlur={commit}
        onKeyDown={(ev) => {
          if (ev.key === 'Enter') commit()
          if (ev.key === 'Escape') { setVal(value); setEditing(false) }
        }}
        onClick={(ev) => ev.stopPropagation()}
        style={{ ...style, fontSize, padding: '2px 6px' }}
      />
    )
  }
  return (
    <span
      onDoubleClick={(ev) => { ev.stopPropagation(); setVal(value); setEditing(true) }}
      style={{ ...style, fontSize, cursor: 'text' }}
    >{value}</span>
  )
}

function ScaleCell({ snap, onChange }) {
  const [editing, setEditing] = useState(false)
  const [val, setVal] = useState(snap.scale || '')
  useEffect(() => { setVal(snap.scale || '') }, [snap.scale])

  const commit = () => {
    onChange(snap.id, val.trim())
    setEditing(false)
  }
  if (editing) {
    return (
      <input
        value={val}
        autoFocus
        onChange={(ev) => setVal(ev.target.value)}
        onBlur={commit}
        onKeyDown={(ev) => {
          if (ev.key === 'Enter') commit()
          if (ev.key === 'Escape') { setVal(snap.scale || ''); setEditing(false) }
        }}
        onClick={(ev) => ev.stopPropagation()}
        placeholder="1:50"
        style={{ width: 64, fontSize: 10, padding: '2px 6px', textAlign: 'right' }}
      />
    )
  }
  return (
    <span
      onDoubleClick={(ev) => { ev.stopPropagation(); setEditing(true) }}
      className={snap.scale ? 'chip chip-accent' : 'chip'}
      style={{
        fontSize: 9, cursor: 'text',
        fontFamily: 'var(--font-mono)',
        flexShrink: 0,
      }}
      title={snap.scale ? `Maßstab ${snap.scale} — wird auf Detail angewendet` : 'Doppelklick um Maßstab einzutragen (z.B. 1:50)'}
    >{snap.scale || '—:—'}</span>
  )
}

function OrientationBadge({ orientation }) {
  const variant = orientation === 'perspective' ? {
    icon: 'view_in_ar', color: 'var(--accent)',
    title: 'Perspektive',
  } : orientation === 'horizontal' ? {
    icon: 'align_horizontal_center', color: 'var(--active)',
    title: 'Horizontaler Schnitt (Grundriss)',
  } : {
    icon: 'align_vertical_center', color: 'var(--warn)',
    title: 'Vertikaler Schnitt (Schnitt / Ansicht)',
  }
  return (
    <span
      title={variant.title}
      style={{
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        width: 20, height: 20, flexShrink: 0,
        borderRadius: 999,
        background: 'var(--bg-input)',
        color: variant.color,
      }}
    >
      <Icon name={variant.icon} size={12} />
    </span>
  )
}

function AusschnittCard({ snap, onClick, onContextMenu, onMenuClick, onRename, onScaleChange, onDragStart, onDragEnd, dragging }) {
  return (
    <div
      draggable
      onClick={onClick}
      onContextMenu={onContextMenu}
      onDragStart={onDragStart}
      onDragEnd={onDragEnd}
      style={{
        display: 'flex', alignItems: 'center', gap: 6,
        padding: '2px 8px 2px 4px',
        border: '1px solid var(--border-light)',
        borderRadius: 999,
        background: 'var(--bg-input)',
        cursor: 'grab', userSelect: 'none',
        marginBottom: 3,
        opacity: dragging ? 0.4 : 1,
        transition: 'background 0.14s, border-color 0.14s, opacity 0.14s',
      }}
      onMouseEnter={(ev) => { ev.currentTarget.style.background = 'var(--bg-item-hover)' }}
      onMouseLeave={(ev) => { ev.currentTarget.style.background = 'var(--bg-input)' }}
    >
      <OrientationBadge orientation={snap.orientation} />
      <EditableInline
        value={snap.name}
        onCommit={(n) => onRename(snap.id, n)}
        fontSize={11}
        style={{
          flex: 1, minWidth: 0,
          color: 'var(--text-primary)', fontWeight: 500,
          overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
        }}
      />
      <ScaleCell snap={snap} onChange={onScaleChange} />
      <button
        className="btn-icon-sm"
        onClick={(ev) => { ev.stopPropagation(); onMenuClick(ev) }}
        title="Aktionen"
      >
        <Icon name="more_vert" size={14} />
      </button>
    </div>
  )
}

function FolderCard({
  name, count, collapsed, onToggle, onContextMenu, onMenuClick,
  onDragOver, onDragLeave, onDrop, dragOver, children,
}) {
  return (
    <div
      onContextMenu={onContextMenu}
      onDragOver={onDragOver}
      onDragLeave={onDragLeave}
      onDrop={onDrop}
      style={{
        border: '1px solid var(--border)',
        borderRadius: 'var(--r-lg)',
        background: dragOver ? 'var(--accent-dim)' : 'var(--bg-section)',
        marginBottom: 8,
        padding: 8,
        transition: 'background 0.14s, border-color 0.14s',
        borderColor: dragOver ? 'var(--accent-border)' : 'var(--border)',
      }}
    >
      <div
        onClick={onToggle}
        style={{
          display: 'flex', alignItems: 'center', gap: 6,
          cursor: 'pointer', userSelect: 'none',
          padding: 2,
        }}
      >
        <span style={{
          transform: collapsed ? 'rotate(-90deg)' : 'rotate(0deg)',
          transition: 'transform 0.2s cubic-bezier(0.4, 0, 0.2, 1)',
          color: 'var(--text-muted)', display: 'inline-flex',
        }}>
          <Icon name="arrow_drop_down" size={16} />
        </span>
        <Icon name="folder" size={14} style={{ color: 'var(--warn)' }} />
        <span style={{ flex: 1, fontSize: 11, fontWeight: 500, color: 'var(--text-primary)' }}>{name}</span>
        <span className="chip" style={{ fontSize: 8 }}>{count}</span>
        <button
          className="btn-icon-sm"
          onClick={(ev) => { ev.stopPropagation(); onMenuClick(ev) }}
          title="Ordner-Aktionen"
        >
          <Icon name="more_vert" size={14} />
        </button>
      </div>
      {!collapsed && (
        <div style={{ marginTop: 6, display: 'flex', flexDirection: 'column' }}>
          {children || (
            <div style={{
              padding: '10px 6px', fontSize: 10, color: 'var(--text-muted)',
              textAlign: 'center', fontStyle: 'italic',
            }}>
              Leer — Ausschnitte hier ablegen.
            </div>
          )}
        </div>
      )}
    </div>
  )
}

function RootDropZone({ children, onDragOver, onDragLeave, onDrop, dragOver, empty }) {
  return (
    <div
      onDragOver={onDragOver}
      onDragLeave={onDragLeave}
      onDrop={onDrop}
      style={{
        background: dragOver ? 'var(--accent-dim)' : 'transparent',
        border: '1px dashed transparent',
        borderColor: dragOver ? 'var(--accent-border)' : 'transparent',
        borderRadius: 'var(--r-lg)',
        padding: dragOver || empty ? 6 : 0,
        marginBottom: empty ? 0 : 8,
        transition: 'background 0.14s, border-color 0.14s, padding 0.14s',
      }}
    >
      {children}
    </div>
  )
}

export default function AusschnitteApp() {
  const [snaps,         setSnaps]         = useState([])
  const [extraFolders,  setExtraFolders]  = useState([])
  const [newName,       setNewName]       = useState('')
  const [ctxMenu,       setCtxMenu]       = useState(null)
  const [collapsed,     setCollapsed]     = useState({})
  const [draggingId,    setDraggingId]    = useState(null)
  const [dragTarget,    setDragTarget]    = useState(null)

  useEffect(() => {
    onMessage('LIST', ({ snapshots, folders }) => {
      setSnaps(snapshots || [])
      setExtraFolders(folders || [])
    })
    notifyReady()
    const blockContext = (ev) => ev.preventDefault()
    document.addEventListener('contextmenu', blockContext)
    return () => document.removeEventListener('contextmenu', blockContext)
  }, [])

  const groups = useMemo(() => {
    const map = {}
    snaps.forEach(s => {
      const f = s.folder || ''
      if (!map[f]) map[f] = []
      map[f].push(s)
    })
    return map
  }, [snaps])

  const allFolders = useMemo(() => {
    const set = new Set(extraFolders)
    snaps.forEach(s => { if (s.folder) set.add(s.folder) })
    return [...set].sort((a, b) => a.localeCompare(b))
  }, [snaps, extraFolders])

  const handleSave = () => {
    const name = newName.trim() || `Ausschnitt ${snaps.length + 1}`
    saveAusschnitt(name)
    setNewName('')
  }

  const handleAddFolder = () => {
    const name = window.prompt(t('viewports.new_folder_name'))
    if (name && name.trim()) addAusschnittFolder(name.trim())
  }

  const ctxItems = (id) => [
    { label: t('viewports.restore'),        icon: 'restore',        onClick: () => restoreAusschnitt(id) },
    { label: t('viewports.apply_to_detail'),icon: 'crop_landscape', onClick: () => applyAusschnittToDetail(id) },
    { divider: true },
    { label: t('viewports.settings'),       icon: 'tune',           onClick: () => openAusschnittSettings(id) },
    { divider: true },
    { label: t('common.duplicate'),         icon: 'content_copy',   onClick: () => duplicateAusschnitt(id) },
    { label: t('viewports.update'),         icon: 'sync',           onClick: () => updateAusschnitt(id) },
    { divider: true },
    { label: t('common.delete'),            icon: 'delete', danger: true, onClick: () => deleteAusschnitt(id) },
  ]

  const folderCtxItems = (folderName) => [
    { label: t('common.rename_folder'), icon: 'edit', onClick: () => {
      const newName = window.prompt(t('common.new_folder_name'), folderName)
      if (newName && newName.trim() && newName !== folderName) {
        snaps.filter(s => s.folder === folderName).forEach(s => setAusschnittFolder(s.id, newName.trim()))
        addAusschnittFolder(newName.trim())
        removeAusschnittFolder(folderName)
      }
    }},
    { divider: true },
    { label: t('common.delete_folder'), icon: 'folder_off', danger: true, onClick: () => {
      if (window.confirm(`${t('common.delete_folder')} "${folderName}"? ${t('viewports.delete_folder_confirm')}`)) {
        removeAusschnittFolder(folderName)
      }
    }},
  ]

  const handleDrop = (folderName) => (ev) => {
    ev.preventDefault()
    setDragTarget(null)
    const id = ev.dataTransfer.getData('text/plain') || draggingId
    if (id) setAusschnittFolder(id, folderName || '')
    setDraggingId(null)
  }

  const handleDragOver = (folderName) => (ev) => {
    ev.preventDefault()
    ev.dataTransfer.dropEffect = 'move'
    setDragTarget(folderName || 'root')
  }

  const handleDragLeave = () => () => setDragTarget(null)

  const renderSnapshot = (s) => (
    <AusschnittCard
      key={s.id}
      snap={s}
      dragging={draggingId === s.id}
      onClick={() => restoreAusschnitt(s.id)}
      onContextMenu={(ev) => { ev.preventDefault(); setCtxMenu({ x: ev.clientX, y: ev.clientY, id: s.id, kind: 'snap' }) }}
      onMenuClick={(ev) => setCtxMenu({ x: ev.clientX, y: ev.clientY, id: s.id, kind: 'snap' })}
      onRename={(id, name) => renameAusschnitt(id, name)}
      onScaleChange={(id, scale) => setAusschnittScale(id, scale)}
      onDragStart={(ev) => {
        ev.dataTransfer.setData('text/plain', s.id)
        ev.dataTransfer.effectAllowed = 'move'
        setDraggingId(s.id)
      }}
      onDragEnd={() => { setDraggingId(null); setDragTarget(null) }}
    />
  )

  const rootItems = groups[''] || []
  const isEmpty = snaps.length === 0 && allFolders.length === 0

  return (
    <div style={{
      display: 'flex', flexDirection: 'column',
      height: '100vh', overflow: 'hidden',
      background: 'var(--bg-base)',
      position: 'relative',
    }}>
      <div style={{ flex: 1, overflowY: 'auto', padding: 8 }}>
          {/* Save-Bar — kein Outer-Border mehr, nur das Pill-Input + Add-Button. */}
          <div style={{
            display: 'flex', alignItems: 'center', gap: 6,
            marginBottom: 8,
            marginTop: 6,
          }}>
            <input
              value={newName}
              onChange={(ev) => setNewName(ev.target.value)}
              onKeyDown={(ev) => { if (ev.key === 'Enter') handleSave() }}
              placeholder="Name für neuen Ausschnitt…"
              style={{ flex: 1, fontSize: 11, fontFamily: 'var(--font)', minWidth: 0 }}
            />
            <button className="btn-add" onClick={handleSave} title="Ausschnitt speichern">
              <Icon name="add" size={16} />
            </button>
          </div>

          {isEmpty ? (
            <div style={{
              padding: '32px 16px', textAlign: 'center',
              color: 'var(--text-muted)', fontSize: 11,
              border: '1px dashed var(--border)',
              borderRadius: 'var(--r-lg)',
              background: 'var(--bg-section)',
            }}>
              <Icon name="photo_library" size={32} style={{ color: 'var(--text-muted)', opacity: 0.5 }} />
              <div style={{ marginTop: 8 }}>Noch keine Ausschnitte.</div>
              <div style={{ marginTop: 4, fontSize: 10 }}>Oben einen Namen eingeben und <Icon name="add" size={11} /> klicken.</div>
            </div>
          ) : (
            <>
              {/* Root-Snapshots */}
              <RootDropZone
                dragOver={dragTarget === 'root'}
                empty={rootItems.length === 0}
                onDragOver={handleDragOver('')}
                onDragLeave={handleDragLeave()}
                onDrop={handleDrop('')}
              >
                {rootItems.map(s => renderSnapshot(s))}
                {rootItems.length === 0 && draggingId && (
                  <div style={{
                    padding: '8px 14px', fontSize: 10, color: 'var(--text-muted)',
                    textAlign: 'center', fontStyle: 'italic',
                  }}>Hier ablegen für Wurzel</div>
                )}
              </RootDropZone>

              {/* Ordner-Cards */}
              {allFolders.map(folder => {
                const isCollapsed = !!collapsed[folder]
                const items = groups[folder] || []
                return (
                  <FolderCard
                    key={folder}
                    name={folder}
                    count={items.length}
                    collapsed={isCollapsed}
                    dragOver={dragTarget === folder}
                    onToggle={() => setCollapsed(c => ({ ...c, [folder]: !c[folder] }))}
                    onContextMenu={(ev) => { ev.preventDefault(); setCtxMenu({ x: ev.clientX, y: ev.clientY, name: folder, kind: 'folder' }) }}
                    onMenuClick={(ev) => setCtxMenu({ x: ev.clientX, y: ev.clientY, name: folder, kind: 'folder' })}
                    onDragOver={handleDragOver(folder)}
                    onDragLeave={handleDragLeave()}
                    onDrop={handleDrop(folder)}
                  >
                    {items.length > 0 ? items.map(s => renderSnapshot(s)) : null}
                  </FolderCard>
                )
              })}
            </>
          )}
        <div style={{ padding: '12px 4px 0', fontSize: 9, color: 'var(--text-muted)',
                      lineHeight: 1.6, fontStyle: 'italic' }}>
          Drag & Drop auf Ordner-Card zum Verschieben · Doppelklick auf Name/Maßstab = bearbeiten · ⋮ für Aktionen
        </div>
      </div>

      {/* Sticky Footer: Anzahl + Ordner erstellen + Reload */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 8,
        padding: '8px 10px',
        borderTop: '1px solid var(--border)',
        background: 'var(--bg-panel)',
        flexShrink: 0,
      }}>
        <span className="chip" style={{
          fontSize: 9, minWidth: 22, justifyContent: 'center',
        }}>{snaps.length}</span>
        <span style={{ fontSize: 10, color: 'var(--text-muted)', flex: 1 }}>
          Ausschnitte
        </span>
        <button className="btn-icon-tonal" onClick={handleAddFolder} title="Neuer Ordner">
          <Icon name="create_new_folder" size={14} />
        </button>
        <button className="btn-icon-tonal" onClick={() => listAusschnitte()} title="Aktualisieren">
          <Icon name="refresh" size={14} />
        </button>
      </div>

      {ctxMenu && (
        <ContextMenu
          x={ctxMenu.x} y={ctxMenu.y}
          items={ctxMenu.kind === 'folder' ? folderCtxItems(ctxMenu.name) : ctxItems(ctxMenu.id)}
          onClose={() => setCtxMenu(null)}
        />
      )}

    </div>
  )
}
