<template>
  <div id="container" ref="container">
    <TopBackBar :reloadable="true" title="부대 편성" @reload="refresh" />
    <div v-if="asyncReady && gameConstStore && me" id="troopList" class="bg0">
      <div v-for="[troopID, troop] of troopList" :key="troopID" class="troopItem">
        <div class="troopInfo">
          {{ troop.troopName }}<br />
          【 {{ gameConstStore.cityConst[troop.troopLeader.city].name }} 】
        </div>
        <div class="troopTurn">【턴】 {{ troop.turnTime.slice(14, 19) }}</div>
        <div class="troopLeaderIcon">
          <img height="64" width="64" :src="getIconPath(troop.troopLeader.imgsvr, troop.troopLeader.picture)" />
        </div>
        <div class="troopLeaderName">
          {{ troop.troopLeader.name }}
        </div>
        <div class="troopMembers">
          <template v-for="(member, idx) in troop.members" :key="member.no">
            <template v-if="idx != 0">, </template>
            <span
              v-if="member.troop == member.no"
              class="troopMember troopLeader"
              @mouseover="setPopup($event, member)"
              @mouseout="setPopup($event, undefined)"
            >
              {{ member.name }}
            </span>
            <span
              v-else
              class="troopMember"
              @mouseover="setPopup($event, member)"
              @mouseout="setPopup($event, undefined)"
            >
              {{ member.name }}
            </span>
          </template>
          ({{ troop.members.length }}명)
        </div>
        <div class="troopReservedCommand">
          <div v-for="(brief, idx) in troop.reservedCommandBrief" :key="idx">
            {{ `${idx + 1}: ${brief}` }}
          </div>
        </div>
        <div class="troopAction">
          <BButton v-if="!me.troop">부대 탑승</BButton>
          <BButton v-if="me.troop == troop.troopID">부대 탈퇴</BButton>
        </div>
      </div>
    </div>

    <BottomBar />
    <div
      v-if="asyncReady && gameConstStore"
      id="generalPopup"
      :style="{ display: popupGeneralTarget ? 'block' : 'none', top: `${popupTop}px` }"
    >
      <div v-if="!popupGeneralTarget || !nationInfo"></div>
      <template v-else-if="popupGeneralTarget.st1">
        <GeneralBasicCard
          :general="popupGeneralTarget"
          :troopInfo="convBasicCardTroopInfo(popupGeneralTarget)"
          :nation="nationInfo"
        />
        <GeneralSupplementCard :general="popupGeneralTarget" :showCommandList="true" />
      </template>

      <GeneralLiteCard v-else :general="popupGeneralTarget" :nation="nationInfo" />
    </div>
  </div>
</template>

<script setup lang="ts">
import TopBackBar from "@/components/TopBackBar.vue";
import BottomBar from "@/components/BottomBar.vue";
import { onMounted, provide, ref, toRef } from "vue";
import { SammoAPI } from "./SammoAPI";
import { BButton, useToast } from "bootstrap-vue-3";
import { unwrap } from "./util/unwrap";
import { isString } from "lodash";
import type { GeneralListItem, GeneralListItemP1 } from "./defs/API/Nation";
import { merge2DArrToObjectArr } from "./util/merge2DArrToObjectArr";
import { convertIterableToMap } from "@/util/convertIterableToMap";
import { GameConstStore, getGameConstStore } from "./GameConstStore";
import { getIconPath } from "@/util/getIconPath";
import GeneralBasicCard from "./components/GeneralBasicCard.vue";
import type { NationStaticItem } from "./defs";
import GeneralLiteCard from "./components/GeneralLiteCard.vue";
import GeneralSupplementCard from "./components/GeneralSupplementCard.vue";
const toasts = unwrap(useToast());

const asyncReady = ref(false);
const gameConstStore = ref<GameConstStore>();
provide("gameConstStore", gameConstStore);
const storeP = getGameConstStore().then((store) => {
  gameConstStore.value = store;
});

void Promise.all([storeP]).then(() => {
  asyncReady.value = true;
});

const container = ref<HTMLElement>();

const popupGeneralTarget = ref<GeneralListItem>();
const popupTop = ref<number>(0);

function convBasicCardTroopInfo(general: GeneralListItemP1): { leader: GeneralListItemP1; name: string } | undefined {
  const troop = troopList.value.get(general.troop);
  if (!troop) {
    return undefined;
  }
  const troopLeader = troop.troopLeader;
  if (!troopLeader.st1) {
    return undefined;
  }
  return {
    leader: troopLeader,
    name: troop.troopName,
  };
}

function setPopup(e: MouseEvent, general: GeneralListItem | undefined) {
  if (general === undefined || !e.target) {
    popupTop.value = 0;
    popupGeneralTarget.value = undefined;
    return;
  }
  console.log("e", e);

  const target = e.target as HTMLElement;
  popupGeneralTarget.value = general;
  let parent = target.parentElement;
  console.log("parent", parent);
  while (parent !== null && !parent.classList.contains("troopMembers")) {
    parent = parent.parentElement;
  }

  if (parent === null) {
    popupTop.value = 0;
    popupGeneralTarget.value = undefined;
    return;
  }

  console.log(parent.offsetTop, parent.offsetHeight, parent);

  popupTop.value = parent.offsetTop + parent.offsetHeight;
}

type TroopInfo = {
  troopID: number;
  troopName: string;
  troopLeader: GeneralListItem;
  turnTime: string;
  reservedCommandBrief: string[];
  members: GeneralListItem[];
};

const me = ref<GeneralListItem>({} as GeneralListItem);

const troopList = ref(new Map<number, TroopInfo>());
const generalList = ref(new Map<number, GeneralListItem>());
const nationInfo = ref<NationStaticItem>();

async function refresh() {
  try {
    const generalListP = SammoAPI.Nation.GeneralList();
    const nationP = SammoAPI.Nation.GetNationInfo({});
    nationInfo.value = (await nationP).nation;
    const { column, list, permission, troops, env, myGeneralID } = await generalListP;

    //빠른 턴 순서로 정렬되어있다.

    //XXX: 로직상 똑같은데....
    if (permission == 0) {
      const rawGeneralList = merge2DArrToObjectArr(column, list);
      generalList.value = convertIterableToMap(
        rawGeneralList.map((v) => {
          return { permission, st0: true, st1: false, st2: false, ...v };
        }),
        "no"
      );
    } else if (permission == 1) {
      const rawGeneralList = merge2DArrToObjectArr(column, list);
      generalList.value = convertIterableToMap(
        rawGeneralList.map((v) => {
          return { permission, st0: true, st1: true, st2: false, ...v };
        }),
        "no"
      );
    } else if ([2, 3, 4].includes(permission)) {
      const rawGeneralList = merge2DArrToObjectArr(column, list);
      generalList.value = convertIterableToMap(
        rawGeneralList.map((v) => {
          return { permission, st0: true, st1: true, st2: true, ...v };
        }),
        "no"
      );
    } else {
      throw `?? ${permission}`;
    }

    me.value = unwrap(generalList.value.get(myGeneralID));

    troopList.value = new Map();

    for (const { id: troopLeaderID, name: troopName, turntime: troopTurntime, reservedCommand } of troops) {
      if (!generalList.value.has(troopLeaderID)) {
        toasts.warning({
          title: "경고",
          body: `${troopName} 부대장(${troopLeaderID})이 아국 소속이 아닌 것 같습니다.`,
        });
        continue;
      }
      troopList.value.set(troopLeaderID, {
        troopID: troopLeaderID,
        troopName,
        troopLeader: unwrap(generalList.value.get(troopLeaderID)),
        turnTime: troopTurntime,
        reservedCommandBrief: reservedCommand,
        members: [],
      });
    }

    for (const general of generalList.value.values()) {
      const troopID = general.troop;
      if (!troopID) {
        continue;
      }
      const troop = troopList.value.get(troopID);
      if (troop === undefined) {
        console.error(`부대 소속 오류: ${general.no} in ${troopID}`);
        continue;
      }
      troop.members.push(general);
    }
  } catch (e) {
    if (isString(e)) {
      toasts.danger({
        title: "오류",
        body: e,
      });
    }
    console.error(e);
    return;
  }
}

onMounted(() => {
  void refresh();
});
</script>

<style lang="scss" scoped>
@import "@scss/common/break_500px.scss";

#container {
  position: relative;
}

#generalPopup {
  position: absolute;
  width: 500px;
}

.troopItem {
  display: grid;
  border-right: solid 1px gray;

  > div {
    border-top: solid 1px gray;
    border-left: solid 1px gray;
  }

  .troopInfo {
    grid-column: 1/2;
    grid-row: 1/2;
    display: grid;
    align-content: center;
    text-align: center;
  }

  .troopTurn {
    grid-column: 1/2;
    grid-row: 2/3;
    display: grid;
    align-content: center;
    justify-content: center;
  }

  .troopLeaderIcon {
    grid-column: 2/3;
    grid-row: 1/2;
    display: grid;
    align-content: center;
    justify-content: center;
  }

  .troopLeaderName {
    grid-column: 2/3;
    grid-row: 2/3;
    display: grid;
    align-items: center;
    justify-content: center;
  }

  .troopReservedCommand {
    grid-column: 4/5;
    grid-row: 1/3;
    font-size: 85%;
    text-align: left;
  }

  .troopAction {
    grid-column: 5/6;
    grid-row: 1/3;
  }

  .troopMembers {
    text-align: left;
    padding: 0.5em 0.7em;
  }
}

@include media-1000px {
  #container {
    width: 1000px;
    margin: 0 auto;
    position: relative;
  }

  #generalPopup {
    left: 260px;
  }

  .troopItem {
    grid-template-rows: 65px 28px;
    grid-template-columns: 130px 130px 1fr 110px 130px;

    .troopMembers {
      grid-column: 3/4;
      grid-row: 1/3;
    }

    &:last-of-type {
      border-bottom: solid 1px gray;
    }
  }
}

@include media-500px {
  #container {
    width: 500px;
    margin: 0 auto;
    position: relative;
  }

  #generalPopup {
    left: 0;
  }

  .troopItem {
    grid-template-rows: 65px 28px auto;
    grid-template-columns: 130px 130px 0px 110px 130px;

    .troopMembers {
      grid-column: 2/6;
      grid-row: 3/4;
    }

    &:last-of-type {
      .troopMembers,
      .troopTurn {
        border-bottom: solid 1px gray;
      }
    }
  }
}
</style>
