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

type SystemId =
  | "split"
  | "multi"
  | "vrf"
  | "vrv"
  | "central"
  | "airChiller"
  | "waterChiller"
  | "ahu"
  | "fcu"
  | "rtu"
  | "crac";
type Config = {
  id: SystemId;
  name: string;
  family: string;
  cop: number;
  unitTR: number;
  capexTR: number;
  maint: number;
  space: number;
  life: number;
  note: string;
};
const systems: Config[] = [
  {
    id: "split",
    name: "AC Split",
    family: "DX",
    cop: 3.2,
    unitTR: 2.5,
    capexTR: 12500000,
    maint: 0.035,
    space: 0.35,
    life: 10,
    note: "Satu outdoor–satu indoor; cocok ruang kecil dan jam operasi terpisah.",
  },
  {
    id: "multi",
    name: "AC Multi-split",
    family: "DX",
    cop: 3.4,
    unitTR: 6,
    capexTR: 14500000,
    maint: 0.04,
    space: 0.28,
    life: 11,
    note: "Satu outdoor melayani beberapa indoor; periksa panjang dan beda elevasi refrigeran.",
  },
  {
    id: "vrf",
    name: "VRF",
    family: "Variable refrigerant flow",
    cop: 4.1,
    unitTR: 16,
    capexTR: 20500000,
    maint: 0.045,
    space: 0.22,
    life: 15,
    note: "Diversity dan combination ratio wajib memakai batas pabrikan.",
  },
  {
    id: "vrv",
    name: "VRV",
    family: "VRF – product/vendor route",
    cop: 4.25,
    unitTR: 18,
    capexTR: 22000000,
    maint: 0.045,
    space: 0.22,
    life: 15,
    note: "VRV diperlakukan sebagai route produk/vendor; perhitungan tetap kelas VRF.",
  },
  {
    id: "central",
    name: "Central Chilled-water",
    family: "Chilled water",
    cop: 5.4,
    unitTR: 350,
    capexTR: 23500000,
    maint: 0.05,
    space: 0.65,
    life: 22,
    note: "Plant pusat dengan chiller, pump, AHU/FCU dan sistem kontrol.",
  },
  {
    id: "airChiller",
    name: "Air-cooled Chiller",
    family: "Chilled water",
    cop: 3.2,
    unitTR: 180,
    capexTR: 19500000,
    maint: 0.045,
    space: 0.48,
    life: 18,
    note: "Tanpa cooling tower; membutuhkan area outdoor dan clear airflow.",
  },
  {
    id: "waterChiller",
    name: "Water-cooled Chiller",
    family: "Chilled water",
    cop: 6.1,
    unitTR: 500,
    capexTR: 26000000,
    maint: 0.055,
    space: 0.78,
    life: 25,
    note: "Efisiensi tinggi; termasuk condenser-water pump, cooling tower dan water treatment.",
  },
  {
    id: "ahu",
    name: "AHU + Chilled-water",
    family: "Chilled water terminal",
    cop: 5.4,
    unitTR: 45,
    capexTR: 24500000,
    maint: 0.05,
    space: 0.7,
    life: 20,
    note: "Cocok zona besar; membutuhkan duct, shaft, plant dan ruang AHU.",
  },
  {
    id: "fcu",
    name: "FCU + Chilled-water",
    family: "Chilled water terminal",
    cop: 5.2,
    unitTR: 6,
    capexTR: 22500000,
    maint: 0.055,
    space: 0.48,
    life: 18,
    note: "Zonasi fleksibel; perlu fresh-air terpisah, drain dan akses perawatan.",
  },
  {
    id: "rtu",
    name: "Packaged / Rooftop",
    family: "Packaged DX",
    cop: 3.35,
    unitTR: 30,
    capexTR: 17500000,
    maint: 0.04,
    space: 0.42,
    life: 15,
    note: "Unit packaged dengan duct; periksa struktur atap, noise dan weatherproofing.",
  },
  {
    id: "crac",
    name: "Precision AC / CRAC",
    family: "Critical cooling",
    cop: 3.0,
    unitTR: 20,
    capexTR: 32000000,
    maint: 0.06,
    space: 0.5,
    life: 15,
    note: "Untuk ruang kritis; sensible heat ratio, redundancy dan operasi 24/7 wajib.",
  },
];
const idr = (v: number) =>
  new Intl.NumberFormat("id-ID", {
    style: "currency",
    currency: "IDR",
    maximumFractionDigits: 0,
  }).format(v);
const f = (v: number, d = 2) =>
  new Intl.NumberFormat("id-ID", { maximumFractionDigits: d }).format(
    Number.isFinite(v) ? v : 0,
  );
const sat = (t: number) => 0.61078 * Math.exp((17.2694 * t) / (t + 237.3));
const humidity = (t: number, rh: number) =>
  (0.62198 * ((rh / 100) * sat(t))) / (101.325 - (rh / 100) * sat(t));
const enthalpy = (t: number, rh: number) =>
  1.006 * t + humidity(t, rh) * (2501 + 1.86 * t);

export default function ACSolver() {
  const [system, setSystem] = useState<SystemId>("vrf");
  const [d, setD] = useState({
    area: 5200,
    rooms: 42,
    people: 520,
    sensible: 85,
    latent: 18,
    freshAir: 8,
    indoorT: 24,
    indoorRH: 55,
    outdoorT: 34,
    outdoorRH: 70,
    airDT: 10,
    waterDT: 5,
    diversity: 0.85,
    combination: 1.15,
    ductVelocity: 7,
    pipeVelocity: 1.8,
    fanPressure: 650,
    fanEfficiency: 0.65,
    pumpHead: 28,
    pumpEfficiency: 0.72,
    hours: 10,
    days: 300,
    tariff: 1700,
    reserve: 15,
    redundancy: 1,
  });
  const cfg = systems.find((x) => x.id === system)!;
  const calc = useMemo(() => {
    const roomS = (d.area * d.sensible) / 1000,
      roomL = (d.area * d.latent) / 1000,
      peopleS = (d.people * 75) / 1000,
      peopleL = (d.people * 55) / 1000;
    const oa = (d.people * d.freshAir) / 1000,
      hOut = enthalpy(d.outdoorT, d.outdoorRH),
      hIn = enthalpy(d.indoorT, d.indoorRH),
      freshLoad = Math.max(0, 1.2 * oa * (hOut - hIn));
    const block = (roomS + roomL + peopleS + peopleL + freshLoad) * d.diversity,
      total = block * (1 + d.reserve / 100),
      tr = total / 3.517;
    const chilled = [
        "central",
        "airChiller",
        "waterChiller",
        "ahu",
        "fcu",
      ].includes(system),
      ducted = ["central", "ahu", "rtu", "crac"].includes(system);
    const airflow = Math.max(0, (roomS + peopleS) / (1.2 * 1.006 * d.airDT)),
      waterFlow = chilled ? total / (4.186 * d.waterDT) : 0;
    const ductArea = ducted ? airflow / d.ductVelocity : 0,
      ductEq = ducted ? Math.sqrt((4 * ductArea) / Math.PI) * 1000 : 0,
      pipeD = chilled
        ? Math.sqrt((4 * (waterFlow / 1000)) / (Math.PI * d.pipeVelocity)) *
          1000
        : 0;
    const indoor = Math.max(
        1,
        Math.ceil(d.rooms / (system === "ahu" || system === "rtu" ? 8 : 1)),
      ),
      outdoor = Math.max(1, Math.ceil((tr * d.combination) / cfg.unitTR));
    const fan = (airflow * d.fanPressure) / d.fanEfficiency / 1000,
      pump = chilled
        ? (1000 * 9.81 * (waterFlow / 1000) * d.pumpHead) /
          d.pumpEfficiency /
          1000
        : 0;
    const compressor = total / cfg.cop,
      ct = system === "waterChiller" ? total * 0.035 : 0,
      electrical = compressor + fan + pump + ct,
      annual = electrical * d.hours * d.days,
      cost = annual * d.tariff;
    const capex = tr * cfg.capexTR,
      maintenance = capex * cfg.maint,
      opex = cost + maintenance,
      footprint = tr * cfg.space;
    const comb = tr / (outdoor * cfg.unitTR),
      psych = {
        hOut,
        hIn,
        wOut: humidity(d.outdoorT, d.outdoorRH) * 1000,
        wIn: humidity(d.indoorT, d.indoorRH) * 1000,
      };
    const pass =
      total > 0 &&
      cfg.cop >= 3 &&
      d.diversity > 0 &&
      d.diversity <= 1 &&
      d.reserve >= 10 &&
      airflow > 0 &&
      (!chilled || (waterFlow > 0 && pipeD > 0)) &&
      (!ducted || ductArea > 0) &&
      ((system !== "vrf" && system !== "vrv") ||
        (comb <= 1.3 && d.combination <= 1.3)) &&
      (system !== "crac" || (d.hours >= 20 && d.redundancy >= 1));
    return {
      roomS,
      roomL,
      peopleS,
      peopleL,
      freshLoad,
      total,
      tr,
      airflow,
      waterFlow,
      ductArea,
      ductEq,
      pipeD,
      indoor,
      outdoor,
      fan,
      pump,
      compressor,
      ct,
      electrical,
      annual,
      cost,
      capex,
      maintenance,
      opex,
      footprint,
      comb,
      psych,
      pass,
      chilled,
      ducted,
    };
  }, [d, cfg, system]);
  const compare = systems
    .map((s) => {
      const compressor = calc.total / s.cop,
        extra = [
          "central",
          "airChiller",
          "waterChiller",
          "ahu",
          "fcu",
        ].includes(s.id)
          ? calc.pump
          : 0,
        ct = s.id === "waterChiller" ? calc.total * 0.035 : 0,
        kw = compressor + calc.fan + extra + ct,
        capex = calc.tr * s.capexTR,
        opex = kw * d.hours * d.days * d.tariff + capex * s.maint;
      return {
        ...s,
        kw,
        capex,
        opex,
        score:
          (capex / 1e9) * 0.35 +
          (opex / 1e9) * 0.45 +
          ((s.space * calc.tr) / 100) * 0.1 +
          s.maint * 10 * 0.1,
      };
    })
    .sort((a, b) => a.score - b.score);
  const boq = [
    [
      cfg.family.includes("Chilled")
        ? "Chiller/terminal unit"
        : "Outdoor/condensing unit",
      calc.outdoor,
      "unit",
    ],
    ["Indoor unit / AHU / FCU", calc.indoor, "unit"],
    ["Supply air capacity", calc.airflow, "m³/s"],
    ["Fresh-air capacity", d.people * d.freshAir, "L/s"],
    ...[calc.chilled ? ["Chilled-water flow", calc.waterFlow, "L/s"] : []],
    ...[calc.ducted ? ["Main duct area", calc.ductArea, "m²"] : []],
    ["Electrical connected load", calc.electrical, "kW"],
    [
      "Control/BMS points",
      Math.ceil((calc.indoor + calc.outdoor) * 4),
      "point",
    ],
  ].filter((x) => x.length);
  const checks = [
    calc.total > 0,
    cfg.cop >= 3,
    d.diversity > 0 && d.diversity <= 1,
    d.reserve >= 10,
    calc.freshLoad >= 0,
    !calc.chilled || calc.waterFlow > 0,
    !calc.ducted || calc.ductArea > 0,
    !(["vrf", "vrv"] as SystemId[]).includes(system) || calc.comb <= 1.3,
    system !== "crac" || (d.hours >= 20 && d.redundancy >= 1),
  ];
  return (
    <section className="acSolver">
      <div className="acHead">
        <div>
          <small>BAB AC · SYSTEM SELECTION ENGINE v4.2</small>
          <h2>AC System Designer</h2>
          <p>
            Pilihan sistem mengubah perhitungan, equipment, energi, skema,
            spesifikasi dan BOQ.
          </p>
        </div>
        <b className={calc.pass ? "pass" : "hold"}>
          {calc.pass ? "PASS" : "HOLD"}
        </b>
      </div>
      <div className="acSystems">
        {systems.map((s) => (
          <button
            key={s.id}
            className={system === s.id ? "active" : ""}
            onClick={() => setSystem(s.id)}
          >
            <small>{s.family}</small>
            <b>{s.name}</b>
            <span>
              COP {s.cop} · {s.unitTR} TR/unit
            </span>
          </button>
        ))}
      </div>
      <div className="acBody">
        <aside>
          <h3>Input desain – {cfg.name}</h3>
          {Object.entries({
            area: "Luas terkondisi (m²)",
            rooms: "Jumlah ruang/zona",
            people: "Populasi",
            sensible: "Sensible W/m²",
            latent: "Latent W/m²",
            freshAir: "Fresh air L/s/orang",
            indoorT: "Indoor °C",
            indoorRH: "Indoor RH %",
            outdoorT: "Outdoor °C",
            outdoorRH: "Outdoor RH %",
            airDT: "ΔT udara K",
            waterDT: "ΔT chilled water K",
            diversity: "Diversity",
            combination: "Combination ratio",
            ductVelocity: "Kecepatan duct m/s",
            pipeVelocity: "Kecepatan pipa m/s",
            fanPressure: "Fan static Pa",
            fanEfficiency: "Efisiensi fan",
            pumpHead: "Pump head m",
            pumpEfficiency: "Efisiensi pump",
            hours: "Jam operasi/hari",
            days: "Hari/tahun",
            tariff: "Tarif Rp/kWh",
            reserve: "Reserve %",
            redundancy: "Unit standby",
          }).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>
          ))}
        </aside>
        <main>
          <div className="acKpi">
            {[
              ["Cooling load", `${f(calc.total)} kW`],
              ["Capacity", `${f(calc.tr)} TR`],
              ["Electrical", `${f(calc.electrical)} kW`],
              ["Annual energy", `${f(calc.annual, 0)} kWh`],
              ["Annual OPEX", idr(calc.opex)],
              ["Footprint", `${f(calc.footprint)} m²`],
            ].map((x) => (
              <article key={x[0]}>
                <small>{x[0]}</small>
                <b>{x[1]}</b>
              </article>
            ))}
          </div>
          <div className="acSchedules">
            <article>
              <h3>Cooling-load schedule</h3>
              <table>
                <tbody>
                  {[
                    ["Room sensible", calc.roomS, "kW"],
                    ["Room latent", calc.roomL, "kW"],
                    ["People sensible", calc.peopleS, "kW"],
                    ["People latent", calc.peopleL, "kW"],
                    ["Fresh-air load", calc.freshLoad, "kW"],
                    ["Design + reserve", calc.total, "kW"],
                  ].map((x) => (
                    <tr key={x[0]}>
                      <th>{x[0]}</th>
                      <td>
                        {f(+x[1])} {x[2]}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </article>
            <article>
              <h3>Equipment schedule</h3>
              <table>
                <tbody>
                  {[
                    ["Selected system", cfg.name, ""],
                    ["Indoor/AHU/FCU", calc.indoor, "unit"],
                    ["Outdoor/chiller", calc.outdoor, "unit"],
                    ["Combination ratio", calc.comb, ""],
                    ["Airflow", calc.airflow, "m³/s"],
                    ["Water flow", calc.waterFlow, "L/s"],
                    ["Duct equivalent", calc.ductEq, "mm"],
                    ["Pipe diameter", calc.pipeD, "mm"],
                  ].map((x) => (
                    <tr key={x[0]}>
                      <th>{x[0]}</th>
                      <td>
                        {typeof x[1] === "number" ? f(x[1]) : x[1]} {x[2]}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </article>
          </div>
          <div className="acSchedules">
            <article>
              <h3>Psychrometric & power</h3>
              <table>
                <tbody>
                  {[
                    ["h outdoor", calc.psych.hOut, "kJ/kg"],
                    ["h indoor", calc.psych.hIn, "kJ/kg"],
                    ["W outdoor", calc.psych.wOut, "g/kg"],
                    ["W indoor", calc.psych.wIn, "g/kg"],
                    ["Compressor/chiller", calc.compressor, "kW"],
                    ["Fan", calc.fan, "kW"],
                    ["Pump", calc.pump, "kW"],
                    ["Cooling tower", calc.ct, "kW"],
                  ].map((x) => (
                    <tr key={x[0]}>
                      <th>{x[0]}</th>
                      <td>
                        {f(+x[1])} {x[2]}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </article>
            <article>
              <h3>Gate engineering</h3>
              {checks.map((ok, i) => (
                <p key={i}>
                  <b className={ok ? "pass" : "hold"}>{ok ? "PASS" : "HOLD"}</b>
                  <span>
                    {
                      [
                        "Cooling load positif",
                        "COP minimum terpenuhi",
                        "Diversity valid",
                        "Reserve minimum 10%",
                        "Fresh-air load dihitung",
                        "Chilled-water flow tersedia",
                        "Duct sizing tersedia",
                        "VRF/VRV combination ratio valid",
                        "CRAC 24/7 dan redundancy",
                      ][i]
                    }
                  </span>
                </p>
              ))}
            </article>
          </div>
          <h3>
            Perbandingan sistem – CAPEX, OPEX, efisiensi, ruang & maintenance
          </h3>
          <div className="acTable">
            <table>
              <thead>
                <tr>
                  <th>Rank</th>
                  <th>Sistem</th>
                  <th>COP</th>
                  <th>Daya</th>
                  <th>CAPEX awal</th>
                  <th>OPEX/tahun</th>
                  <th>Ruang</th>
                  <th>Umur</th>
                </tr>
              </thead>
              <tbody>
                {compare.map((s, i) => (
                  <tr className={s.id === system ? "selected" : ""} key={s.id}>
                    <td>{i + 1}</td>
                    <td>
                      <b>{s.name}</b>
                      <small>{s.note}</small>
                    </td>
                    <td>{s.cop}</td>
                    <td>{f(s.kw)} kW</td>
                    <td>{idr(s.capex)}</td>
                    <td>{idr(s.opex)}</td>
                    <td>{f(s.space * calc.tr)} m²</td>
                    <td>{s.life} th</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          <div className="acDiagram">
            {(calc.chilled
              ? [
                  "Cooling plant",
                  cfg.name,
                  "CHW pump",
                  calc.ducted ? "AHU" : "FCU",
                  "Duct/room zones",
                ]
              : [
                  "Outdoor air",
                  cfg.name,
                  "Refrigerant network",
                  "Indoor units",
                  "Room zones",
                ]
            ).map((x, i) => (
              <span key={x}>
                <b>{String(i + 1).padStart(2, "0")}</b>
                {x}
              </span>
            ))}
          </div>
          <div className="acSchedules">
            <article>
              <h3>BOQ otomatis</h3>
              <table>
                <thead>
                  <tr>
                    <th>Item</th>
                    <th>Qty</th>
                    <th>Sat.</th>
                  </tr>
                </thead>
                <tbody>
                  {boq.map((x, i) => (
                    <tr key={i}>
                      <td>{x[0]}</td>
                      <td>{typeof x[1] === "number" ? f(x[1]) : x[1]}</td>
                      <td>{x[2]}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </article>
            <article>
              <h3>Spesifikasi desain</h3>
              <p>{cfg.note}</p>
              <ul>
                <li>
                  Kapasitas minimum {f(calc.tr)} TR termasuk reserve {d.reserve}
                  %.
                </li>
                <li>
                  COP sistem tidak kurang dari {cfg.cop}; data final mengikuti
                  certified selection.
                </li>
                <li>
                  Fresh air {f(d.people * d.freshAir)} L/s dan kondisi
                  psikrometrik wajib diverifikasi.
                </li>
                <li>
                  Kontrol, interlock, BMS points, condensate, insulation, noise
                  dan vibration wajib dikoordinasikan.
                </li>
                <li>
                  Seluruh merek ditulis “atau setara” dan memerlukan technical
                  submittal.
                </li>
              </ul>
            </article>
          </div>
        </main>
      </div>
    </section>
  );
}
