import AnimatedModal from "../utils/animated-modal";

import * as TestLogic from "../test/test-logic";
import {
  showNoticeNotification,
  showErrorNotification,
} from "../states/notifications";
import { CompletedEvent } from "@monkeytype/schemas/results";
import { getAuthenticatedUser } from "../firebase";
import { authEvent } from "../events/auth";

function reset(): void {
  modal.getModal().qs(".result")?.setHtml(`
  <div class="group wpm">
        <div class="sub">wpm</div>
        <div class="val">-</div>
      </div>
      <div class="group acc">
        <div class="sub">accuracy</div>
        <div class="val">-</div>
      </div>
      <div class="group raw">
        <div class="sub">raw</div>
        <div class="val">-</div>
      </div>
      <div class="group con">
        <div class="sub">consistency</div>
        <div class="val">-</div>
      </div>
      <div class="group chardata">
        <div class="sub">characters</div>
        <div class="val">-</div>
      </div>
      <div class="group testType">
        <div class="sub">test type</div>
        <div class="val">-</div>
      </div>`);
}

function fillData(): void {
  //safe because we check if it exists before showing the modal
  const r = TestLogic.notSignedInLastResult as CompletedEvent;

  // const r: CompletedEvent = {
  //   wpm: 100,
  //   acc: 100,
  //   rawWpm: 100,
  //   consistency: 100,
  //   mode: "time",
  //   mode2: "60",
  //   numbers: true,
  //   punctuation: true,
  //   difficulty: "master",
  //   language: "english",
  //   blindMode: true,
  //   lazyMode: true,
  //   funbox: "read_ahead",
  //   tags: ["asdf", "sdfsdf"],
  //   charStats: [10, 10, 10, 10],
  // };

  fillGroup("wpm", r.wpm);
  fillGroup("acc", r.acc + "%");
  fillGroup("raw", r.rawWpm);
  fillGroup("con", r.consistency + "%");
  fillGroup("chardata", r.charStats.join("/"));

  let tt = r.mode + " " + r.mode2;

  tt += "<br>" + r.language;

  if (r.numbers) tt += "<br>numbers";
  if (r.punctuation) tt += "<br>punctuation";
  if (r.blindMode) tt += "<br>blind";
  if (r.lazyMode) tt += "<br>lazy";
  if (r.funbox.length > 0) {
    tt += "<br>" + r.funbox.map((it) => it.replace(/_/g, " ")).join(",");
  }
  if (r.difficulty !== "normal") tt += "<br>" + r.difficulty;
  if (r.tags.length > 0) tt += "<br>" + r.tags.length + " tags";

  fillGroup("testType", tt, true);
}

function fillGroup(
  groupClass: string,
  text: string | number,
  html = false,
): void {
  const el = modal.getModal().qs(`.group.${groupClass} .val`);
  if (!el) return;

  if (html) {
    el.setHtml(`${text}`);
  } else {
    el.setText(`${text}`);
  }
}

export function show(): void {
  if (!TestLogic.notSignedInLastResult) {
    showErrorNotification(
      "Failed to show last signed out result modal: no last result",
    );
    return;
  }

  void modal.show({
    beforeAnimation: async (): Promise<void> => {
      reset();
      fillData();
    },
  });
}

function hide(): void {
  void modal.hide();
}

authEvent.subscribe((event) => {
  if (event.type === "snapshotUpdated" && event.data.isInitial) {
    if (TestLogic.notSignedInLastResult !== null) {
      show();
    }
  }
});

const modal = new AnimatedModal({
  dialogId: "lastSignedOutResult",
  setup: async (modalEl): Promise<void> => {
    modalEl.qs("button.save")?.on("click", async () => {
      const user = getAuthenticatedUser();
      if (user !== null) {
        void TestLogic.syncNotSignedInLastResult(user.uid);
      }
      hide();
    });
    modalEl.qs("button.discard")?.on("click", () => {
      TestLogic.clearNotSignedInResult();
      showNoticeNotification("Last test result discarded");
      hide();
    });
  },
  customWrapperClickHandler: (): void => {
    //do nothing
  },
});
