/* global React, Icons, FieldMap, FIELDS, STATUS, FARM_COORDS, L */
const { useState: fState, useEffect: fEffect, useRef: fRef } = React;

const InfoCard = ({ icon: Ico, label, value, left }) => (
  <div className="glass pill hit" style={{ position: "absolute", left, top: 24, width: 176, height: 58, zIndex: 6,
    display: "flex", alignItems: "center", gap: 12, padding: "0 14px" }}>
    <div style={{ width: 38, height: 38, borderRadius: 999, background: "rgba(255,255,255,0.55)",
      display: "flex", alignItems: "center", justifyContent: "center", color: "var(--ink-2)" }}><Ico size={19} /></div>
    <div style={{ lineHeight: 1.15, whiteSpace: "nowrap" }}>
      <div style={{ fontSize: 11.5, color: "var(--muted)", fontWeight: 500 }}>{label}</div>
      <div style={{ fontSize: 17, fontWeight: 700 }}>{value}</div>
    </div>
  </div>
);

const Zoom = ({ icon: Ico, top, primary, onClick }) => (
  <button onClick={onClick} className="round-btn glass hit" style={{ position: "absolute", right: 0, top,
    background: primary ? "var(--lime)" : "var(--glass)", color: "var(--ink)", border: primary ? "none" : undefined }}>
    <Ico size={18} />
  </button>
);

const Stat = ({ icon: Ico, label, value, left }) => (
  <div className="glass hit" style={{ position: "absolute", left, top: 104, width: 284, height: 66, borderRadius: 18, zIndex: 6,
    display: "flex", alignItems: "center", gap: 14, padding: "0 18px" }}>
    <div style={{ width: 40, height: 40, borderRadius: 13, background: "rgba(255,255,255,0.55)",
      display: "flex", alignItems: "center", justifyContent: "center", color: "var(--ink-2)", flex: "none" }}><Ico size={20} /></div>
    <div style={{ lineHeight: 1.1, whiteSpace: "nowrap" }}>
      <div style={{ fontSize: 12.5, color: "var(--muted)", fontWeight: 500 }}>{label}</div>
      <div style={{ fontSize: 22, fontWeight: 700, letterSpacing: "-0.01em" }}>{value}</div>
    </div>
  </div>
);

function LayerChip({ on, label, onClick }) {
  return (
    <button onClick={onClick} className="hit" style={{
      border: "none", cursor: "pointer", fontFamily: "Onest", fontWeight: 600, fontSize: 12,
      padding: "7px 12px", borderRadius: 999,
      background: on ? "var(--lime)" : "rgba(245,245,239,0.82)",
      color: "var(--ink)",
    }}>{label}</button>
  );
}

function IntaCard({ profile, field }) {
  const props = (profile && profile.soil && profile.soil.feature && profile.soil.feature.properties) || {};
  const soil = (profile && profile.weather_soil && profile.weather_soil.soil) || {};
  const sen = (profile && profile.sentinel2 && profile.sentinel2.latest) || {};
  const sm = soil.moisture_0_7cm;
  const loading = profile && profile.loading;
  return (
    <div className="card hit" style={{ position: "absolute", right: 28, top: 184, width: 320, maxHeight: 520, zIndex: 6,
      padding: "18px 18px 16px", overflow: "auto", background: "rgba(245,245,239,0.92)" }}>
      <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: "0.12em", color: "var(--muted)", marginBottom: 6 }}>
        INTA · 1:500.000 · VIVO
      </div>
      <div style={{ fontSize: 18, fontWeight: 800, letterSpacing: "-0.02em" }}>
        {props.orden_sue1 || (loading ? "Consultando…" : "Clic en el mapa")}
      </div>
      <div style={{ fontSize: 12.5, color: "var(--muted)", marginTop: 4 }}>
        {field ? `${field.name} · ${field.crop}` : "Punto en el visor"}
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "108px 1fr", gap: "6px 8px", marginTop: 14, fontSize: 13 }}>
        <span style={{ color: "var(--muted)" }}>Provincia</span><span>{props.provincia || "—"}</span>
        <span style={{ color: "var(--muted)" }}>Subgrupo</span><span>{props.sgrup_sue1 || "—"}</span>
        <span style={{ color: "var(--muted)" }}>Limitación</span><span>{props.limit_ppal || "—"}</span>
        <span style={{ color: "var(--muted)" }}>Índice prod.</span><span>{props.ind_prod == null ? "—" : props.ind_prod}</span>
        <span style={{ color: "var(--muted)" }}>Drenaje</span><span>{props.drenaje_s1 || "—"}</span>
        <span style={{ color: "var(--muted)" }}>Humedad 0–7</span>
        <span>{sm == null ? "—" : `${Number(sm).toFixed(3)} m³/m³`}</span>
        <span style={{ color: "var(--muted)" }}>Sentinel-2</span>
        <span>{sen.datetime ? String(sen.datetime).slice(0, 10) : "—"}</span>
      </div>
      {profile && profile.agronomic_hint && (
        <div style={{ marginTop: 12, fontSize: 12.5, lineHeight: 1.45, background: "rgba(198,232,75,0.18)",
          borderRadius: 12, padding: "10px 12px" }}>{profile.agronomic_hint}</div>
      )}
      <button
        className="btn-lime"
        style={{ marginTop: 14, width: "100%", padding: "10px 12px", borderRadius: 999, fontSize: 13.5 }}
        onClick={() => {
          const name = field ? field.name : "este punto";
          const orden = props.orden_sue1 || "el suelo INTA";
          window.askAI(
            `En ${name} el visor INTA da ${orden}` +
            (props.limit_ppal ? ` con limitación «${props.limit_ppal}»` : "") +
            (sm != null ? ` y humedad 0–7 cm ${Number(sm).toFixed(3)} m³/m³` : "") +
            `. ¿Qué implica para ${field ? field.crop : "el cultivo"}? Cruzá NDVI y no inventes dosis.`
          );
        }}
      >
        Preguntale al Agrónomo
      </button>
      <div style={{ marginTop: 10, fontSize: 11, color: "var(--muted)" }}>
        Mejor que el visor INTA genérico: recorte al lote, humedad de perfil y el chat usa la ficha.
      </div>
    </div>
  );
}

async function overlayVirtualStation() {
  const c = window.FARM_COORDS || { lat: -31.4173, lng: -63.2438 };
  try {
    const r = await fetch(`/api/weather?lat=${c.lat}&lng=${c.lng}`);
    const d = await r.json();
    const cur = d.current || {};
    const st = {
      id: "open-meteo",
      name: "Estación virtual Open-Meteo",
      lat: c.lat,
      lng: c.lng,
      t: cur.temp,
      rh: cur.humidity,
      wind: cur.windspeed,
      source: "Open-Meteo (casco)",
    };
    window.__STATIONS = Object.assign({}, window.__STATIONS, { [st.id]: st });
    if (window.__PAMPA_VISOR) window.__PAMPA_VISOR.addStation(st);
    window.toast("Estación Open-Meteo superpuesta en el casco", "ok");
  } catch (e) {
    window.toast("No pude leer Open-Meteo: " + e.message, "warn");
  }
}

async function pairBleStation() {
  if (!navigator.bluetooth || !navigator.bluetooth.requestDevice) {
    window.toast("Web Bluetooth no está disponible. Uso estación virtual.", "info");
    return overlayVirtualStation();
  }
  try {
    const device = await navigator.bluetooth.requestDevice({
      acceptAllDevices: true,
      optionalServices: [0x181a, 0x180f, 0x1800],
    });
    const server = await device.gatt.connect();
    let t = null;
    let rh = null;
    try {
      const env = await server.getPrimaryService(0x181a);
      try {
        const tc = await env.getCharacteristic(0x2a6e);
        const tv = await tc.readValue();
        t = tv.getInt16(0, true) / 100;
      } catch { /* not all stations expose 0x2A6E */ }
      try {
        const hc = await env.getCharacteristic(0x2a6f);
        const hv = await hc.readValue();
        rh = hv.getUint16(0, true) / 100;
      } catch { /* optional */ }
    } catch {
      window.toast("Conecté " + device.name + " pero no es GATT Environmental Sensing. Superpongo igual en el casco.", "info");
    }
    const c = window.FARM_COORDS || { lat: -31.4173, lng: -63.2438 };
    const st = {
      id: "ble-" + (device.id || device.name || "station"),
      name: device.name || "Estación BLE",
      lat: c.lat,
      lng: c.lng,
      t, rh,
      source: "Bluetooth LE",
    };
    window.__STATIONS = Object.assign({}, window.__STATIONS, { [st.id]: st });
    if (window.__PAMPA_VISOR) window.__PAMPA_VISOR.addStation(st);
    window.toast("Estación BLE: " + st.name, "ok");
  } catch (e) {
    if (e && e.name === "NotFoundError") return;
    window.toast("Bluetooth: " + (e.message || e) + " — pruebo estación virtual.", "warn");
    return overlayVirtualStation();
  }
}

async function importAgFiles(fileList) {
  const conv = window.PampaConvert;
  if (!conv) {
    window.toast("Conversor no cargado", "warn");
    return;
  }
  const files = [];
  for (const file of fileList) {
    const buf = new Uint8Array(await file.arrayBuffer());
    files.push({ name: file.name, data: buf });
  }
  try {
    const out = await conv.convertFiles(files);
    window.__IMPORT_LAYER = out;
    if (window.__PAMPA_VISOR) window.__PAMPA_VISOR.addGeoJSON(out.geojson);
    const ratio = out.geojsonBytes ? Math.round((out.pbfBytes / out.geojsonBytes) * 100) : 0;
    window.toast(
      `Importé ${out.featureCount} features (${out.source}) · GeoJSON ${out.geojsonBytes} B → PBF ${out.pbfBytes} B (${ratio}%)`,
      "ok"
    );
  } catch (e) {
    window.toast("Conversión: " + (e.message || e), "warn");
  }
}

function FieldsTab({ go }) {
  const [selectedId, setSelectedId] = fState("F-01");
  const [showSoils, setShowSoils] = fState(true);
  const [showNdvi, setShowNdvi] = fState(false);
  const [profile, setProfile] = fState(null);
  const fileRef = fRef(null);
  const field = (FIELDS || []).find((f) => f.id === selectedId) || (FIELDS || [])[0];
  const hs = field && STATUS[field.status];

  fEffect(() => {
    if (!field || !field.center) return;
    const [lat, lng] = field.center;
    setProfile({ loading: true, field });
    const qs = new URLSearchParams({ lat, lng, fieldId: field.id, fieldName: field.name });
    fetch(`/api/visor?${qs}`)
      .then((r) => r.json())
      .then((d) => { window.__VISOR_SOIL = d; setProfile(d); })
      .catch((e) => setProfile({ ok: false, error: String(e) }));
  }, [selectedId]);

  const moistureLive = profile && profile.weather_soil && profile.weather_soil.soil
    && profile.weather_soil.soil.moisture_0_7cm;
  const moistureLabel = moistureLive == null
    ? (field ? `${field.moisture} %` : "—")
    : `${Math.round(Number(moistureLive) * 100)} % vol.`;

  return (
    <div style={{ position: "absolute", left: 272, top: 24, width: 1144, height: 892, borderRadius: 28,
      boxShadow: "0 30px 70px -40px rgba(30,40,15,0.6)", overflow: "hidden" }}>
      <FieldMap
        selectedId={selectedId}
        showSoils={showSoils}
        showNdvi={showNdvi}
        onSelect={(id) => setSelectedId(id)}
        onProfile={setProfile}
      />

      <button className="round-btn hit" onClick={() => go("dashboard")} style={{ position: "absolute", left: 28, top: 28,
        background: "var(--cream)", color: "var(--ink)", boxShadow: "var(--shadow-soft)", zIndex: 6 }}>
        <Icons.back size={20} />
      </button>
      <div onClick={() => field && window.openField(field.id)} className="hit" style={{ position: "absolute", left: 84, top: 22, cursor: "pointer", zIndex: 6 }}>
        <div style={{ display: "flex", alignItems: "baseline", gap: 12 }}>
          <span style={{ fontSize: 30, fontWeight: 800, color: "#fff", letterSpacing: "-0.02em",
            textShadow: "0 2px 14px rgba(0,0,0,0.45)", whiteSpace: "nowrap" }}>{field ? field.name : "Lotes"}</span>
          <span style={{ fontSize: 12.5, color: "rgba(255,255,255,0.9)", fontWeight: 500, lineHeight: 1.1,
            textShadow: "0 1px 6px rgba(0,0,0,0.45)" }}>
            {field && field.center
              ? `${Math.abs(field.center[0]).toFixed(3)}°S · ${Math.abs(field.center[1]).toFixed(3)}°O`
              : `${Math.abs(FARM_COORDS.lat).toFixed(3)}°S`}
            {hs ? <><br />{field.crop} · {hs.label}</> : null}
          </span>
        </div>
      </div>

      <InfoCard icon={Icons.flag} label="Visor" value="INTA vivo" left={700} />
      <InfoCard icon={Icons.cloud} label="Ubicación" value="Córdoba" left={888} />

      <div className="hit" style={{ position: "absolute", left: 28, top: 184, display: "flex", gap: 8, zIndex: 6, flexWrap: "wrap", width: 520 }}>
        <LayerChip on={showSoils} label="Suelos INTA" onClick={() => setShowSoils((v) => !v)} />
        <LayerChip on={showNdvi} label="NDVI 8 días" onClick={() => setShowNdvi((v) => !v)} />
        <LayerChip on={false} label="Visión satelital" onClick={() => window.toast("Base Esri World Imagery (más nítida que el visor INTA)", "info")} />
        <LayerChip on={false} label="Importar ISOXML / SHP" onClick={() => fileRef.current && fileRef.current.click()} />
        <LayerChip on={false} label="Estación BLE / meteo" onClick={() => pairBleStation()} />
        <input
          ref={fileRef}
          type="file"
          multiple
          accept=".zip,.xml,.shp,.dbf,.prj,.shx,.geojson,.json"
          style={{ display: "none" }}
          onChange={(e) => {
            const list = e.target.files;
            if (list && list.length) importAgFiles(list);
            e.target.value = "";
          }}
        />
      </div>

      <div className="hit" style={{ position: "absolute", left: 28, top: 228, display: "flex", gap: 6, zIndex: 6, flexWrap: "wrap", width: 640 }}>
        {(FIELDS || []).map((f) => (
          <button key={f.id} onClick={() => setSelectedId(f.id)} className="hit" style={{
            border: "none", cursor: "pointer", fontFamily: "Onest", fontSize: 12, fontWeight: 600,
            padding: "6px 10px", borderRadius: 999,
            background: f.id === selectedId ? "var(--lime)" : "rgba(20,28,10,0.55)",
            color: f.id === selectedId ? "var(--ink)" : "#f2f3ea",
          }}>{f.name}</button>
        ))}
      </div>

      <div style={{ position: "absolute", right: 28, top: 28, width: 40, height: 148, zIndex: 6 }}>
        <Zoom icon={Icons.expand} top={0} onClick={() => {
          const map = window.__PAMPA_MAP;
          if (!map || !field || !field.coordinates) return;
          map.fitBounds(L.latLngBounds(field.coordinates).pad(0.2));
        }} />
        <Zoom icon={Icons.plus} top={54} primary onClick={() => window.__PAMPA_MAP && window.__PAMPA_MAP.zoomIn()} />
        <Zoom icon={Icons.minus} top={108} onClick={() => window.__PAMPA_MAP && window.__PAMPA_MAP.zoomOut()} />
      </div>

      <Stat icon={Icons.sprout} label="Área del lote" value={field ? `${field.area} ha` : "—"} left={28} />
      <Stat icon={Icons.ndvi} label="NDVI lote" value={field ? field.ndvi.toFixed(2) : "—"} left={332} />
      <Stat icon={Icons.drop} label="Humedad" value={moistureLabel} left={636} />

      <IntaCard profile={profile} field={field} />
    </div>
  );
}
window.FieldsTab = FieldsTab;
