<template>
  <QuickNav selected="Home"></QuickNav>
  <!-- CONTENT -->
  <section id="Content" class="p-6 pb-24 max-w-3xl mx-auto">
    <!-- Breadcrumb -->
    <div id="ViewBreadcrumb" class="mb-8">
      <h1 class="text-lg text-center font-light relative px-7">
        <!-- Back -->
        <font-awesome
          icon="chevron-left"
          class="fa-fw text-lg text-center px-2 py-1 absolute -left-2 -top-1"
          @click="$router.back()"
        />
        New Activity For You
      </h1>
    </div>

    <!-- Display a single row with the name of "New Offers To You" with a count. -->
    <div class="flex justify-between" data-testId="showOffersToUser">
      <div>
        <span class="text-lg font-medium"
          >{{ newOffersToUser.length
          }}{{ newOffersToUserHitLimit ? "+" : "" }}</span
        >
        <span class="text-lg font-medium ml-4"
          >New Offer{{ newOffersToUser.length === 1 ? "" : "s" }} To You</span
        >
        <font-awesome
          v-if="newOffersToUser.length > 0"
          :icon="showOffersDetails ? 'chevron-down' : 'chevron-right'"
          class="cursor-pointer ml-4 mr-4 text-lg"
          @click="expandOffersToUserAndMarkRead()"
        />
      </div>
      <router-link to="/recent-offers-to-user" class="text-blue-500">
        See&nbsp;all
      </router-link>
    </div>

    <div v-if="showOffersDetails" class="ml-4 mt-4">
      <ul class="list-disc ml-4">
        <li
          v-for="offer in newOffersToUser"
          :key="offer.jwtId"
          class="mt-4 relative group"
        >
          <span>{{
            didInfo(offer.offeredByDid, activeDid, allMyDids, allContacts)
          }}</span>
          offered
          <span v-if="offer.objectDescription">{{
            offer.objectDescription
          }}</span
          >{{ offer.objectDescription && offer.amount ? ", and " : "" }}
          <span v-if="offer.amount">{{
            displayAmount(offer.unit, offer.amount)
          }}</span>
          <router-link
            :to="{ path: '/claim/' + encodeURIComponent(offer.jwtId) }"
            class="text-blue-500"
          >
            <font-awesome
              icon="file-lines"
              class="pl-2 text-blue-500 cursor-pointer"
            />
          </router-link>
          <!-- New line that appears on hover or when the offer is clicked -->
          <div
            class="absolute left-0 w-full text-left text-gray-500 text-sm hidden group-hover:flex cursor-pointer items-center"
            @click="markOffersAsReadStartingWith(offer.jwtId)"
          >
            <span class="inline-block w-8 h-px bg-gray-500 mr-2" />
            Click to keep all above as new offers
          </div>
        </li>
      </ul>
    </div>

    <!-- Display a single row with the name of "New Offers To Your Projects" with a count. -->
    <div
      class="mt-4 flex justify-between"
      data-testId="showOffersToUserProjects"
    >
      <div>
        <span class="text-lg font-medium"
          >{{ newOffersToUserProjects.length
          }}{{ newOffersToUserProjectsHitLimit ? "+" : "" }}</span
        >
        <span class="text-lg font-medium ml-4"
          >New Offer{{ newOffersToUserProjects.length === 1 ? "" : "s" }} To
          Your Projects</span
        >
        <font-awesome
          v-if="newOffersToUserProjects.length > 0"
          :icon="
            showOffersToUserProjectsDetails ? 'chevron-down' : 'chevron-right'
          "
          class="cursor-pointer ml-4 mr-4 text-lg"
          @click="expandOffersToUserProjectsAndMarkRead()"
        />
      </div>
      <router-link to="/recent-offers-to-user-projects" class="text-blue-500">
        See&nbsp;all
      </router-link>
    </div>

    <div v-if="showOffersToUserProjectsDetails" class="ml-4 mt-4">
      <ul class="list-disc ml-4">
        <li
          v-for="offer in newOffersToUserProjects"
          :key="offer.jwtId"
          class="mt-4 relative group"
        >
          <span>{{
            didInfo(offer.offeredByDid, activeDid, allMyDids, allContacts)
          }}</span>
          offered
          <span v-if="offer.objectDescription">{{
            offer.objectDescription
          }}</span
          >{{ offer.objectDescription && offer.amount ? ", and " : "" }}
          <span v-if="offer.amount">{{
            displayAmount(offer.unit, offer.amount)
          }}</span>
          to
          <span>{{ offer.planName }}</span>
          <router-link
            :to="{ path: '/claim/' + encodeURIComponent(offer.jwtId) }"
            class="text-blue-500"
          >
            <font-awesome
              icon="file-lines"
              class="pl-2 text-blue-500 cursor-pointer"
            />
          </router-link>
          <!-- New line that appears on hover -->
          <div
            class="absolute left-0 w-full text-left text-gray-500 text-sm hidden group-hover:flex cursor-pointer items-center"
            @click="markOffersToUserProjectsAsReadStartingWith(offer.jwtId)"
          >
            <span class="inline-block w-8 h-px bg-gray-500 mr-2" />
            Click to keep all above as new offers
          </div>
        </li>
      </ul>
    </div>
  </section>
</template>

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

import GiftedDialog from "../components/GiftedDialog.vue";
import QuickNav from "../components/QuickNav.vue";
import EntityIcon from "../components/EntityIcon.vue";
import { NotificationIface, USE_DEXIE_DB } from "../constants/app";
import {
  db,
  retrieveSettingsForActiveAccount,
  updateAccountSettings,
} from "../db/index";
import { Contact } from "../db/tables/contacts";
import { Router } from "vue-router";
import { OfferSummaryRecord, OfferToPlanSummaryRecord } from "../interfaces";
import {
  didInfo,
  displayAmount,
  getNewOffersToUser,
  getNewOffersToUserProjects,
} from "../libs/endorserServer";
import { retrieveAccountDids } from "../libs/util";
import { PlatformServiceFactory } from "../services/PlatformServiceFactory";
import * as databaseUtil from "../db/databaseUtil";
import { logger } from "../utils/logger";

@Component({
  components: { GiftedDialog, QuickNav, EntityIcon },
})
export default class NewActivityView extends Vue {
  $notify!: (notification: NotificationIface, timeout?: number) => void;
  $router!: Router;
  activeDid = "";
  allContacts: Array<Contact> = [];
  allMyDids: string[] = [];
  apiServer = "";
  lastAckedOfferToUserJwtId = "";
  lastAckedOfferToUserProjectsJwtId = "";
  newOffersToUser: Array<OfferSummaryRecord> = [];
  newOffersToUserHitLimit = false;
  newOffersToUserProjects: Array<OfferToPlanSummaryRecord> = [];
  newOffersToUserProjectsHitLimit = false;

  showOffersDetails = false;
  showOffersToUserProjectsDetails = false;
  didInfo = didInfo;
  displayAmount = displayAmount;

  async created() {
    try {
      let settings = await databaseUtil.retrieveSettingsForActiveAccount();
      if (USE_DEXIE_DB) {
        settings = await retrieveSettingsForActiveAccount();
      }
      this.apiServer = settings.apiServer || "";
      this.activeDid = settings.activeDid || "";
      this.lastAckedOfferToUserJwtId = settings.lastAckedOfferToUserJwtId || "";
      this.lastAckedOfferToUserProjectsJwtId =
        settings.lastAckedOfferToUserProjectsJwtId || "";

      const platformService = PlatformServiceFactory.getInstance();
      const queryResult = await platformService.dbQuery(
        "SELECT * FROM contacts",
      );
      this.allContacts = databaseUtil.mapQueryResultToValues(
        queryResult,
      ) as unknown as Contact[];
      if (USE_DEXIE_DB) {
        await db.open();
        this.allContacts = await db.contacts.toArray();
      }

      this.allMyDids = await retrieveAccountDids();

      const offersToUserData = await getNewOffersToUser(
        this.axios,
        this.apiServer,
        this.activeDid,
        this.lastAckedOfferToUserJwtId,
      );
      this.newOffersToUser = offersToUserData.data;
      this.newOffersToUserHitLimit = offersToUserData.hitLimit;

      const offersToUserProjectsData = await getNewOffersToUserProjects(
        this.axios,
        this.apiServer,
        this.activeDid,
        this.lastAckedOfferToUserProjectsJwtId,
      );
      this.newOffersToUserProjects = offersToUserProjectsData.data;
      this.newOffersToUserProjectsHitLimit = offersToUserProjectsData.hitLimit;

      // eslint-disable-next-line @typescript-eslint/no-explicit-any
    } catch (err: any) {
      logger.error("Error retrieving settings & contacts:", err);
      this.$notify(
        {
          group: "alert",
          type: "danger",
          title: "Error",
          text: err.message || "There was an error retrieving your activity.",
        },
        5000,
      );
    }
  }

  async expandOffersToUserAndMarkRead() {
    this.showOffersDetails = !this.showOffersDetails;
    if (this.showOffersDetails) {
      await databaseUtil.updateDidSpecificSettings(this.activeDid, {
        lastAckedOfferToUserJwtId: this.newOffersToUser[0].jwtId,
      });
      if (USE_DEXIE_DB) {
        await updateAccountSettings(this.activeDid, {
          lastAckedOfferToUserJwtId: this.newOffersToUser[0].jwtId,
        });
      }
      // note that we don't update this.lastAckedOfferToUserJwtId in case they
      // later choose the last one to keep the offers as new
      this.$notify(
        {
          group: "alert",
          type: "info",
          title: "Marked as Read",
          text: "The offers are marked as viewed. Click in the list to keep them as new.",
        },
        5000,
      );
    }
  }

  async markOffersAsReadStartingWith(jwtId: string) {
    const index = this.newOffersToUser.findIndex(
      (offer) => offer.jwtId === jwtId,
    );
    if (index !== -1 && index < this.newOffersToUser.length - 1) {
      // Set to the next offer's jwtId
      await databaseUtil.updateDidSpecificSettings(this.activeDid, {
        lastAckedOfferToUserJwtId: this.newOffersToUser[index + 1].jwtId,
      });
      if (USE_DEXIE_DB) {
        await db.settings.update(this.activeDid, {
          lastAckedOfferToUserJwtId: this.newOffersToUser[index + 1].jwtId,
        });
      }
    } else {
      // it's the last entry (or not found), so just keep it the same
      await databaseUtil.updateDidSpecificSettings(this.activeDid, {
        lastAckedOfferToUserJwtId: this.lastAckedOfferToUserJwtId,
      });
      if (USE_DEXIE_DB) {
        await db.settings.update(this.activeDid, {
          lastAckedOfferToUserJwtId: this.lastAckedOfferToUserJwtId,
        });
      }
    }
    this.$notify(
      {
        group: "alert",
        type: "info",
        title: "Marked as Unread",
        text: "All offers above that line are marked as unread.",
      },
      3000,
    );
  }

  async expandOffersToUserProjectsAndMarkRead() {
    this.showOffersToUserProjectsDetails =
      !this.showOffersToUserProjectsDetails;
    if (this.showOffersToUserProjectsDetails) {
      await databaseUtil.updateDidSpecificSettings(this.activeDid, {
        lastAckedOfferToUserProjectsJwtId:
          this.newOffersToUserProjects[0].jwtId,
      });
      if (USE_DEXIE_DB) {
        await db.settings.update(this.activeDid, {
          lastAckedOfferToUserProjectsJwtId:
            this.newOffersToUserProjects[0].jwtId,
        });
      }
      // note that we don't update this.lastAckedOfferToUserProjectsJwtId in case
      // they later choose the last one to keep the offers as new
      this.$notify(
        {
          group: "alert",
          type: "info",
          title: "Marked as Read",
          text: "The offers are now marked as viewed. Click in the list to keep them as new.",
        },
        5000,
      );
    }
  }

  async markOffersToUserProjectsAsReadStartingWith(jwtId: string) {
    const index = this.newOffersToUserProjects.findIndex(
      (offer) => offer.jwtId === jwtId,
    );
    if (index !== -1 && index < this.newOffersToUserProjects.length - 1) {
      // Set to the next offer's jwtId
      await databaseUtil.updateDidSpecificSettings(this.activeDid, {
        lastAckedOfferToUserProjectsJwtId:
          this.newOffersToUserProjects[index + 1].jwtId,
      });
      if (USE_DEXIE_DB) {
        await db.settings.update(this.activeDid, {
          lastAckedOfferToUserProjectsJwtId:
            this.newOffersToUserProjects[index + 1].jwtId,
        });
      }
    } else {
      // it's the last entry (or not found), so just keep it the same
      await databaseUtil.updateDidSpecificSettings(this.activeDid, {
        lastAckedOfferToUserProjectsJwtId:
          this.lastAckedOfferToUserProjectsJwtId,
      });
      if (USE_DEXIE_DB) {
        await db.settings.update(this.activeDid, {
          lastAckedOfferToUserProjectsJwtId:
            this.lastAckedOfferToUserProjectsJwtId,
        });
      }
    }
    this.$notify(
      {
        group: "alert",
        type: "info",
        title: "Marked as Unread",
        text: "All offers above that line are marked as unread.",
      },
      3000,
    );
  }
}
</script>
