import { DndContext, DragOverlay, PointerSensor, useSensor, useSensors } from '@dnd-kit/core'
import { useState } from 'react'
import { VariablePalette } from '../components/VariablePalette.jsx'
import { Workspace } from '../components/Workspace.jsx'
import { ResultsPanel } from '../components/ResultsPanel.jsx'
import { PaletteCard } from '../components/VariableCard.jsx'
import { PropellantModal } from '../components/PropellantModal.jsx'
import { EquationBrowser } from '../components/EquationBrowser.jsx'
import { useSolver } from '../hooks/useSolver.js'
import { EQUATIONS } from '../engine/equations.js'
import { buildExportData, exportJSON, parseImport, downloadBlob } from '../engine/exportImport.js'
import { generateOdt } from '../engine/exportOdt.js'

export default function Solver() {
  const {
    workspaceVarIds,
    userValues,
    solved,
    missingReport,
    allKnown,
    unitSelections,
    getUnit,
    setUnit,
    sciNotation,
    areaRatioBranch,
    toggleSciNotation,
    toggleAreaRatioBranch,
    addVariable,
    addVariables,
    removeVariable,
    reorderVariable,
    setValue,
    addPreset,
    applyPropellant,
    clearWorkspace,
    importWorkspace,
  } = useSolver()

  const [activeVarId, setActiveVarId] = useState(null)
  const [showPropellants, setShowPropellants] = useState(false)
  const [showEquations, setShowEquations] = useState(false)

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 6 } })
  )

  function handleDragStart(event) {
    const { varId } = event.active.data.current ?? {}
    if (varId) setActiveVarId(varId)
  }

  function handleDragEnd(event) {
    const { over, active } = event
    if (!over) {
      setActiveVarId(null)
      return
    }

    // Palette → workspace drop
    if (over.id === 'workspace') {
      const { varId } = active.data.current ?? {}
      if (varId) addVariable(varId)
    }
    // Workspace → workspace reorder
    else if (workspaceVarIds.includes(active.id) && workspaceVarIds.includes(over.id)) {
      reorderVariable(active.id, over.id)
    }
    setActiveVarId(null)
  }

  async function handleExportOdt() {
    const data = buildExportData(workspaceVarIds, userValues, solved, unitSelections, getUnit, sciNotation)
    const blob = await generateOdt(data)
    downloadBlob(blob, 'rocketry-workspace.odt')
  }

  function handleExportJSON() {
    const data = buildExportData(workspaceVarIds, userValues, solved, unitSelections, getUnit, sciNotation)
    const blob = exportJSON(data, workspaceVarIds, userValues, unitSelections)
    downloadBlob(blob, 'rocketry-workspace.json')
  }

  function handleImportJSON(jsonString) {
    try {
      const workspace = parseImport(jsonString)
      importWorkspace(workspace)
    } catch (err) {
      alert(`Import failed: ${err.message}`)
    }
  }

  return (
    <DndContext sensors={sensors} onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
      <div className="flex flex-1 min-h-0 overflow-hidden flex-col">
        {/* Solver sub-header */}
        <div className="flex items-center gap-2 px-5 py-2 border-b border-slate-700 bg-slate-900 shrink-0">
          <p className="text-xs text-slate-400">
            Add variables, enter known values, and unknowns solve automatically.
          </p>
          <div className="ml-auto flex items-center gap-2">
            <button
              onClick={toggleSciNotation}
              title="Toggle scientific notation"
              className={`flex items-center gap-1.5 px-3 py-2 rounded-lg border text-sm font-medium transition-colors ${
                sciNotation
                  ? 'bg-blue-700 border-blue-500 text-white'
                  : 'bg-slate-700 border-slate-600 text-slate-300 hover:bg-slate-600 hover:border-slate-500'
              }`}
            >
              10ˣ
            </button>
            <button
              onClick={() => setShowEquations(true)}
              className="flex items-center gap-2 px-4 py-2 rounded-lg bg-slate-700 hover:bg-slate-600 border border-slate-600 hover:border-slate-500 text-sm text-slate-200 font-medium transition-colors"
            >
              <span>∑</span> Equations
            </button>
            <button
              onClick={() => setShowPropellants(true)}
              className="flex items-center gap-2 px-4 py-2 rounded-lg bg-slate-700 hover:bg-slate-600 border border-slate-600 hover:border-slate-500 text-sm text-slate-200 font-medium transition-colors"
            >
              <span>⛽</span> Propellants
            </button>
          </div>
        </div>

        {/* Three-panel layout */}
        <div className="flex flex-1 min-h-0 overflow-hidden">
          <VariablePalette
            workspaceVarIds={workspaceVarIds}
            onAddVariable={addVariable}
          />
          <Workspace
            workspaceVarIds={workspaceVarIds}
            userValues={userValues}
            solved={solved}
            onRemove={removeVariable}
            onValueChange={setValue}
            onAddPreset={addPreset}
            onClear={clearWorkspace}
            getUnit={getUnit}
            setUnit={setUnit}
            sciNotation={sciNotation}
            areaRatioBranch={areaRatioBranch}
            onToggleAreaRatioBranch={toggleAreaRatioBranch}
          />
          <ResultsPanel
            workspaceVarIds={workspaceVarIds}
            userValues={userValues}
            solved={solved}
            missingReport={missingReport}
            getUnit={getUnit}
            sciNotation={sciNotation}
            onExportOdt={handleExportOdt}
            onExportJSON={handleExportJSON}
            onImportJSON={handleImportJSON}
          />
        </div>
      </div>

      {showPropellants && (
        <PropellantModal
          onClose={() => setShowPropellants(false)}
          onApply={applyPropellant}
        />
      )}

      {showEquations && (
        <EquationBrowser
          equations={EQUATIONS}
          allKnown={allKnown}
          workspaceVarIds={workspaceVarIds}
          onAddVariables={varIds => addVariables(varIds)}
          onClose={() => setShowEquations(false)}
        />
      )}

      <DragOverlay dropAnimation={null}>
        {activeVarId ? (
          <div className="opacity-90 rotate-2 scale-105">
            <PaletteCard varId={activeVarId} isInWorkspace={false} />
          </div>
        ) : null}
      </DragOverlay>
    </DndContext>
  )
}
