import { DataModel } from '@dvn/core/models/data-model';
import CalendarUtils from '@dvn/core/util/calendar';
import { SozlukApi } from '@dvn/sozluk/api';
import { Component, h, Host, Listen, Prop, State } from '@stencil/core';
import { createMentornityApiInstance } from '../../../../mentornity-js-client';
import { Config } from '../../../../mentornity-js-client/models';
import { MentornityBridgeApi } from '../../api/mentorinty-bridge-api';
import { mentornityApiEndpoint } from '../../constants/env';
import { getSessionDetails } from '../../util/session';
import { getPairOverviewViewConfig } from '../mentornity-pairs-overview-wrapper/wrapper-util';
import { sozlukCalendarEntryEn, sozlukCalendarEntryPtBr, sozlukCalendarEntryTr } from '../sozluk-calendar-entries';
import { sozlukEntries } from '../sozluk-entries';
/**
 * Mentornity web-client has the same event name mapping to consume the events with the same name.
 */
const ViewEvents = {
  openProfilePage: 'dvn.mentornity-member-home-widgets-wrapper.open-profile-page',
  openMeetingDetail: 'dvn.mentornity-member-home-widgets-wrapper.open-meeting-page',
  openMenteesPage: 'dvn.mentornity-member-home-widgets-wrapper.open-mentees-page',
  openMentorsPage: 'dvn.mentornity-member-home-widgets-wrapper.open-mentors-page',
  openUserPairPage: 'dvn.mentornity-member-home-widgets-wrapper.open-user-pair-page',
  openMentorSelectionPage: 'dvn.mentornity-member-home-widgets-wrapper.open-mentor-selection-page',
};
export class MentornityMemberHomeWidgetsWrapper {
  constructor() {
    this.isPairsDataPending = true;
    this.isMeetingPending = true;
    this.isAnnouncementsPending = true;
    this.isOrganisationDataPending = true;
  }
  componentWillLoad() {
    const { timeFormat, timeZone, language } = this;
    switch (language) {
      case 'pt-br':
        CalendarUtils.setLocale(language, sozlukCalendarEntryPtBr);
        break;
      case 'tr':
        CalendarUtils.setLocale(language, sozlukCalendarEntryTr);
        break;
      default:
        CalendarUtils.setLocale(language, sozlukCalendarEntryEn);
        break;
    }
    // set user's locale and time zone
    CalendarUtils.setTimeFormat(timeFormat);
    CalendarUtils.setTimeZone(timeZone);
    this.loadData();
  }
  onAction(event) {
    const action = event.detail;
    switch (action.name) {
      case 'go-to-mentees-page':
        // dispatch event for Mentornity web-client to handle the action
        window.dispatchEvent(new CustomEvent(ViewEvents.openMenteesPage));
        break;
      case 'go-to-mentors-page':
        // dispatch event for Mentornity web-client to handle the action
        window.dispatchEvent(new CustomEvent(ViewEvents.openMentorsPage));
        break;
      case 'go-to-pair-detail-page':
        // dispatch event for Mentornity web-client to handle the action
        window.dispatchEvent(new CustomEvent(ViewEvents.openUserPairPage, {
          detail: {
            userId: action.params.uid,
            subId: action.params.subId,
          }
        }));
        break;
      case 'go-to-mentor-selection':
        // dispatch event for Mentornity web-client to handle the action
        window.dispatchEvent(new CustomEvent(ViewEvents.openMentorSelectionPage));
        break;
      case 'go-to-meeting-page':
        // dispatch event for Mentornity web-client to handle the action
        window.dispatchEvent(new CustomEvent(ViewEvents.openMeetingDetail, {
          detail: {
            meetingId: action.params.meetingId,
          }
        }));
        break;
    }
  }
  async fetchPairs(meetings, mentornityApi, context) {
    const getViewConfigsResponse = await mentornityApi.getViewConfigs(context.organisationId)
      .catch(error => this.error = error);
    if (!getViewConfigsResponse)
      return;
    const viewConfigs = getViewConfigsResponse.results;
    const view = getPairOverviewViewConfig(context, this.language, this.organisationConfig, viewConfigs);
    const membership = DataModel.decode({});
    const userRefFieldId = context.role === 'mentor' ? 'subscribed' : 'subscriber';
    const getPairsResponse = await this.mentornityBridgeApi.getPairsOfUser(view.table.base, view.table.name, userRefFieldId, membership._id)
      .catch(error => this.error = error);
    const requestedList = await this.mentornityBridgeApi.getReceivedRequests(view.table.base, view.table.name)
      .catch(error => this.error = error);
    const activePairs = [];
    const requestedPairs = requestedList === null || requestedList === void 0 ? void 0 : requestedList.results;
    const pairsType = context.role === 'mentor' ? 'subscriber' : 'subscribed';
    getPairsResponse.results.forEach(pair => {
      if ((pair === null || pair === void 0 ? void 0 : pair.status) === 'active') {
        activePairs.push({
          user: pair[pairsType][0],
          meetings: meetings.filter(meeting => meeting.guests.some(guest => (meeting.status === 'active' && guest._id === pair[pairsType][0]._id)))
        });
      }
    });
    this.activePairs = activePairs;
    this.requestedPairs = requestedPairs;
    this.isPairsDataPending = false;
  }
  async fetchPairsMeetings(context, mentornityApi) {
    var _a;
    const { organisationDomain, organisationId, userId, groupId } = context;
    const hasMeetingGoal = this.meetingGoalConfig && ((_a = this.meetingGoalConfig.meetingGoals) === null || _a === void 0 ? void 0 : _a.length) > 0;
    let meetings;
    if (hasMeetingGoal) {
      meetings = await mentornityApi.getMeetingsInMeetingGoal(organisationDomain, { status: 'active' })
        .catch(error => this.error = error);
      meetings = meetings === null || meetings === void 0 ? void 0 : meetings.results;
    }
    else {
      if (this.userType === 'mentee' && this.menteeType === 'group') {
        meetings = await mentornityApi.getGroupsMeetingsChronologically(groupId, 0)
          .catch(error => this.error = error);
      }
      else {
        meetings = await mentornityApi.getUsersMeetingsChronologically(userId, organisationId, 0)
          .catch(error => this.error = error);
      }
    }
    return meetings;
  }
  async fetchPastMeeings(context) {
    let promise;
    if (context.groupId) {
      promise = this.api.getGroupsMeetingsChronologically(context.groupId, 0);
    }
    else {
      promise = this.api.getUsersMeetingsChronologically(this.context.userId, this.context.organisationId, 0);
    }
    let meetings = await promise.catch(error => this.error = error);
    const pastMeetings = [];
    let unfilledFormCount = 0;
    const today = new Date();
    (meetings || []).forEach((meeting) => {
      const startDate = new Date(meeting.startDate * 1000);
      if (startDate < today && meeting.status !== 'canceled') {
        if (!(meeting === null || meeting === void 0 ? void 0 : meeting.feedback))
          unfilledFormCount++;
        pastMeetings.unshift(meeting);
      }
    });
    return {
      meetings: pastMeetings,
      unfilledFormCount
    };
  }
  async fetchUserMeetings(context, mentornityApi) {
    var _a;
    let promise;
    if (context.groupId) {
      promise = mentornityApi.getGroupsMeetingsChronologically(context.groupId, 0);
    }
    else {
      promise = mentornityApi.getUsersMeetingsChronologically(context.userId, context.organisationId, 0);
    }
    let meetings = await promise.catch(error => this.error = error);
    const hasMeetingGoal = this.meetingGoalConfig && ((_a = this.meetingGoalConfig.meetingGoals) === null || _a === void 0 ? void 0 : _a.length) > 0;
    const upcomingMeetings = [];
    const pastMeetings = [];
    let unfilledFormCount = 0;
    let unfilledSessionFormCount = 0;
    const today = new Date();
    (meetings || []).forEach((meeting) => {
      var _a, _b, _c, _d, _e, _f, _g;
      const startDate = new Date(meeting.startDate * 1000);
      if (startDate >= today && meeting.status !== 'canceled') {
        upcomingMeetings.unshift(meeting);
      }
      if (startDate < today && meeting.status !== 'canceled') {
        if (!(meeting === null || meeting === void 0 ? void 0 : meeting.feedback))
          unfilledFormCount++;
        // calculate unfilled session forms
        if (hasMeetingGoal) {
          let sessionHasQuestions = false;
          const ownSession = hasMeetingGoal && ((_a = this.meetingGoalConfig) === null || _a === void 0 ? void 0 : _a.meetingGoals.find(session => session.identifier === meeting.meetingGoalIdentifier));
          const session = ownSession === null || ownSession === void 0 ? void 0 : ownSession.specifications[this.userType];
          sessionHasQuestions = ((_c = (_b = session === null || session === void 0 ? void 0 : session.postMeetingForm) === null || _b === void 0 ? void 0 : _b.fields) === null || _c === void 0 ? void 0 : _c.length) > 0 || ((_e = (_d = session === null || session === void 0 ? void 0 : session.preMeetingForm) === null || _d === void 0 ? void 0 : _d.fields) === null || _e === void 0 ? void 0 : _e.length) > 0;
          const hasFeedback = !!((_f = meeting === null || meeting === void 0 ? void 0 : meeting.feedback) === null || _f === void 0 ? void 0 : _f._id) || ((_g = meeting === null || meeting === void 0 ? void 0 : meeting.feedback) === null || _g === void 0 ? void 0 : _g.length) > 0;
          if (sessionHasQuestions && !hasFeedback)
            unfilledSessionFormCount++;
        }
        pastMeetings.unshift(meeting);
      }
    });
    this.upcomingMeetings = upcomingMeetings;
    this.pastMeetings = pastMeetings;
    this.unfilledSessionFormCount = unfilledSessionFormCount;
    this.unfilledFormCount = unfilledFormCount;
    this.isMeetingPending = false;
  }
  async fetchAnnouncements(mentornityApi) {
    const { organisationId, role } = this.context;
    // Fetch announcements from api
    this.announcements = await mentornityApi.getAnnouncements(organisationId, role);
    this.isAnnouncementsPending = false;
  }
  async fetchOrganisation(mentornityApi) {
    this.organisation = await mentornityApi.getOrganisation(this.organisationConfig.organisation._id);
    this.isOrganisationDataPending = false;
  }
  async loadData() {
    const { context, headers } = getSessionDetails(this.groupId);
    const { organisationId } = context;
    const showPairsWidget = this.mentorMenteeSubscription === 'restricted';
    // Setup configuration
    this.apiSozluk = new SozlukApi().setLanguage(this.language).setContents(sozlukEntries);
    this.mentornityBridgeApi = new MentornityBridgeApi(mentornityApiEndpoint, context, headers);
    const mentornityApi = createMentornityApiInstance(mentornityApiEndpoint, headers);
    mentornityApi.getOrganisationConfig(organisationId)
      .then((response) => {
      this.organisationConfig = Config.decode(response);
      this.mentornityBridgeApi.organisationConfig = Config.decode(response);
    });
    this.api = mentornityApi;
    this.context = context;
    this.sessionData = await mentornityApi.getSessionData(context.organisationDomain);
    this.meetingGoalConfig = await mentornityApi.getOrganisationMeetingGoalConfig(context.organisationDomain)
      .catch(error => this.error = error);
    // Fetch data from api
    const meetings = await this.fetchPairsMeetings(context, mentornityApi);
    if (showPairsWidget) {
      this.fetchPairs(meetings, mentornityApi, context);
    }
    this.fetchUserMeetings(context, mentornityApi);
    this.fetchOrganisation(mentornityApi);
    this.fetchAnnouncements(mentornityApi);
  }
  render() {
    const { activePairs, apiSozluk, isPairsDataPending, menteeType, meetingGoalConfig, organisationConfig, requestedPairs, userType, mentorMenteeSubscription, upcomingMeetings, pastMeetings, unfilledFormCount, unfilledSessionFormCount, isMeetingPending, sessionData, groupId, context, api, announcements, isAnnouncementsPending, isOrganisationDataPending, organisation } = this;
    const showPairsWidget = mentorMenteeSubscription === 'restricted';
    const feedbackConfig = (organisationConfig && organisationConfig.feedback) && (organisationConfig === null || organisationConfig === void 0 ? void 0 : organisationConfig.feedback[userType]);
    return (h(Host, null,
      h("mentornity-root-wrapper", { class: "d-block pt-4", theme: { cornerRadius: '15px' } },
        h("div", { class: "row" },
          h("div", { class: "col-md-8 order-2 order-md-1" },
            showPairsWidget &&
              h("mentornity-pair-meeting-summary-widget", { apiSozluk: apiSozluk, isPending: isPairsDataPending, activePairs: activePairs, organisationConfig: organisationConfig, meetingGoalConfig: meetingGoalConfig, requestedPairs: requestedPairs, userType: userType, menteeType: menteeType }),
            h("mentornity-upcoming-meetings-widget", { meetings: upcomingMeetings, meetingGoalConfig: this.meetingGoalConfig, account: sessionData === null || sessionData === void 0 ? void 0 : sessionData.account, groupId: groupId, isPending: isMeetingPending, timeFormat: this.timeFormat, apiSozluk: apiSozluk }),
            h("mentornity-past-meetings-widget", { meetings: pastMeetings, meetingGoalConfig: this.meetingGoalConfig, fetchPastMeetings: this.fetchPastMeeings, context: context, userType: userType, unfilledFormCount: unfilledFormCount, unfilledSessionFormCount: unfilledSessionFormCount, account: sessionData === null || sessionData === void 0 ? void 0 : sessionData.account, groupId: groupId, isPending: isMeetingPending, timeFormat: this.timeFormat, apiSozluk: apiSozluk, feedbackConfig: feedbackConfig, api: api })),
          h("div", { class: "col-md-4 order-1 order-md-2" },
            h("mentornity-announcements-widget", { announcements: announcements, isPending: isAnnouncementsPending, apiSozluk: apiSozluk }),
            h("mentornity-program-info-widget", { organisation: organisation, organisationConfig: organisationConfig, isPending: isOrganisationDataPending, apiSozluk: apiSozluk }))))));
  }
  static get is() { return "mentornity-member-home-widgets-wrapper"; }
  static get properties() { return {
    "language": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "language",
      "reflect": false
    },
    "timeZone": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "time-zone",
      "reflect": false
    },
    "timeFormat": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "time-format",
      "reflect": false
    },
    "userType": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "user-type",
      "reflect": false
    },
    "mentorMenteeSubscription": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "mentor-mentee-subscription",
      "reflect": false
    },
    "menteeType": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "mentee-type",
      "reflect": false
    },
    "groupId": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "group-id",
      "reflect": false
    }
  }; }
  static get states() { return {
    "error": {},
    "meetingGoalConfig": {},
    "context": {},
    "activePairs": {},
    "requestedPairs": {},
    "organisationConfig": {},
    "mentornityBridgeApi": {},
    "api": {},
    "isPairsDataPending": {},
    "isMeetingPending": {},
    "upcomingMeetings": {},
    "pastMeetings": {},
    "sessionData": {},
    "unfilledFormCount": {},
    "unfilledSessionFormCount": {},
    "announcements": {},
    "isAnnouncementsPending": {},
    "organisation": {},
    "isOrganisationDataPending": {}
  }; }
  static get listeners() { return [{
      "name": "action",
      "method": "onAction",
      "target": undefined,
      "capture": false,
      "passive": false
    }]; }
}
