import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
import { createRoot } from 'react-dom/client';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { Play, RotateCcw, Lightbulb, Sun, Cpu, Check, LockKeyhole, Volume2, Settings, Cable, X } from 'lucide-react';
import './styles.css';
import brandLogo from '../logo-be-tech.png';

const levels = [
  ['Primer destello', 'Sensor de luz'], ['A tu paso', 'Movimiento'], ['Clima ideal', 'Temperatura'],
  ['Dos condiciones', 'Operador Y'], ['Una u otra', 'Operador O'], ['Modo nocturno', 'Reloj'],
  ['Luz gradual', 'PWM'], ['Alerta en casa', 'Zumbador'], ['Puerta inteligente', 'Servo'],
  ['Zona segura', 'Distancia'], ['Aire limpio', 'Sensor de gas'], ['Riego preciso', 'Humedad'],
  ['Escena cine', 'Múltiples salidas'], ['Ahorro total', 'Consumo'], ['Casa conectada', 'MQTT'],
  ['El gran sistema', 'Desafío final']
];

const levelConfigs = [
  ['Primer destello','Sensor de luz','Encendé la luz cuando oscurezca.','Activá la lámpara cuando el sensor detecte menos de 50 lux.','Sensor de luz','lx',0,100,32,50,v=>v<50,'Menor que 50','Encender luz','LÁMPARA','Noche','Día'],
  ['A tu paso','Movimiento','Iluminá el pasillo cuando alguien pase.','Detectá movimiento y encendé la luz del pasillo.','Sensor PIR','%',0,100,75,50,v=>v>=50,'Movimiento ≥ 50','Luz de pasillo','PASILLO','Vacío','Movimiento'],
  ['Clima ideal','Temperatura','Refrescá la casa cuando haga calor.','Encendé el ventilador si la temperatura supera 26 °C.','Temperatura','°C',10,40,30,26,v=>v>26,'Mayor que 26','Ventilador','VENTILADOR','Frío','Calor'],
  ['Dos condiciones','Operador Y','Activá el aire sólo si hace falta.','Combiná presencia y temperatura alta con el operador Y.','Presencia + calor','%',0,100,80,65,v=>v>=65,'Presencia Y calor','Aire acondicionado','AIRE','Una condición','Ambas'],
  ['Una u otra','Operador O','Detectá cualquier acceso.','Dispará el aviso si se abre la puerta o una ventana.','Puerta o ventana','%',0,100,70,50,v=>v>=50,'Puerta O ventana','Enviar aviso','AVISO','Cerradas','Acceso abierto'],
  ['Modo nocturno','Reloj','Prepará la casa para la noche.','Activá el modo nocturno después de las 22 horas.','Reloj','h',0,23,23,22,v=>v>=22||v<6,'Después de las 22','Modo nocturno','MODO NOCHE','00 h','23 h'],
  ['Luz gradual','PWM','Regulá la luz sin saltos.','Usá PWM para lograr una intensidad superior al 60%.','Intensidad PWM','%',0,100,70,60,v=>v>=60,'Intensidad ≥ 60','Regular lámpara','DIMMER','Apagada','Máxima'],
  ['Alerta en casa','Zumbador','Hacé sonar una alerta inmediata.','Activá el zumbador cuando el nivel de riesgo sea alto.','Nivel de riesgo','%',0,100,82,70,v=>v>=70,'Riesgo ≥ 70','Activar zumbador','ZUMBADOR','Seguro','Alerta'],
  ['Puerta inteligente','Servo','Abrí la puerta con autorización.','Mové el servo cuando la validación supere el 80%.','Autorización','%',0,100,90,80,v=>v>=80,'Acceso ≥ 80','Girar servo','PUERTA','Denegado','Autorizado'],
  ['Zona segura','Distancia','Protegé el perímetro de la casa.','Activá la alerta cuando algo se acerque a menos de 30 cm.','Distancia','cm',0,100,20,30,v=>v<30,'Menor que 30','Alerta perimetral','PERÍMETRO','Cerca','Lejos'],
  ['Aire limpio','Sensor de gas','Ventilá ante una fuga de gas.','Encendé el extractor si el gas supera 40 ppm.','Sensor de gas','ppm',0,100,55,40,v=>v>40,'Mayor que 40','Encender extractor','EXTRACTOR','Limpio','Gas'],
  ['Riego preciso','Humedad','Regá sólo cuando la tierra esté seca.','Activá la bomba si la humedad baja del 35%.','Humedad de suelo','%',0,100,25,35,v=>v<35,'Menor que 35','Activar bomba','RIEGO','Seca','Húmeda'],
  ['Escena cine','Múltiples salidas','Creá una escena de cine.','Bajá la luz y cerrá las cortinas con una sola regla.','Nivel de escena','%',0,100,85,75,v=>v>=75,'Escena ≥ 75','Luz + cortinas','ESCENA CINE','Normal','Cine'],
  ['Ahorro total','Consumo','Reducí el consumo innecesario.','Cortá cargas cuando el consumo supere 3 kW.','Consumo','kW',0,5,4,3,v=>v>3,'Mayor que 3','Cortar cargas','AHORRO','0 kW','5 kW'],
  ['Casa conectada','MQTT','Publicá el estado de la casa.','Enviá los datos cuando la calidad de conexión sea suficiente.','Señal MQTT','%',0,100,88,70,v=>v>=70,'Señal ≥ 70','Publicar estado','MQTT','Sin señal','Conectada'],
  ['El gran sistema','Desafío final','Poné en marcha toda la casa.','Superá la validación final integrando sensores, reglas y actuadores.','Estado del sistema','%',0,100,95,90,v=>v>=90,'Sistema ≥ 90','Activar casa','CASA INTELIGENTE','Incompleto','Óptimo']
].map(([title,topic,mission,detail,sensor,unit,min,max,start,target,test,condition,action,output,low,high])=>({title,topic,mission,detail,sensor,unit,min,max,start,target,test,condition,action,output,low,high}));

function House3D({ lightOn, lux, connected }) {
  const mount = useRef(null);
  useEffect(() => {
    const el = mount.current;
    const scene = new THREE.Scene();
    scene.background = new THREE.Color('#e8f1eb');
    const camera = new THREE.PerspectiveCamera(35, el.clientWidth / el.clientHeight, .1, 100);
    camera.position.set(7, 6, 8);
    const renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
    renderer.setSize(el.clientWidth, el.clientHeight);
    renderer.shadowMap.enabled = true;
    el.appendChild(renderer.domElement);
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true; controls.enablePan = false;
    controls.minDistance = 7; controls.maxDistance = 16;
    controls.target.set(0, .8, 0);

    scene.add(new THREE.HemisphereLight(0xf4fbff, 0x9ea28d, lux < 50 ? 1.2 : 2));
    const sun = new THREE.DirectionalLight(0xffffff, 2);
    sun.position.set(4, 8, 5); sun.castShadow = true; scene.add(sun);
    const floor = new THREE.Mesh(new THREE.BoxGeometry(7, .25, 5), new THREE.MeshStandardMaterial({color:0xd8d3c7}));
    floor.receiveShadow = true; scene.add(floor);
    const wallMat = new THREE.MeshStandardMaterial({color:0xf7f3e8});
    const back = new THREE.Mesh(new THREE.BoxGeometry(7, 3.4, .15), wallMat); back.position.set(0,1.8,-2.4); scene.add(back);
    const side = new THREE.Mesh(new THREE.BoxGeometry(.15,3.4,5), wallMat); side.position.set(-3.4,1.8,0); scene.add(side);
    const rug = new THREE.Mesh(new THREE.BoxGeometry(3.8,.03,2.5), new THREE.MeshStandardMaterial({color:0x839d8e}));
    rug.position.set(.4,.16,.25); scene.add(rug);
    const sofa = new THREE.Group();
    const fab = new THREE.MeshStandardMaterial({color:0xd8a578});
    const seat = new THREE.Mesh(new THREE.BoxGeometry(3,.55,1),fab); seat.position.y=.55; sofa.add(seat);
    const backS = new THREE.Mesh(new THREE.BoxGeometry(3,1.1,.28),fab); backS.position.set(0,1,-.4); sofa.add(backS);
    sofa.position.set(.5,.12,-1.5); scene.add(sofa);
    const table = new THREE.Mesh(new THREE.CylinderGeometry(.72,.72,.13,32),new THREE.MeshStandardMaterial({color:0x7a543d}));
    table.position.set(.5,.58,.35); scene.add(table);
    const stem = new THREE.Mesh(new THREE.CylinderGeometry(.08,.14,.85,20),new THREE.MeshStandardMaterial({color:0x333936}));
    stem.position.set(2.4,.62,.6); scene.add(stem);
    const bulbMat = new THREE.MeshStandardMaterial({color: lightOn?0xffe28c:0xd5d3c9, emissive:lightOn?0xffb52e:0x000000, emissiveIntensity:lightOn?3:0});
    const bulb = new THREE.Mesh(new THREE.SphereGeometry(.25,24,16),bulbMat); bulb.position.set(2.4,1.24,.6); scene.add(bulb);
    const lampLight = new THREE.PointLight(0xffc457, lightOn?18:0, 5); lampLight.position.copy(bulb.position); scene.add(lampLight);
    const shade = new THREE.Mesh(new THREE.CylinderGeometry(.28,.55,.7,32,1,true),new THREE.MeshStandardMaterial({color:0xf0eadb,side:THREE.DoubleSide,transparent:true,opacity:.85}));
    shade.position.set(2.4,1.45,.6); scene.add(shade);
    // Placa controladora y sensor de luminosidad visibles dentro de la casa.
    const board = new THREE.Group();
    const pcb = new THREE.Mesh(new THREE.BoxGeometry(1.25,.12,.78),new THREE.MeshStandardMaterial({color:0x167b73,roughness:.55}));
    pcb.castShadow=true; board.add(pcb);
    const chip = new THREE.Mesh(new THREE.BoxGeometry(.38,.09,.32),new THREE.MeshStandardMaterial({color:0x202522}));
    chip.position.y=.1; board.add(chip);
    for(let i=0;i<8;i++){const pin=new THREE.Mesh(new THREE.BoxGeometry(.055,.08,.055),new THREE.MeshStandardMaterial({color:0xd9b34a,metalness:.7}));pin.position.set(-.48+i*.14,.12,-.28);board.add(pin)}
    const usb = new THREE.Mesh(new THREE.BoxGeometry(.26,.18,.34),new THREE.MeshStandardMaterial({color:0xbfc5c2,metalness:.8}));
    usb.position.set(-.68,.03,0);board.add(usb);
    board.position.set(-1.8,.32,1.35); board.rotation.y=-.12; scene.add(board);
    const sensor = new THREE.Group();
    const sensorPcb=new THREE.Mesh(new THREE.BoxGeometry(.48,.08,.42),new THREE.MeshStandardMaterial({color:0x285e91}));sensor.add(sensorPcb);
    const eye=new THREE.Mesh(new THREE.CylinderGeometry(.11,.11,.1,20),new THREE.MeshStandardMaterial({color:0xe4bf5b,emissive:0x7b5b08,emissiveIntensity:.2}));
    eye.rotation.x=Math.PI/2;eye.position.y=.09;sensor.add(eye);sensor.position.set(-.6,.28,1.38);scene.add(sensor);
    const wireMat=new THREE.LineBasicMaterial({color:connected>=1?0xa8d43a:0x83928a});
    const wirePts=[new THREE.Vector3(-1.25,.34,1.36),new THREE.Vector3(-.95,.26,1.55),new THREE.Vector3(-.72,.3,1.4)];
    scene.add(new THREE.Line(new THREE.BufferGeometry().setFromPoints(wirePts),wireMat));
    const plant = new THREE.Mesh(new THREE.CylinderGeometry(.28,.38,.55,18),new THREE.MeshStandardMaterial({color:0xb56f4f}));
    plant.position.set(-2.5,.45,-1.6); scene.add(plant);
    for(let i=0;i<6;i++){ const leaf=new THREE.Mesh(new THREE.SphereGeometry(.3,16,12),new THREE.MeshStandardMaterial({color:0x4c765d})); leaf.scale.set(.7,1.6,.55); leaf.rotation.z=(i-2.5)*.32; leaf.position.set(-2.5+(i-2.5)*.13,1.05+Math.abs(i-2.5)*.04,-1.6); scene.add(leaf);}
    const grid = new THREE.GridHelper(18,18,0xaabbb1,0xcbd6cf); grid.position.y=-.01; scene.add(grid);
    let raf; const animate=()=>{controls.update(); renderer.render(scene,camera); raf=requestAnimationFrame(animate)}; animate();
    const resize=()=>{camera.aspect=el.clientWidth/el.clientHeight;camera.updateProjectionMatrix();renderer.setSize(el.clientWidth,el.clientHeight)}; window.addEventListener('resize',resize);
    return()=>{cancelAnimationFrame(raf);window.removeEventListener('resize',resize);controls.dispose();renderer.dispose();el.removeChild(renderer.domElement)};
  },[lightOn,lux,connected]);
  return <div className="house3d" ref={mount}><div className="view-tag"><span/> SALÓN · VISTA 3D</div><div className="orbit-tip">Arrastrá para explorar</div></div>
}

function Node({ id, type, title, subtitle, icon, position, active, onPort, selected, inputLive, outputLive, setPortRef, onDragStart }) {
  return <div className={`logic-node ${type} ${selected?'selected':''}`} style={{left:position.x,top:position.y}} onPointerDown={e=>onDragStart(e,id)}>
    {type!=='sensor'&&<button ref={el=>setPortRef(`${id}-in`,el)} aria-label={`Entrada de ${title}`} title="Entrada" className={`port in ${inputLive?'live':''}`} onPointerDown={e=>e.stopPropagation()} onClick={()=>onPort(id,'in')}/>}
    <div className="node-icon">{icon}</div><div><b>{title}</b><small>{subtitle}</small></div>
    {type!=='action'&&<button ref={el=>setPortRef(`${id}-out`,el)} aria-label={`Salida de ${title}`} title="Salida" className={`port out ${active||outputLive?'live':''}`} onPointerDown={e=>e.stopPropagation()} onClick={()=>onPort(id,'out')}/>}
  </div>
}

function App(){
  const [level,setLevel]=useState(()=>Math.min(15,Number(localStorage.getItem('nexo-current-level'))||0));
  const [completed,setCompleted]=useState(()=>Math.min(16,Number(localStorage.getItem('nexo-completed-levels'))||0));
  const config=levelConfigs[level];
  const [lux,setLux]=useState(()=>levelConfigs[Math.min(15,Number(localStorage.getItem('nexo-current-level'))||0)].start), [running,setRunning]=useState(false), [links,setLinks]=useState({sensorCondition:false,conditionAction:false});
  const [pending,setPending]=useState(null);
  const [positions,setPositions]=useState({sensor:{x:42,y:57},condition:{x:283,y:138},action:{x:533,y:222}});
  const [wires,setWires]=useState({});
  const canvasRef=useRef(null), portRefs=useRef({}), dragRef=useRef(null);
  const [toast,setToast]=useState(''), [showLevels,setShowLevels]=useState(false);
  const connected=Number(links.sensorCondition)+Number(links.conditionAction);
  const lightOn=running&&connected>=2&&config.test(lux);
  const resetCircuit=()=>{setLinks({sensorCondition:false,conditionAction:false});setPending(null);setRunning(false)};
  const selectLevel=index=>{
    if(index>completed)return;
    setLevel(index);setLux(levelConfigs[index].start);resetCircuit();setShowLevels(false);
    localStorage.setItem('nexo-current-level',String(index));
  };
  const connect=(id,side)=>{
    if(side==='out'){setPending(id);setToast(`Salida de ${id==='sensor'?'sensor':'condición'} seleccionada. Elegí una entrada.`);return}
    if(id==='condition'&&pending==='sensor'){setLinks(v=>({...v,sensorCondition:true}));setPending(null);setToast('Sensor conectado a la condición.')}
    else if(id==='action'&&pending==='condition'&&links.sensorCondition){setLinks(v=>({...v,conditionAction:true}));setPending(null);setToast('Condición conectada a la lámpara.')}
    else{setToast(id==='action'&&!links.sensorCondition?'Primero conectá el sensor con la condición.':'Elegí primero el conector de salida correcto.')}
    setTimeout(()=>setToast(''),2300);
  };
  const setPortRef=(key,el)=>{if(el)portRefs.current[key]=el};
  const updateWires=()=>{
    const canvas=canvasRef.current;if(!canvas)return;
    const box=canvas.getBoundingClientRect();
    const point=key=>{const el=portRefs.current[key];if(!el)return null;const r=el.getBoundingClientRect();return{x:r.left+r.width/2-box.left,y:r.top+r.height/2-box.top}};
    setWires({a:point('sensor-out'),b:point('condition-in'),c:point('condition-out'),d:point('action-in')});
  };
  useLayoutEffect(()=>{updateWires()},[positions,links]);
  useEffect(()=>{const ro=new ResizeObserver(updateWires);if(canvasRef.current)ro.observe(canvasRef.current);return()=>ro.disconnect()},[]);
  const onDragStart=(e,id)=>{
    if(e.button!==0)return;
    const canvas=canvasRef.current, card=e.currentTarget;if(!canvas)return;
    const c=canvas.getBoundingClientRect(), r=card.getBoundingClientRect();
    dragRef.current={id,dx:e.clientX-r.left,dy:e.clientY-r.top,w:r.width,h:r.height,c};
    card.setPointerCapture(e.pointerId);
  };
  const onDragMove=e=>{
    const d=dragRef.current;if(!d)return;
    const x=Math.max(8,Math.min(d.c.width-d.w-8,e.clientX-d.c.left-d.dx));
    const y=Math.max(28,Math.min(d.c.height-d.h-8,e.clientY-d.c.top-d.dy));
    setPositions(v=>({...v,[d.id]:{x,y}}));
  };
  const onDragEnd=()=>{dragRef.current=null};
  const cable=(a,b)=>{
    if(!a||!b)return'';
    const bend=Math.max(45,Math.abs(b.x-a.x)*.45);
    return`M ${a.x} ${a.y} C ${a.x+bend} ${a.y}, ${b.x-bend} ${b.y}, ${b.x} ${b.y}`;
  };
  const simulate=()=>{setRunning(true);setToast(connected<2?'Todavía falta conectar el circuito.':lux<50?'¡Sistema funcionando! La luz se encendió.':'La regla funciona. Bajá la luz ambiente a menos de 50 lx.');setTimeout(()=>setToast(''),3200)};
  const completeLevel=()=>{
    setRunning(true);
    if(connected<2){setToast('Todavía falta conectar el circuito.');setTimeout(()=>setToast(''),2600);return}
    if(!config.test(lux)){setToast(`Ajustá ${config.sensor.toLowerCase()} para cumplir la condición.`);setTimeout(()=>setToast(''),3000);return}
    const progress=Math.max(completed,level+1);
    setCompleted(progress);localStorage.setItem('nexo-completed-levels',String(progress));
    if(level===15){setToast('¡Completaste los 16 niveles de BeTech!');setTimeout(()=>setToast(''),4000);return}
    setToast(`¡Nivel ${level+1} completado! Pasando al siguiente…`);
    setTimeout(()=>{
      const next=level+1;
      setLevel(next);setLux(levelConfigs[next].start);resetCircuit();
      localStorage.setItem('nexo-current-level',String(next));
      setToast(`Nivel ${next+1}: ${levelConfigs[next].title}`);
      setTimeout(()=>setToast(''),1800);
    },1200);
  };
  return <main>
    <header><div className="brand"><img src={brandLogo} alt="BeTech — Coding for the future"/></div>
      <div className="level-head"><span>NIVEL {String(level+1).padStart(2,'0')}</span><b>{config.title}</b><div className="progress"><i style={{width:`${(level+1)*6.25}%`}}/></div><small>{level+1} / 16</small></div>
      <div className="head-actions"><button className="icon-btn"><Volume2 size={18}/></button><button className="icon-btn"><Settings size={18}/></button><button className="avatar">EA</button></div>
    </header>
    <section className="brief"><div><span className="eyebrow">TU MISIÓN · NIVEL {String(level+1).padStart(2,'0')}</span><h1>{config.mission}</h1><p>{config.detail}</p></div>
      <div className="status"><span className={connected>=2?'done':''}>{connected>=2?<Check/>:<Cable/>} {connected}/2 conexiones</span><button onClick={()=>setShowLevels(true)}>Ver recorrido</button></div>
    </section>
    <section className="workspace">
      <div className="simulation"><House3D lightOn={lightOn} lux={lux} connected={connected}/>
        <div className="sim-controls"><div><span>{config.sensor.toUpperCase()}</span><b><Sun size={17}/>{lux} {config.unit}</b></div><input aria-label={config.sensor} type="range" min={config.min} max={config.max} value={lux} onChange={e=>{setLux(+e.target.value);setRunning(false)}}/><div className="range-labels"><span>{config.low}</span><span>{config.high}</span></div></div>
        <div className={`lamp-state ${lightOn?'on':''}`}><Lightbulb size={19}/><div><small>{config.output}</small><b>{lightOn?'ACTIVO':'INACTIVO'}</b></div></div>
      </div>
      <div className="logic">
        <div className="logic-bar"><div><span>02</span><b>Armá la lógica</b></div><p>Elegí una salida y después la entrada del siguiente bloque.</p><button onClick={resetCircuit}><RotateCcw size={16}/> Reiniciar</button></div>
        <div className="canvas" ref={canvasRef} onPointerMove={onDragMove} onPointerUp={onDragEnd} onPointerCancel={onDragEnd}>
          <svg className="wires">
            {links.sensorCondition&&<path className="wire live" d={cable(wires.a,wires.b)}/>}
            {links.conditionAction&&<path className={`wire live ${lightOn?'powered':''}`} d={cable(wires.c,wires.d)}/>}
          </svg>
          <div className="canvas-label">FLUJO DE AUTOMATIZACIÓN</div>
          <Node id="sensor" type="sensor" title={config.sensor} subtitle={`${lux} ${config.unit} detectados`} icon={<Sun/>} position={positions.sensor} onPort={connect} active={links.sensorCondition} selected={pending==='sensor'} outputLive={links.sensorCondition} setPortRef={setPortRef} onDragStart={onDragStart}/>
          <Node id="condition" type="condition" title={config.condition} subtitle="Condición lógica" icon={<span className="op">{config.test(lux)?'✓':'?'}</span>} position={positions.condition} onPort={connect} selected={pending==='condition'} inputLive={links.sensorCondition} outputLive={links.conditionAction} setPortRef={setPortRef} onDragStart={onDragStart}/>
          <Node id="action" type="action" title={config.action} subtitle={lightOn?'Salida activa':'Salida digital'} icon={<Lightbulb/>} position={positions.action} onPort={connect} active={lightOn} inputLive={links.conditionAction} setPortRef={setPortRef} onDragStart={onDragStart}/>
          <div className="arduino"><Cpu size={18}/><span>ARDUINO UNO</span><i className={running?'pulse':''}/></div>
        </div>
        <div className="runbar"><div><Cpu size={20}/><p><b>Nivel {level+1} listo</b><span>Los datos se simulan en tiempo real</span></p></div><button onClick={completeLevel}><Play size={18} fill="currentColor"/> PROBAR SISTEMA</button></div>
      </div>
    </section>
    {toast&&<div className={`toast ${connected>=2?'success':''}`}><Check size={18}/>{toast}</div>}
    {showLevels&&<div className="modal-wrap" onClick={()=>setShowLevels(false)}><div className="levels-modal" onClick={e=>e.stopPropagation()}><button className="close" onClick={()=>setShowLevels(false)}><X/></button><span className="eyebrow">RUTA DE APRENDIZAJE · {completed}/16 COMPLETADOS</span><h2>16 desafíos. Una casa inteligente.</h2><p>Cada nivel agrega una nueva pieza al sistema.</p><div className="level-grid">{levelConfigs.map((item,i)=><button type="button" disabled={i>completed} onClick={()=>selectLevel(i)} className={`level-card ${i===level?'current':''} ${i<completed?'complete':''}`} key={item.title}><span>{i<completed?<Check/>:i>completed?<LockKeyhole/>:<Play/>}</span><div><small>NIVEL {String(i+1).padStart(2,'0')}</small><b>{item.title}</b><em>{item.topic}</em></div></button>)}</div></div></div>}
  </main>
}
createRoot(document.getElementById('root')).render(<App/>);
