"use client";
import { useMemo, useState } from "react";
import "./genset-solver.css";

type Load = {
  id: string;
  name: string;
  kw: number;
  demand: number;
  start: number;
  priority: number;
};
const ratings = [
  100, 150, 200, 250, 300, 350, 400, 500, 625, 750, 800, 1000, 1250, 1500, 1750,
  2000, 2500,
];
const f = (v: number, d = 2) =>
  new Intl.NumberFormat("id-ID", { maximumFractionDigits: d }).format(
    Number.isFinite(v) ? v : 0,
  );
const initial: Load[] = [
  { id: "EL-01", name: "Fire pump", kw: 75, demand: 1, start: 6, priority: 1 },
  {
    id: "EL-02",
    name: "Lift emergency",
    kw: 45,
    demand: 1,
    start: 2.5,
    priority: 1,
  },
  {
    id: "EL-03",
    name: "Smoke control fan",
    kw: 55,
    demand: 1,
    start: 6,
    priority: 1,
  },
  {
    id: "EL-04",
    name: "Emergency lighting",
    kw: 38,
    demand: 1,
    start: 1,
    priority: 1,
  },
  {
    id: "EL-05",
    name: "IT/Communication",
    kw: 42,
    demand: 0.9,
    start: 1.2,
    priority: 2,
  },
  {
    id: "EL-06",
    name: "Essential AC",
    kw: 90,
    demand: 0.7,
    start: 3,
    priority: 3,
  },
];
export default function GensetSolver() {
  const [loads, setLoads] = useState(initial);
  const [d, setD] = useState({
    pf: 0.8,
    reserve: 20,
    units: 2,
    standby: 1,
    maxDip: 15,
    voltage: 400,
    autonomy: 8,
    fuelRate: 0.24,
    heatReject: 0.28,
    airDT: 10,
    louverVelocity: 3,
    exhaustVelocity: 35,
    noiseTarget: 65,
    roomLength: 9,
    roomWidth: 6,
    maintenanceClearance: 1.2,
  });
  const r = useMemo(() => {
    const rows = loads.map((x) => ({
        ...x,
        run: x.kw * x.demand,
        startKw: x.kw * x.start,
      })),
      running = rows.reduce((a, x) => a + x.run, 0),
      largest = rows.reduce((a, x) => (x.startKw > a.startKw ? x : a), rows[0]),
      baseKva = running / d.pf,
      transient =
        ((running - largest.run + largest.startKw) / d.pf) * (15 / d.maxDip),
      design = Math.max(baseKva, transient) * (1 + d.reserve / 100),
      duty = Math.max(1, d.units - d.standby),
      perUnit = design / duty,
      rating =
        ratings.find((x) => x >= perUnit) || Math.ceil(perUnit / 100) * 100,
      installed = rating * d.units,
      loadPct = (baseKva / (rating * duty)) * 100,
      ats =
        ratings.find(
          (x) => x >= running / ((Math.sqrt(3) * d.voltage) / 1000),
        ) ||
        Math.ceil(running / ((Math.sqrt(3) * d.voltage) / 1000) / 100) * 100,
      fuelHour = rating * duty * d.pf * d.fuelRate,
      tank = fuelHour * d.autonomy * 1.1,
      heat = rating * duty * d.pf * d.heatReject,
      air = heat / (1.2 * 1.006 * d.airDT),
      louver = air / d.louverVelocity,
      exhaustD =
        Math.sqrt(
          (4 * (rating * duty * 0.002)) / (Math.PI * d.exhaustVelocity),
        ) * 1000,
      room = d.roomLength * d.roomWidth,
      requiredRoom = d.units * ((rating / 500) * 8 + 6),
      pass =
        rating >= perUnit &&
        loadPct >= 30 &&
        loadPct <= 85 &&
        d.standby >= 1 &&
        d.reserve >= 15 &&
        room >= requiredRoom &&
        d.noiseTarget <= 70;
    return {
      rows,
      running,
      largest,
      baseKva,
      transient,
      design,
      duty,
      perUnit,
      rating,
      installed,
      loadPct,
      ats,
      fuelHour,
      tank,
      heat,
      air,
      louver,
      exhaustD,
      room,
      requiredRoom,
      pass,
    };
  }, [loads, d]);
  const edit = (i: number, k: keyof Load, v: string) =>
    setLoads(
      loads.map((x, j) =>
        j === i ? { ...x, [k]: k === "name" || k === "id" ? v : +v } : x,
      ),
    );
  return (
    <section className="genSolver">
      <header>
        <div>
          <small>EMERGENCY POWER ENGINE v4.3</small>
          <h2>Genset & Emergency Power Designer</h2>
          <p>
            Load schedule, step-load, rating, ATS/AMF, fuel, ventilasi, exhaust,
            ruang dan BOQ.
          </p>
        </div>
        <b className={r.pass ? "pass" : "hold"}>{r.pass ? "PASS" : "HOLD"}</b>
      </header>
      <div className="genInputs">
        {Object.entries({
          pf: "Power factor",
          reserve: "Reserve %",
          units: "Unit terpasang",
          standby: "Unit standby",
          maxDip: "Max voltage dip %",
          voltage: "Tegangan V",
          autonomy: "Fuel autonomy jam",
          fuelRate: "Fuel L/kWh",
          heatReject: "Heat rejection",
          airDT: "ΔT ruang K",
          louverVelocity: "Louver velocity m/s",
          exhaustVelocity: "Exhaust velocity m/s",
          noiseTarget: "Noise target dBA",
          roomLength: "Panjang ruang m",
          roomWidth: "Lebar ruang m",
          maintenanceClearance: "Clearance m",
        }).map(([k, l]) => (
          <label key={k}>
            {l}
            <input
              type="number"
              step="any"
              value={d[k as keyof typeof d]}
              onChange={(e) => setD({ ...d, [k]: +e.target.value })}
            />
          </label>
        ))}
      </div>
      <h3>Emergency load & starting schedule</h3>
      <div className="genTable">
        <table>
          <thead>
            <tr>
              <th>ID</th>
              <th>Beban</th>
              <th>kW</th>
              <th>Demand</th>
              <th>Start ×</th>
              <th>Priority</th>
              <th>Running</th>
              <th>Starting</th>
            </tr>
          </thead>
          <tbody>
            {r.rows.map((x, i) => (
              <tr key={x.id}>
                <td>{x.id}</td>
                <td>
                  <input
                    value={x.name}
                    onChange={(e) => edit(i, "name", e.target.value)}
                  />
                </td>
                {(["kw", "demand", "start", "priority"] as const).map((k) => (
                  <td key={k}>
                    <input
                      type="number"
                      value={x[k]}
                      onChange={(e) => edit(i, k, e.target.value)}
                    />
                  </td>
                ))}
                <td>{f(x.run)} kW</td>
                <td>{f(x.startKw)} kW</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      <button
        className="genAdd"
        onClick={() =>
          setLoads([
            ...loads,
            {
              id: `EL-${String(loads.length + 1).padStart(2, "0")}`,
              name: "Beban baru",
              kw: 20,
              demand: 1,
              start: 1,
              priority: 3,
            },
          ])
        }
      >
        + Tambah beban
      </button>
      <div className="genKpi">
        {[
          ["Running load", `${f(r.running)} kW`],
          ["Base capacity", `${f(r.baseKva)} kVA`],
          ["Transient capacity", `${f(r.transient)} kVA`],
          ["Selected rating", `${r.units} × ${r.rating} kVA`],
          ["Duty loading", `${f(r.loadPct)}%`],
          ["ATS rating", `${r.ats} A`],
          ["Fuel tank", `${f(r.tank)} L`],
          ["Ventilation", `${f(r.air)} m³/s`],
        ].map((x) => (
          <article key={x[0]}>
            <small>{x[0]}</small>
            <b>{x[1]}</b>
          </article>
        ))}
      </div>
      <div className="genGrid">
        <article>
          <h3>Engineering gate</h3>
          {[
            [r.rating >= r.perUnit, "Rating ≥ design per unit"],
            [r.loadPct >= 30 && r.loadPct <= 85, "Duty loading 30–85%"],
            [d.standby >= 1, "N+1 standby tersedia"],
            [d.reserve >= 15, "Reserve minimum 15%"],
            [r.room >= r.requiredRoom, "Ruang dan maintenance access cukup"],
            [d.noiseTarget <= 70, "Target noise façade/ruang ditetapkan"],
          ].map((x, i) => (
            <p key={i}>
              <b className={x[0] ? "pass" : "hold"}>{x[0] ? "PASS" : "HOLD"}</b>
              <span>{x[1]}</span>
            </p>
          ))}
        </article>
        <article>
          <h3>Room, fuel & exhaust schedule</h3>
          <table>
            <tbody>
              {[
                ["Room available", r.room, "m²"],
                ["Room screening", r.requiredRoom, "m²"],
                ["Heat rejection", r.heat, "kW"],
                ["Louver free area", r.louver, "m²"],
                ["Exhaust diameter", r.exhaustD, "mm"],
                ["Fuel/hour", r.fuelHour, "L/h"],
                ["Fuel autonomy", d.autonomy, "jam"],
                ["Noise target", d.noiseTarget, "dBA"],
              ].map((x) => (
                <tr key={x[0]}>
                  <th>{x[0]}</th>
                  <td>
                    {f(+x[1])} {x[2]}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </article>
      </div>
      <div className="genDiagram">
        {[
          "PLN / Normal",
          `ATS ${r.ats} A`,
          `AMF & synchronizing`,
          `${r.units} × ${r.rating} kVA`,
          `Emergency MDB`,
          `Priority load groups`,
        ].map((x, i) => (
          <span key={x}>
            <b>{String(i + 1).padStart(2, "0")}</b>
            {x}
          </span>
        ))}
      </div>
      <div className="genGrid">
        <article>
          <h3>BOQ otomatis</h3>
          <table>
            <tbody>
              {[
                ["Diesel generator", d.units, "unit"],
                ["ATS/AMF panel", 1, "set"],
                [
                  "Synchronizing/load-sharing panel",
                  d.units > 1 ? 1 : 0,
                  "set",
                ],
                ["Bulk/day fuel tank", r.tank, "L"],
                ["Supply/discharge louver", r.louver * 2, "m² free area"],
                ["Exhaust system", d.units, "set"],
                ["Starting batteries", d.units * 2, "unit"],
                ["Load bank connection", 1, "set"],
              ].map((x) => (
                <tr key={x[0]}>
                  <th>{x[0]}</th>
                  <td>
                    {f(+x[1])} {x[2]}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </article>
        <article>
          <h3>Control narrative & specification</h3>
          <ol>
            <li>PLN gagal → AMF memulai unit duty secara berurutan.</li>
            <li>Genset stabil → ATS transfer emergency bus.</li>
            <li>
              Beban priority 1 masuk lebih dahulu; priority 2–3 mengikuti
              step-load.
            </li>
            <li>
              Overload/under-frequency → load shedding prioritas terendah.
            </li>
            <li>
              PLN stabil kembali → retransfer, cooldown, stop dan reset standby.
            </li>
          </ol>
          <p>
            Rating final, voltage dip, harmonics, ambient derating, altitude,
            exhaust back-pressure, emisi dan fuel consumption wajib memakai
            certified generator-set selection.
          </p>
        </article>
      </div>
    </section>
  );
}
