/*
 * Copyright (c) 2021 The ZMK Contributors
 *
 * SPDX-License-Identifier: MIT
 */

import { useState } from "react";
import classnames from "classnames";
import Layout from "@theme/Layout";
import styles from "./styles.module.css";
import PowerEstimate from "../components/power-estimate";
import CustomBoardForm from "../components/custom-board-form";
import { useInput } from "../utils/hooks";
import { zmkBoards, backlightLEDs } from "../data/power";
import "../css/power-profiler.css";

const Disclaimer = `This profiler makes many assumptions about typing
              activity, battery characteristics, hardware behavior, and
              doesn't account for error of user inputs. For example battery
              mAh, which is often incorrectly advertised higher than it's actual capacity.
              While it tries to estimate power usage using real power readings of ZMK,
              every person will have different results that may be worse or even
              better than the estimation given here.`;

function PowerProfiler() {
  const { value: board, bind: bindBoard } = useInput("");
  const { value: split, bind: bindSplit } = useInput(false);
  const { value: batteryMilliAh, bind: bindBatteryMilliAh } = useInput(110);

  const { value: psuType, bind: bindPsuType } = useInput("");
  const { value: outputV, bind: bindOutputV } = useInput(3.3);
  const { value: quiescentMicroA, bind: bindQuiescentMicroA } = useInput(55);
  const { value: otherQuiescentMicroA, bind: bindOtherQuiescentMicroA } =
    useInput(0);
  const { value: efficiency, bind: bindEfficiency } = useInput(0.9);

  const { value: bondedQty, bind: bindBondedQty } = useInput(1);
  const { value: percentAsleep, bind: bindPercentAsleep } = useInput(0.5);

  const { value: glowEnabled, bind: bindGlowEnabled } = useInput(false);
  const { value: glowQuantity, bind: bindGlowQuantity } = useInput(10);
  const { value: glowBrightness, bind: bindGlowBrightness } = useInput(1);

  const { value: backlightEnabled, bind: bindBacklightEnabled } =
    useInput(false);
  const { value: backlightQuantity, bind: bindBacklightQuantity } =
    useInput(60);
  const { value: backlightColor, bind: bindBacklightColor } = useInput("");
  const { value: backlightVoltage, bind: bindBacklightVoltage } = useInput(2.2);
  const { value: backlightResistance, bind: bindBacklightResistance } =
    useInput(100);
  const { value: backlightBrightness, bind: bindBacklightBrightness } =
    useInput(1);

  const { value: displayEnabled, bind: bindDisplayEnabled } = useInput(false);
  const { value: displayType, bind: bindDisplayType } = useInput("");

  const [disclaimerAcknowledged, setDisclaimerAcknowledged] = useState(
    typeof window !== "undefined"
      ? localStorage.getItem("zmkPowerProfilerDisclaimer") === "true"
      : false
  );

  const currentBoard =
    board === "custom"
      ? {
          powerSupply: {
            type: psuType,
            outputVoltage: outputV,
            quiescentMicroA: quiescentMicroA,
            efficiency,
          },
          otherQuiescentMicroA: otherQuiescentMicroA,
        }
      : zmkBoards[board];

  const currentBacklightVoltage =
    backlightColor === "custom"
      ? backlightVoltage
      : backlightLEDs[backlightColor || "White"];

  return (
    <Layout
      title={`ZMK Power Profiler`}
      description="Estimate your keyboard's power usage and battery life on ZMK."
    >
      <header className={classnames("hero hero--primary", styles.heroBanner)}>
        <div className="container">
          <h1 className="hero__title">ZMK Power Profiler</h1>
          <p className="hero__subtitle">
            {"Estimate your keyboard's power usage and battery life on ZMK."}
          </p>
        </div>
      </header>
      <main>
        <section className="container">
          <div className="profilerSection">
            <h3>Keyboard Specifications</h3>
            <div className="row">
              <div className="col col--4">
                <div className="profilerInput">
                  <label>Board</label>
                  <select {...bindBoard}>
                    <option hidden value="">
                      Select a board
                    </option>
                    {Object.keys(zmkBoards).map((b) => (
                      <option key={b}>{b}</option>
                    ))}
                    <option value="custom">Custom</option>
                  </select>
                </div>
              </div>
              <div className="col col--4">
                <div className="profilerInput">
                  <label>Split Keyboard</label>
                  <input
                    id="split"
                    checked={split}
                    {...bindSplit}
                    className="toggleInput"
                    type="checkbox"
                  />
                  <label htmlFor="split" className="toggle">
                    <div className="toggleThumb" />
                  </label>
                </div>
              </div>
              <div className="col col--4">
                <div className="profilerInput">
                  <label>Battery Size</label>
                  <div className="inputBox">
                    <input {...bindBatteryMilliAh} type="number" />
                    <span>mAh</span>
                  </div>
                </div>
              </div>
            </div>
          </div>

          {board === "custom" && (
            <CustomBoardForm
              bindPsuType={bindPsuType}
              bindOutputV={bindOutputV}
              bindEfficiency={bindEfficiency}
              bindQuiescentMicroA={bindQuiescentMicroA}
              bindOtherQuiescentMicroA={bindOtherQuiescentMicroA}
            />
          )}

          <div className="profilerSection">
            <h3>Usage Values</h3>
            <div className="row">
              <div className="col col--4">
                <div className="profilerInput">
                  <label>
                    Bonded Bluetooth Profiles{" "}
                    <span data-tooltip="The average number of host devices connected at once">
                      ⓘ
                    </span>
                  </label>
                  <input {...bindBondedQty} type="range" min="1" max="5" />
                  <span>{bondedQty}</span>
                </div>
              </div>
              <div className="col col--4">
                <div className="profilerInput">
                  <label>
                    Percentage Asleep{" "}
                    <span data-tooltip="How much time the keyboard is in deep sleep (15 min. default timeout)">
                      ⓘ
                    </span>
                  </label>
                  <input
                    {...bindPercentAsleep}
                    type="range"
                    min="0"
                    step=".1"
                    max="1"
                  />
                  <span>{Math.round(percentAsleep * 100)}%</span>
                </div>
              </div>
            </div>
          </div>

          <div className="profilerSection">
            <h3>Features</h3>
            <div className="row">
              <div className="col col--4">
                <div className="profilerInput">
                  <label>RGB Underglow</label>
                  <input
                    checked={glowEnabled}
                    id="glow"
                    {...bindGlowEnabled}
                    className="toggleInput"
                    type="checkbox"
                  />
                  <label htmlFor="glow" className="toggle">
                    <div className="toggleThumb" />
                  </label>
                </div>
                {glowEnabled && (
                  <>
                    <div className="profilerInput">
                      <label>LED Quantity</label>
                      <div className="inputBox">
                        <input {...bindGlowQuantity} type="number" />
                      </div>
                    </div>
                    <div className="profilerInput">
                      <label>Brightness</label>
                      <input
                        {...bindGlowBrightness}
                        type="range"
                        min="0"
                        step=".01"
                        max="1"
                      />
                      <span>{Math.round(glowBrightness * 100)}%</span>
                    </div>
                  </>
                )}
              </div>
              <div className="col col--4">
                <div className="profilerInput">
                  <label>Backlight</label>
                  <input
                    checked={backlightEnabled}
                    id="backlight"
                    {...bindBacklightEnabled}
                    className="toggleInput"
                    type="checkbox"
                  />
                  <label htmlFor="backlight" className="toggle">
                    <div className="toggleThumb" />
                  </label>
                </div>
                {backlightEnabled && (
                  <>
                    <div className="profilerInput">
                      <label>LED Quantity</label>
                      <div className="inputBox">
                        <input {...bindBacklightQuantity} type="number" />
                      </div>
                    </div>
                    <div className="profilerInput">
                      <label>LED Forward Voltage</label>
                      <select {...bindBacklightColor}>
                        {Object.entries(backlightLEDs).map(([c, v]) => (
                          <option key={c} value={c}>
                            {c} ({v.toFixed(1)} V)
                          </option>
                        ))}
                        <option value="custom">Custom</option>
                      </select>
                      {backlightColor === "custom" && (
                        <div className="profilerInput">
                          <div className="inputBox">
                            <input {...bindBacklightVoltage} type="number" />
                            <span>V</span>
                          </div>
                        </div>
                      )}
                    </div>
                    <div className="profilerInput">
                      <label>LED Resistance</label>
                      <div className="inputBox">
                        <input {...bindBacklightResistance} type="number" />
                        <span>ohm</span>
                      </div>
                    </div>
                    <div className="profilerInput">
                      <label>Brightness</label>
                      <input
                        {...bindBacklightBrightness}
                        type="range"
                        min="0"
                        step=".01"
                        max="1"
                      />
                      <span>{Math.round(backlightBrightness * 100)}%</span>
                    </div>
                  </>
                )}
              </div>
              <div className="col col--4">
                <div className="profilerInput">
                  <label>Display</label>
                  <input
                    checked={displayEnabled}
                    id="display"
                    {...bindDisplayEnabled}
                    className="toggleInput"
                    type="checkbox"
                  />
                  <label htmlFor="display" className="toggle">
                    <div className="toggleThumb" />
                  </label>
                </div>
                {displayEnabled && (
                  <div className="profilerInput">
                    <label>Display Type</label>
                    <select {...bindDisplayType}>
                      <option hidden selected>
                        Select type
                      </option>
                      <option value="EPAPER">ePaper</option>
                      <option value="OLED">OLED</option>
                      <option value="NICEVIEW">nice!view</option>
                    </select>
                  </div>
                )}
              </div>
            </div>
          </div>
          {split ? (
            <>
              <PowerEstimate
                board={currentBoard}
                splitType="central"
                batteryMilliAh={batteryMilliAh}
                usage={{ bondedQty, percentAsleep }}
                underglow={{ glowEnabled, glowBrightness, glowQuantity }}
                backlight={{
                  backlightEnabled,
                  backlightVoltage: currentBacklightVoltage,
                  backlightResistance,
                  backlightBrightness,
                  backlightQuantity,
                }}
                display={{ displayEnabled, displayType }}
              />
              <PowerEstimate
                board={currentBoard}
                splitType="peripheral"
                batteryMilliAh={batteryMilliAh}
                usage={{ bondedQty, percentAsleep }}
                underglow={{ glowEnabled, glowBrightness, glowQuantity }}
                backlight={{
                  backlightEnabled,
                  backlightVoltage: currentBacklightVoltage,
                  backlightResistance,
                  backlightBrightness,
                  backlightQuantity,
                }}
                display={{ displayEnabled, displayType }}
              />
            </>
          ) : (
            <PowerEstimate
              board={currentBoard}
              splitType="standalone"
              batteryMilliAh={batteryMilliAh}
              usage={{ bondedQty, percentAsleep }}
              underglow={{ glowEnabled, glowBrightness, glowQuantity }}
              backlight={{
                backlightEnabled,
                backlightVoltage: currentBacklightVoltage,
                backlightResistance,
                backlightBrightness,
                backlightQuantity,
              }}
              display={{ displayEnabled, displayType }}
            />
          )}
          <div className="row">
            <div className="col col--8 col--offset-2 profilerDisclaimer">
              Disclaimer: {Disclaimer}
            </div>
          </div>
        </section>
      </main>
      {!disclaimerAcknowledged && (
        <div className="disclaimerHolder">
          <div className="disclaimer">
            <h3>Disclaimer</h3>
            <p>{Disclaimer}</p>
            <button
              onClick={() => {
                setDisclaimerAcknowledged(true);
                localStorage.setItem("zmkPowerProfilerDisclaimer", true);
              }}
            >
              I Understand
            </button>
          </div>
        </div>
      )}
    </Layout>
  );
}

export default PowerProfiler;
