import { useState, useEffect, useRef } from 'react'
import Icon from './components/Icon'
import {
  onMessage, notifyReady,
  requestMassstab, setMassstab,
  zoomOneToOne, zoomExtents, zoomSelection,
  setMassstabDpi, detectMassstabDpi, setShowLineweights,
} from './lib/rhinoBridge'

const PRESETS = [
  { value: 1,    label: '1:1'   },
  { value: 5,    label: '1:5'   },
  { value: 10,   label: '1:10'  },
  { value: 20,   label: '1:20'  },
  { value: 25,   label: '1:25'  },
  { value: 50,   label: '1:50'  },
  { value: 100,  label: '1:100' },
  { value: 200,  label: '1:200' },
  { value: 500,  label: '1:500' },
  { value: 1000, label: '1:1000'},
]

function fmtScale(s) {
  if (s == null) return '—'
  if (s >= 1)   return '1:' + (s >= 10 ? s.toFixed(0) : s.toFixed(1))
  return (1 / s).toFixed(2) + ':1'
}

function snapToPreset(s, tol = 0.03) {
  if (s == null) return null
  for (const p of PRESETS) {
    if (Math.abs(s - p.value) / p.value <= tol) return p.value
  }
  return null
}

function parseScale(input) {
  if (!input) return null
  const s = String(input).trim()
  for (const sep of [':', '=', '/']) {
    if (s.includes(sep)) {
      const [a, b] = s.split(sep, 2)
      const pa = parseFloat(a)
      const pb = parseFloat(b)
      if (pa > 0 && pb > 0) return pb / pa
      return null
    }
  }
  const n = parseFloat(s)
  return n > 0 ? n : null
}

// ---------------------------------------------------------------------------

export default function MassstabApp() {
  const [state, setState] = useState({
    viewName: null, parallel: false, scale: null,
    pixelWidth: null, pixelHeight: null, unitSystem: '?',
    dpi: 96, dpiSource: 'default',
    showLineweights: false,
  })
  const [appliedScale, setAppliedScale] = useState(null)
  const appliedScaleRef = useRef(null)
  const [draft, setDraft] = useState('')
  const [dpiOpen, setDpiOpen] = useState(false)
  const [dpiDraft, setDpiDraft] = useState('96')

  useEffect(() => {
    onMessage('STATE', (s) => {
      setState((prev) => ({ ...prev, ...s }))
      // Backend appliedScale (gilt nur fuer aktuellen Viewport) > Live-Snap > roher Live-Wert
      let next = null
      if (typeof s?.appliedScale === 'number' && s.appliedScale > 0) {
        next = s.appliedScale
      } else if (s?.parallel && typeof s?.scale === 'number' && s.scale > 0) {
        const snap = snapToPreset(s.scale)
        next = snap != null ? snap : Math.round(s.scale * 10) / 10
      }
      if (next != null && next > 0 && next !== appliedScaleRef.current) {
        setAppliedScale(next)
        appliedScaleRef.current = next
      }
    })
    notifyReady()
    setTimeout(() => requestMassstab(), 50)
  }, [])

  const isPerspective = state.parallel === false
  const scaleVal = state.scale
  const dropdownValue = appliedScale != null ? String(appliedScale) : '__none__'

  const applyDropdown = (val) => {
    if (val === '__none__') return
    const r = parseFloat(val)
    if (r > 0) {
      setAppliedScale(r)
      appliedScaleRef.current = r
      setMassstab(r)
    }
  }

  const applyDraft = () => {
    const r = parseScale(draft)
    if (r != null) {
      setAppliedScale(r)
      appliedScaleRef.current = r
      setMassstab(r)
      setDraft('')
    }
  }

  const commitDpi = () => {
    const v = parseFloat(dpiDraft)
    if (v >= 30 && v <= 600) setMassstabDpi(v)
    setDpiOpen(false)
  }

  // "100%" = Viewport-Zoom auf den aktuell eingestellten Massstab snappen
  // (nicht: Massstab auf 1:1 setzen). Praktisch nach Pan/Zoom, um wieder
  // zur Soll-Skala zu kommen.
  const apply100 = () => {
    if (appliedScale && appliedScale > 0) {
      setMassstab(appliedScale)
    }
  }

  // --- Style-Bausteine ------------------------------------------------------
  const cellBtn = {
    fontSize: 11, padding: '0 8px', height: 24,
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 4,
    background: 'var(--bg-item)', border: '1px solid var(--border)',
    borderRadius: 'var(--r)', color: 'var(--text-primary)', cursor: 'pointer',
    whiteSpace: 'nowrap',
  }
  const cellInput = {
    fontSize: 11, padding: '0 6px', height: 24, minWidth: 0,
    background: 'var(--bg-input)', border: '1px solid var(--border)',
    borderRadius: 'var(--r)', color: 'var(--text-primary)',
  }

  return (
    <div style={{
      width: '100%', height: '100%',
      display: 'flex', alignItems: 'center', gap: 6,
      padding: '4px 8px',
      fontFamily: 'var(--font)', color: 'var(--text-primary)',
      background: 'var(--bg-base)',
      borderTop: '1px solid var(--border)',
      boxSizing: 'border-box',
      overflow: 'hidden',
    }}>
      {/* Live-Zoom Anzeige */}
      <div style={{
        fontSize: 13, fontWeight: 600,
        fontFamily: 'DM Mono, monospace',
        minWidth: 56, textAlign: 'right',
        color: isPerspective ? 'var(--text-muted)' : 'var(--text-primary)',
      }} title={isPerspective ? 'Perspective — kein Massstab'
                              : `Aktueller Zoom (live)${appliedScale!=null ? ` · gesetzt 1:${appliedScale}` : ''}`}>
        {isPerspective ? '—' : fmtScale(scaleVal)}
      </div>

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

      {/* Skala-Dropdown */}
      <select
        disabled={isPerspective}
        value={dropdownValue}
        onChange={(e) => applyDropdown(e.target.value)}
        style={{ ...cellInput, width: 80 }}
        title="Massstab wählen"
      >
        <option value="__none__">1:?</option>
        {PRESETS.map(p => (
          <option key={p.value} value={String(p.value)}>{p.label}</option>
        ))}
        {appliedScale != null && !PRESETS.some(p => p.value === appliedScale) && (
          <option value={String(appliedScale)}>1:{appliedScale}</option>
        )}
      </select>

      {/* Freitext */}
      <input
        disabled={isPerspective}
        type="text"
        placeholder="1:N"
        value={draft}
        onChange={(e) => setDraft(e.target.value)}
        onKeyDown={(e) => { if (e.key === 'Enter') applyDraft() }}
        onBlur={() => { if (draft) applyDraft() }}
        style={{ ...cellInput, width: 64 }}
        title="Eigenen Massstab eingeben (Enter)"
      />

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

      {/* Aktions-Buttons */}
      <button
        disabled={isPerspective || !appliedScale}
        onClick={apply100}
        style={cellBtn}
        title={appliedScale
          ? `Zoom auf eingestellten Massstab snappen (1:${appliedScale >= 10 ? Math.round(appliedScale) : appliedScale})`
          : 'Erst einen Massstab wählen'}
      >100%</button>
      <button onClick={zoomExtents} style={cellBtn} title="Auf gesamten Inhalt zoomen">
        <Icon name="fit_screen" size={14} />
      </button>
      <button onClick={zoomSelection} style={cellBtn} title="Auf Selektion zoomen">
        <Icon name="center_focus_strong" size={14} />
      </button>

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

      {/* Print-View / Strichstaerken-Toggle
          Beide Icons werden permanent gerendert; nur display: none togglet,
          damit die Font-Ligatur nicht neu aufgeloest wird (sonst Flackern). */}
      <button
        onClick={() => setShowLineweights(!state.showLineweights)}
        style={{
          ...cellBtn,
          background: state.showLineweights ? 'var(--accent)' : 'var(--bg-item)',
          color:      state.showLineweights ? '#fff' : 'var(--text-primary)',
          borderColor: state.showLineweights ? 'var(--accent)' : 'var(--border)',
        }}
        title={state.showLineweights
          ? 'Strichstärken werden angezeigt (Print-View) — klicken zum Ausschalten'
          : 'Strichstärken als Hairlines (Edit-View) — klicken um Print-View zu zeigen'}
      >
        <Icon name="edit"  size={14} style={{ display: state.showLineweights ? 'none' : 'inline-block' }} />
        <Icon name="print" size={14} style={{ display: state.showLineweights ? 'inline-block' : 'none' }} />
        <span style={{ fontSize: 10 }}>{state.showLineweights ? 'Print' : 'Edit'}</span>
      </button>

      {/* Spacer */}
      <div style={{ flex: 1 }} />

      {/* View-Name */}
      <div style={{
        fontSize: 10, color: 'var(--text-muted)',
        whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
        maxWidth: 140,
      }} title={state.viewName || ''}>
        {state.viewName || '?'}{isPerspective ? ' · Persp.' : ''}
      </div>

      {/* DPI-Popover */}
      <div style={{ position: 'relative' }}>
        <button
          onClick={() => { setDpiDraft(String(state.dpi || 96)); setDpiOpen(o => !o) }}
          style={{ ...cellBtn, fontSize: 10, padding: '0 6px', height: 22,
                   color: state.dpiSource === 'auto'    ? 'var(--accent)'
                        : state.dpiSource === 'manual'  ? 'var(--text-primary)'
                        : 'var(--text-muted)' }}
          title={`DPI Kalibrierung — aktuell ${Math.round(state.dpi || 96)} dpi (${state.dpiSource || 'default'})`}
        >
          {Math.round(state.dpi || 96)}dpi
          {state.dpiSource === 'auto' && (
            <span style={{ marginLeft: 3, fontSize: 8, opacity: 0.8 }}>auto</span>
          )}
        </button>
        {dpiOpen && (
          <div style={{
            position: 'absolute', right: 0, bottom: '100%', marginBottom: 4,
            background: 'var(--bg-panel)', border: '1px solid var(--border)',
            borderRadius: 'var(--r)', padding: 8, display: 'flex',
            flexDirection: 'column', gap: 6,
            boxShadow: '0 4px 12px rgba(0,0,0,0.15)', zIndex: 10, minWidth: 220,
          }}>
            <div style={{ fontSize: 10, color: 'var(--text-muted)' }}>
              Bildschirm-Auflösung für Massstab-Berechnung
            </div>
            <div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
              <input
                type="number" min={30} max={600}
                value={dpiDraft}
                onChange={(e) => setDpiDraft(e.target.value)}
                onKeyDown={(e) => { if (e.key === 'Enter') commitDpi() }}
                autoFocus
                style={{ ...cellInput, flex: 1 }}
              />
              <button onClick={commitDpi} style={{ ...cellBtn, fontSize: 10 }}>OK</button>
            </div>
            <button
              onClick={() => { detectMassstabDpi(); setDpiOpen(false) }}
              style={{ ...cellBtn, fontSize: 10, justifyContent: 'flex-start' }}
              title="DPI automatisch über EDID des Bildschirms ermitteln"
            >
              <Icon name="auto_fix_high" size={12} /> Auto-Detect (EDID)
            </button>
          </div>
        )}
      </div>
    </div>
  )
}
