import { useEffect, useState, useRef } from 'react'
import Icon from './components/Icon'
import {
  onMessage, notifyReady,
  setRefPoint, setCoordSystem,
  setDimPosition, setDimDimension, setDimRotationZ,
  setCircleRadius, setLineLength, setRectangleDims,
} from './lib/rhinoBridge'

// ---- Helpers --------------------------------------------------------------

const REF_CODES = ['min', 'mid', 'max']  // row/col mapping
const REF_LABELS = { min: 'min', mid: 'mid', max: 'max' }

function fmtNum(v) {
  if (v == null) return ''
  if (typeof v !== 'number') return String(v)
  // 4 Nachkommastellen, aber unnoetige Nullen weg
  return Number(v.toFixed(4)).toString()
}

// Input-Komponente: zeigt formatierten Wert, sendet onCommit bei Enter/Blur.
// Verhindert Update waehrend des Tippens, damit der Cursor nicht springt.
function NumInput({ value, onCommit, disabled, suffix, width }) {
  const [text, setText] = useState(fmtNum(value))
  const [focused, setFocused] = useState(false)
  useEffect(() => { if (!focused) setText(fmtNum(value)) }, [value, focused])
  const commit = () => {
    const v = parseFloat(text.replace(',', '.'))
    if (!isNaN(v) && v !== value) onCommit(v)
    else setText(fmtNum(value))  // ungueltig → zurueck auf alten Wert
  }
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 4, flex: width ? 0 : 1, width }}>
      <input
        type="text"
        value={text}
        disabled={disabled}
        onChange={(e) => setText(e.target.value)}
        onFocus={(e) => { setFocused(true); e.target.select() }}
        onBlur={() => { setFocused(false); commit() }}
        onKeyDown={(e) => {
          if (e.key === 'Enter') { e.target.blur() }
          else if (e.key === 'Escape') { setText(fmtNum(value)); e.target.blur() }
        }}
        style={{ flex: 1, width: '100%', fontFamily: 'DM Mono, monospace', fontSize: 11, textAlign: 'right' }}
      />
      {suffix && <span style={{ fontSize: 10, color: 'var(--text-muted)', flexShrink: 0 }}>{suffix}</span>}
    </div>
  )
}

// 9-Punkt-Referenzpunkt-Selektor: sichtbarer BBox-Rahmen, Kreise auf den
// Eckpunkten / Kantenmitten / Zentrum.
function RefPointGrid({ ref, onChange }) {
  const SIZE = 28      // Aussenkanten-Quadrat (px)
  const DOT  = 6       // Kreis-Durchmesser (px)
  const pct = (c) => c === 'min' ? '0%' : c === 'max' ? '100%' : '50%'
  return (
    <div style={{
      position: 'relative',
      width: SIZE, height: SIZE,
      border: '1px solid var(--border)',
      background: 'transparent',
      flexShrink: 0,
    }}>
      {REF_CODES.map(yc => REF_CODES.map(xc => {
        const active = ref.x === xc && ref.y === yc
        const topPct = yc === 'max' ? '0%' : yc === 'min' ? '100%' : '50%'
        return (
          <button
            key={`${xc}-${yc}`}
            onClick={() => onChange({ ...ref, x: xc, y: yc })}
            title={`X=${xc}, Y=${yc}`}
            style={{
              position: 'absolute',
              left: pct(xc), top: topPct,
              transform: 'translate(-50%, -50%)',
              width: DOT, height: DOT, padding: 0,
              borderRadius: '50%',
              background: active ? 'var(--accent)' : 'var(--text-muted)',
              border: 'none',
              cursor: 'pointer',
              transition: 'background 0.12s, transform 0.12s',
            }}
            onMouseEnter={(e) => {
              if (!active) e.currentTarget.style.background = 'var(--text-primary)'
              e.currentTarget.style.transform = 'translate(-50%, -50%) scale(1.25)'
            }}
            onMouseLeave={(e) => {
              if (!active) e.currentTarget.style.background = 'var(--text-muted)'
              e.currentTarget.style.transform = 'translate(-50%, -50%) scale(1)'
            }}
          />
        )
      }))}
    </div>
  )
}

// Z-Referenz-Selektor (Bottom / Mid / Top) — kompakt, nur Icons.
function RefZSelector({ z, onChange }) {
  return (
    <div style={{ display: 'flex', gap: 2 }}>
      {[
        { code: 'max', icon: 'vertical_align_top',    title: 'Z = Top' },
        { code: 'mid', icon: 'vertical_align_center', title: 'Z = Mid' },
        { code: 'min', icon: 'vertical_align_bottom', title: 'Z = Bottom' },
      ].map(opt => (
        <button
          key={opt.code}
          onClick={() => onChange(opt.code)}
          className={z === opt.code ? 'btn-contained' : 'btn-outlined'}
          style={{
            padding: '2px 5px', fontSize: 10,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}
          title={opt.title}
        >
          <Icon name={opt.icon} size={12} />
        </button>
      ))}
    </div>
  )
}

// Inline-Label vor einem Input — minimal, knackig
function Field({ label, children, style }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 4, ...style }}>
      <span style={{
        width: 12, fontSize: 10, fontWeight: 600,
        color: 'var(--text-muted)', textAlign: 'center',
        fontFamily: 'DM Mono, monospace', flexShrink: 0,
      }}>
        {label}
      </span>
      {children}
    </div>
  )
}

// ---- Hauptkomponente ------------------------------------------------------

export default function DimensionenApp() {
  const [state, setState] = useState({
    selection:   { count: 0, type: 'none' },
    refPoint:    { x: 'min', y: 'min', z: 'mid' },
    coordSystem: 'world',
    position:    null,
    dimensions:  null,
    shape:       null,
    planeName:   'Welt',
  })
  const [rotationDelta, setRotationDelta] = useState(0)

  useEffect(() => {
    onMessage('STATE', (s) => setState((prev) => ({ ...prev, ...s })))
    notifyReady()
  }, [])

  const sel    = state.selection || { count: 0, type: 'none' }
  const ref    = state.refPoint  || { x: 'min', y: 'min', z: 'mid' }
  const pos    = state.position
  const dims   = state.dimensions
  const shape  = state.shape
  const hasSelection = sel.count > 0 && pos != null

  const onRefChange = (next) => setRefPoint(next.x, next.y, next.z)
  const onCoordChange = (mode) => setCoordSystem(mode)

  // Selektions-Beschriftung
  const selLabel = () => {
    if (sel.count === 0) return 'Keine Selektion'
    if (sel.count === 1) {
      const map = {
        curve: 'Kurve', brep: 'Brep', mesh: 'Mesh', extrusion: 'Extrusion',
        block: 'Block', point: 'Punkt', text: 'Text', other: 'Objekt',
      }
      let base = map[sel.type] || '1 Objekt'
      if (shape?.type === 'circle')    base = 'Kreis'
      if (shape?.type === 'rectangle') base = 'Rechteck'
      if (shape?.type === 'line')      base = 'Linie'
      return '1 ' + base
    }
    return `${sel.count} Objekte`
  }

  return (
    <div style={{
      display: 'flex', flexDirection: 'column',
      height: '100vh', overflow: 'hidden',
      background: 'var(--bg-base)', color: 'var(--text-primary)',
      fontFamily: 'var(--font)', fontSize: 11,
    }}>
      <div style={{ flex: 1, overflowY: 'auto', overflowX: 'hidden' }}>

        {/* Header: Selektions-Info + World/CPlane */}
        <div style={{
          display: 'flex', alignItems: 'center', gap: 6,
          padding: '8px 12px',
          borderBottom: '1px solid var(--border-light)',
        }}>
          <Icon name="select_all" size={14} style={{ color: 'var(--text-muted)' }} />
          <span style={{ flex: 1, fontWeight: 500 }}>{selLabel()}</span>
          <div style={{ display: 'flex', gap: 2 }}>
            <button
              onClick={() => onCoordChange('world')}
              className={state.coordSystem === 'world' ? 'btn-contained' : 'btn-outlined'}
              style={{ fontSize: 10, padding: '3px 8px' }}
              title="Weltkoordinaten"
            >Welt</button>
            <button
              onClick={() => onCoordChange('cplane')}
              className={state.coordSystem === 'cplane' ? 'btn-contained' : 'btn-outlined'}
              style={{ fontSize: 10, padding: '3px 8px' }}
              title="Aktive Konstruktionsebene"
            >CPlane</button>
          </div>
        </div>

        {!hasSelection ? (
          <div style={{
            padding: '32px 16px', textAlign: 'center',
            color: 'var(--text-muted)', fontSize: 11,
          }}>
            <Icon name="aspect_ratio" size={32} style={{ color: 'var(--text-muted)', opacity: 0.4 }} />
            <div style={{ marginTop: 8 }}>Keine Selektion.</div>
            <div style={{ marginTop: 4, fontSize: 10 }}>
              In Rhino ein oder mehrere Objekte auswählen.
            </div>
          </div>
        ) : (
          <>
            {/* Referenzpunkt */}
            <div style={{
              display: 'flex', alignItems: 'center', gap: 10,
              padding: '10px 12px',
              borderBottom: '1px solid var(--border-light)',
            }}>
              <span className="label-xs" style={{ width: 30 }}>Ref</span>
              <RefPointGrid ref={ref} onChange={onRefChange} />
              <div style={{ flex: 1 }} />
              <RefZSelector z={ref.z} onChange={(z) => onRefChange({ ...ref, z })} />
            </div>

            {/* Position + BBox nebeneinander */}
            <div style={{
              display: 'flex', gap: 16,
              padding: '10px 12px',
              borderBottom: '1px solid var(--border-light)',
            }}>
              <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 4, minWidth: 0 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between',
                              alignItems: 'baseline', marginBottom: 2 }}>
                  <span className="label-xs">Position</span>
                  <span style={{ fontFamily: 'DM Mono, monospace', fontSize: 9,
                                 color: 'var(--text-muted)' }}>
                    {state.planeName}
                  </span>
                </div>
                <Field label="X"><NumInput value={pos.x} onCommit={(v) => setDimPosition('x', v)} /></Field>
                <Field label="Y"><NumInput value={pos.y} onCommit={(v) => setDimPosition('y', v)} /></Field>
                <Field label="Z"><NumInput value={pos.z} onCommit={(v) => setDimPosition('z', v)} /></Field>
              </div>
              <div style={{ width: 1, background: 'var(--border-light)' }} />
              <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 4, minWidth: 0 }}>
                <span className="label-xs" style={{ marginBottom: 2 }}>BBox</span>
                <Field label="B"><NumInput value={dims?.width}  onCommit={(v) => setDimDimension('width',  v)} /></Field>
                <Field label="T"><NumInput value={dims?.depth}  onCommit={(v) => setDimDimension('depth',  v)} /></Field>
                <Field label="H"><NumInput value={dims?.height} onCommit={(v) => setDimDimension('height', v)} /></Field>
              </div>
            </div>

            {/* Shape-spezifisch */}
            {shape && (
              <div style={{
                display: 'flex', flexDirection: 'column', gap: 4,
                padding: '10px 12px',
                borderBottom: '1px solid var(--border-light)',
              }}>
                <span className="label-xs" style={{ color: 'var(--accent)' }}>
                  {shape.type === 'circle' && 'Kreis'}
                  {shape.type === 'rectangle' && 'Rechteck'}
                  {shape.type === 'line' && 'Linie'}
                </span>
                {shape.type === 'circle' && (
                  <Field label="R"><NumInput value={shape.radius} onCommit={(v) => setCircleRadius(v)} /></Field>
                )}
                {shape.type === 'rectangle' && (
                  <div style={{ display: 'flex', gap: 8 }}>
                    <Field label="W" style={{ flex: 1 }}>
                      <NumInput value={shape.width}
                                onCommit={(v) => setRectangleDims(v, shape.height)} />
                    </Field>
                    <Field label="H" style={{ flex: 1 }}>
                      <NumInput value={shape.height}
                                onCommit={(v) => setRectangleDims(shape.width, v)} />
                    </Field>
                  </div>
                )}
                {shape.type === 'line' && (
                  <div style={{ display: 'flex', gap: 8 }}>
                    <Field label="L" style={{ flex: 1 }}>
                      <NumInput value={shape.length} onCommit={(v) => setLineLength(v)} />
                    </Field>
                    <Field label="α" style={{ flex: 1 }}>
                      <NumInput value={shape.angle} onCommit={() => {}} disabled suffix="°" />
                    </Field>
                  </div>
                )}
              </div>
            )}

            {/* Rotation */}
            <div style={{
              display: 'flex', alignItems: 'center', gap: 6,
              padding: '10px 12px',
            }}>
              <span className="label-xs" style={{ width: 50 }}>Drehen</span>
              <div style={{ width: 56 }}>
                <NumInput value={rotationDelta} onCommit={setRotationDelta} suffix="°" />
              </div>
              <button
                className="btn-outlined"
                onClick={() => { if (rotationDelta) setDimRotationZ(rotationDelta) }}
                disabled={!rotationDelta}
                title="Selektion um Z-Achse der aktiven Plane drehen"
                style={{ padding: '3px 8px', fontSize: 11 }}
              >
                <Icon name="rotate_right" size={13} />
              </button>
              <div style={{ flex: 1 }} />
              {[-90, -45, 45, 90].map(a => (
                <button
                  key={a}
                  className="btn-outlined"
                  onClick={() => setDimRotationZ(a)}
                  style={{ padding: '3px 6px', fontSize: 9, minWidth: 28 }}
                  title={`${a}°`}
                >
                  {a > 0 ? '+' : ''}{a}°
                </button>
              ))}
            </div>
          </>
        )}
      </div>
    </div>
  )
}
