<template>
  <div v-if="visible" class="dialog-overlay">
    <div class="dialog">
      <h1 class="text-xl font-bold text-center relative">
        Here's one:
        <div
          class="text-lg text-center p-2 leading-none absolute right-0 -top-1"
          @click="cancel"
        >
          <font-awesome icon="xmark" class="w-[1em]"></font-awesome>
        </div>
      </h1>
      <span class="mt-2 flex justify-between">
        <span
          v-if="currentCategory === CATEGORY_IDEAS"
          class="rounded-l border border-slate-400 bg-slate-200 px-4 py-2 flex"
          @click="prevIdea()"
        >
          <font-awesome icon="chevron-left" class="m-auto" />
        </span>

        <div class="m-2">
          <span v-if="currentCategory === CATEGORY_IDEAS">
            <p class="text-center text-lg">
              {{ IDEAS[currentIdeaIndex] }}
            </p>
          </span>
          <div v-if="currentCategory === CATEGORY_CONTACTS">
            <p class="text-center">
              <span
                v-if="currentContact == null"
                class="text-orange-500 text-lg"
              >
                That's all your contacts.
              </span>
              <span v-else>
                <span class="text-lg">
                  Did {{ currentContact.name || AppString.NO_CONTACT_NAME }}
                  <br />
                  or someone near them do anything &ndash; maybe a while ago?
                </span>
                <span class="flex justify-between">
                  <span />
                  <button
                    class="text-center bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mt-4"
                    @click="nextIdeaPastContacts()"
                  >
                    Skip Contacts <font-awesome icon="forward" />
                  </button>
                </span>
              </span>
            </p>
          </div>
        </div>

        <span
          class="rounded-r border border-slate-400 bg-slate-200 px-4 py-2 flex"
          @click="nextIdea()"
        >
          <font-awesome icon="chevron-right" class="m-auto" />
        </span>
      </span>
      <button
        class="block w-full text-center text-md uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mt-4"
        @click="proceed"
      >
        That's it!
      </button>
    </div>
  </div>
</template>

<script lang="ts">
import { Vue, Component } from "vue-facing-decorator";
import { Router } from "vue-router";

import { AppString, NotificationIface, USE_DEXIE_DB } from "../constants/app";
import { db } from "../db/index";
import { Contact } from "../db/tables/contacts";
import * as databaseUtil from "../db/databaseUtil";
import { GiverReceiverInputInfo } from "../libs/util";
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";

@Component
export default class GivenPrompts extends Vue {
  $notify!: (notification: NotificationIface, timeout?: number) => void;
  $router!: Router;

  CATEGORY_CONTACTS = 1;
  CATEGORY_IDEAS = 0;
  IDEAS = [
    "What food did someone make? (How did it free up your time for something? Was something doable because it eased your stress?)",
    "What did a family member do? (How did you take better action because it made you feel loved?)",
    "What compliment did someone give you? (What task could you tackle because it boosted your confidence?)",
    "Who is someone you can always rely on, and how did they demonstrate that? (What project tasks were enabled because you could depend on them?)",
    "What did you see someone give to someone else? (What is the effect of the positivity you gained from seeing that?)",
    "What is a way that someone helped you even though you have never met? (What different action did you take due to that newfound perspective or inspiration?)",
    "How did a musician or author or artist inspire you? (What were you motivated to do more creatively because of that?)",
    "What inspiration did you get from someone who handled tragedy well? (What could you accomplish with better grace or resilience after seeing their example?)",
    "What is something worth respect that an organization gave you? (How did their contribution improve the situation or enable new activities?)",
    "Who last gave you a good laugh? (What kind of bond or revitalization did that bring to a situation?)",
    "What do you recall someone giving you while you were young? (How did it bring excitement or teach a skill or ignite a passion that resulted in improvements in your life?)",
    "Who forgave you or overlooked a mistake? (How did that free you or build trust that enabled better relationships?)",
    "What is a way an ancestor contributed to your life? (What in your life is now possible because of their efforts? What challenges are you undertaking knowing of their lives?)",
    "What kind of help did someone at work give you? (How did that help with team progress? How did that lift your professional growth?)",
    "How did a teacher or mentor or great example help you? (How did their guidance enhance your attitude or actions?)",
    "What is a surprise gift you received? (What extra possibilities did it give you?)",
  ];

  callbackOnFullGiftInfo?: (
    contactInfo?: GiverReceiverInputInfo,
    description?: string,
  ) => void;
  currentCategory = this.CATEGORY_IDEAS; // 0 = IDEAS, 1 = CONTACTS
  currentContact: Contact | undefined = undefined;
  currentIdeaIndex = 0;
  numContacts = 0;
  shownContactDbIndices: Array<boolean> = [];
  visible = false;

  AppString = AppString;

  async open(
    callbackOnFullGiftInfo?: (
      contactInfo?: GiverReceiverInputInfo,
      description?: string,
    ) => void,
  ) {
    this.visible = true;
    this.callbackOnFullGiftInfo = callbackOnFullGiftInfo;

    const platformService = PlatformServiceFactory.getInstance();
    const result = await platformService.dbQuery(
      "SELECT COUNT(*) FROM contacts",
    );
    if (result) {
      this.numContacts = result.values[0][0] as number;
    }
    if (USE_DEXIE_DB) {
      this.numContacts = await db.contacts.count();
    }
    this.shownContactDbIndices = new Array<boolean>(this.numContacts); // all undefined to start
  }

  cancel() {
    this.currentCategory = this.CATEGORY_IDEAS;
    this.currentContact = undefined;
    this.currentIdeaIndex = 0;
    this.numContacts = 0;
    this.shownContactDbIndices = [];

    this.visible = false;
  }

  proceed() {
    // proceed with logic but don't change values (just in case some actions are added later)
    this.visible = false;
    if (this.currentCategory === this.CATEGORY_IDEAS) {
      this.$router.push({
        name: "contact-gift",
        query: {
          prompt: this.IDEAS[this.currentIdeaIndex],
        },
      });
    } else {
      // must be this.CATEGORY_CONTACTS
      this.callbackOnFullGiftInfo?.(
        this.currentContact as GiverReceiverInputInfo,
      );
    }
  }

  /**
   * Get the next idea.
   * If it is a contact prompt, loop through.
   */
  async nextIdea() {
    // check if the next one is an idea or a contact
    if (this.currentCategory === this.CATEGORY_IDEAS) {
      this.currentIdeaIndex++;
      if (this.currentIdeaIndex === this.IDEAS.length) {
        // must have just finished ideas so move to contacts
        this.findNextUnshownContact();
      }
    } else {
      // must be this.CATEGORY_CONTACTS
      this.findNextUnshownContact();
      // when that's finished, it'll reset to ideas
    }
  }

  /**
   * Get the previous idea.
   * If it is a contact prompt, loop through.
   */
  async prevIdea() {
    // check if the next one is an idea or a contact
    if (this.currentCategory === this.CATEGORY_IDEAS) {
      this.currentIdeaIndex--;
      if (this.currentIdeaIndex < 0) {
        // must have just finished ideas so move to contacts
        this.findNextUnshownContact();
      }
    } else {
      // must be this.CATEGORY_CONTACTS
      this.findNextUnshownContact();
      // when that's finished, it'll reset to ideas
    }
  }

  nextIdeaPastContacts() {
    this.currentContact = undefined;
    this.shownContactDbIndices = new Array<boolean>(this.numContacts);

    this.currentCategory = this.CATEGORY_IDEAS;
    // look at the previous idea and switch to the other side of the list
    this.currentIdeaIndex =
      this.currentIdeaIndex >= this.IDEAS.length ? 0 : this.IDEAS.length - 1;
  }

  async findNextUnshownContact() {
    if (this.currentCategory === this.CATEGORY_IDEAS) {
      // we're not in the contact prompts, so reset index array
      this.shownContactDbIndices = new Array<boolean>(this.numContacts);
    }
    this.currentCategory = this.CATEGORY_CONTACTS;

    let someContactDbIndex = Math.floor(Math.random() * this.numContacts);
    let count = 0;

    // as long as the index has an entry, loop
    while (
      this.shownContactDbIndices[someContactDbIndex] != null &&
      count++ < this.numContacts
    ) {
      someContactDbIndex = (someContactDbIndex + 1) % this.numContacts;
    }
    if (count >= this.numContacts) {
      // all contacts have been shown
      this.nextIdeaPastContacts();
    } else {
      // get the contact at that offset
      const platformService = PlatformServiceFactory.getInstance();
      const result = await platformService.dbQuery(
        "SELECT * FROM contacts LIMIT 1 OFFSET ?",
        [someContactDbIndex],
      );
      if (result) {
        const mappedContacts = databaseUtil.mapQueryResultToValues(result);
        this.currentContact = mappedContacts[0] as unknown as Contact;
      }
      if (USE_DEXIE_DB) {
        await db.open();
        this.currentContact = await db.contacts
          .offset(someContactDbIndex)
          .first();
      }
      this.shownContactDbIndices[someContactDbIndex] = true;
    }
  }
}
</script>

<style>
.dialog-overlay {
  z-index: 50;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 1.5rem;
}

.dialog {
  background-color: white;
  padding: 1rem;
  border-radius: 0.5rem;
  width: 100%;
  max-width: 500px;
}
</style>
