import { Component, Element, Event, h, Host, Listen, Prop, State } from "@stencil/core";
import { Error } from "gracely";
import { Identifier, Property } from "authly";
import { App } from "smoothly";
import { Customer, Key } from "@payfunc/model";
import { Connection } from "@payfunc/model-base";
import { Handler } from "./Handler";
import { isDefined } from "./model";
import * as translation from "./translation";
export class IntergiroCustomer {
  constructor() {
    this.login = false;
    this.paths = [""];
    this.unpackedKeys = [];
  }
  async componentWillLoad() {
    await Handler.open("", "");
    Handler.client.me.onUnauthorized = () => {
      this.customer = undefined;
      return Promise.reject();
    };
    if (location.search && location.search.split("&").length > 2) {
      const queryParameters = location.search.substring(1).split("&");
      const customerId = decodeURIComponent(queryParameters[0].split("=")[1]);
      const linkId = decodeURIComponent(queryParameters[1].split("=")[1]);
      if (Identifier.is(customerId, 16) && Identifier.is(linkId, 16)) {
        Connection.key = "a.b.c";
        Connection.url = decodeURIComponent(queryParameters[2].split("=")[1]);
        await Handler.client.customer.openLink(customerId, linkId);
      }
    }
    this.authenticate();
    this.t = translation.create(this.element);
  }
  async authenticate() {
    var _a;
    this.apiKey && this.apiKey != "" && (Connection.key = this.apiKey);
    const unpackedKey = await Key.getVerifier().verify(Connection.key, "customer");
    if (unpackedKey && unpackedKey.customer && Connection.key) {
      this.login = false;
      Handler.client.me.addCustomerKey((_a = Connection.key) !== null && _a !== void 0 ? _a : "", unpackedKey.customer);
      Connection.url = unpackedKey.iss;
      const response = await Handler.client.customer.get("me");
      this.unpackedKeys = await Handler.client.me.customerKeys.reduce(async (accumulator, currentKey) => {
        const unpacked = await Key.getVerifier()
          .add(Property.Remover.create(["exp"]))
          .verify(currentKey, "customer");
        if (unpacked)
          (await accumulator).push(unpacked);
        return accumulator;
      }, Promise.resolve([]));
      this.customer = !Error.is(response) && typeof response != "string" ? response : undefined;
      this.unpackedKey = unpackedKey;
      const orders = await Handler.client.order.list();
      this.customerRefresh = window.setTimeout(async () => {
        await this.getCustomer();
      }, 30000);
      if (!Error.is(orders) && typeof orders != "string")
        this.orders = orders;
    }
    else {
      window.clearTimeout(this.customerRefresh);
      this.customerRefresh = undefined;
      if (!this.unpackedKey)
        this.login = true;
    }
    this.features();
  }
  async onSelectionChanged(e) {
    if (e.detail.identifier == "customer") {
      this.apiKey = e.detail.value;
      this.authenticate();
    }
  }
  async updateMethod(event) {
    if (Customer.is(this.customer)) {
      await Handler.client.customer.setMethods(this.customer.method, "me");
      await Handler.client.customer.retryPayment();
      await this.getCustomer();
    }
  }
  async getCustomer() {
    const response = await Handler.client.customer.get("me");
    if (!Error.is(response))
      this.customer = response;
    return response;
  }
  logIn(e) {
    this.apiKey = e.detail[0];
    this.unpackedKey = e.detail[1];
    this.login = false;
    this.authenticate();
  }
  features() {
    var _a;
    this.paths =
      ((_a = this.unpackedKey) === null || _a === void 0 ? void 0 : _a.features) == undefined
        ? this.paths
        : [
          "",
          this.checkAccess(this.unpackedKey.features, "customer.order", true),
          this.checkAccess(this.unpackedKey.features, "customer.subscription", false),
          this.checkAccess(this.unpackedKey.features, "customer.balance", false),
          this.checkAccess(this.unpackedKey.features, "customer.address", true),
          this.checkAccess(this.unpackedKey.features, "customer.method", true),
        ].filter(isDefined);
  }
  checkAccess(features, flag, showByDefault) {
    return flag.match(/\w+\.\w+/)
      ? this.checkAccess(features[flag.split(".")[0]], flag.split(".")[1], showByDefault)
      : (features != undefined && typeof features[flag] == "boolean" ? features[flag] : showByDefault)
        ? flag
        : undefined;
  }
  handleTrigger(event) {
    if (event.detail.name == "logout") {
      this.login = true;
      this.apiKey = undefined;
      this.customer = undefined;
      Connection.key = undefined;
    }
  }
  getCustomCssVariables() {
    var _a, _b, _c, _d, _e;
    const result = {};
    if (this.cosmetic && (typeof this.cosmetic == "object" || ((_a = this.cosmetic) === null || _a === void 0 ? void 0 : _a.length) > 0)) {
      const cosmetic = typeof this.cosmetic == "string" && this.cosmetic.length > 0 ? JSON.parse(this.cosmetic) : this.cosmetic;
      Object.entries({
        "--smoothly-font-family": (_b = cosmetic === null || cosmetic === void 0 ? void 0 : cosmetic.fontFamily) !== null && _b !== void 0 ? _b : cosmetic === null || cosmetic === void 0 ? void 0 : cosmetic.font_family,
        "--smoothly-primary-color": (_c = cosmetic === null || cosmetic === void 0 ? void 0 : cosmetic.success) === null || _c === void 0 ? void 0 : _c.background,
        "--smoothly-success-color": (_d = cosmetic === null || cosmetic === void 0 ? void 0 : cosmetic.success) === null || _d === void 0 ? void 0 : _d.background,
        "--smoothly-success-contrast": (_e = cosmetic === null || cosmetic === void 0 ? void 0 : cosmetic.success) === null || _e === void 0 ? void 0 : _e.color,
      }).forEach(([key, value]) => {
        value && (result[key] = value);
      });
    }
    return result;
  }
  render() {
    const t = this.t;
    return (h(Host, { style: this.getCustomCssVariables() }, !this.component || this.component == "app" ? (h("customer-login", { open: this.login, onSelected: e => this.logIn(e) },
      h(App, { label: "Intergiro Customer" },
        Customer.is(this.customer)
          ? [
            h("smoothly-room", { path: "", to: "" }),
            this.unpackedKeys.length > 1 ? (h("smoothly-select", { slot: "header", identifier: "customer", background: "transparent" }, this.unpackedKeys.map(a => {
              var _a;
              return (h("option", { value: a.token, selected: ((_a = this.unpackedKey) === null || _a === void 0 ? void 0 : _a.customer) == a.customer }, `${a.name} - ${t("Customer ID")}: ${a.customer}`));
            }))) : (h("span", { slot: "header" }, this.unpackedKey ? this.unpackedKey.name : "")),
            this.paths.includes("order") && (h("smoothly-room", { label: t("order"), path: "order" },
              h("customer-orders", { orders: this.orders, cosmetic: this.cosmetic, receipt: this.whitelistReceipt(), component: this.component }))),
            this.paths.includes("subscription") && (h("smoothly-room", { label: t("subscription"), path: "subscription" },
              h("customer-subscriptions", { customer: this.customer, cosmetic: this.cosmetic, orders: this.orders, receipt: this.whitelistReceipt(), component: this.component }))),
            this.paths.includes("balance") && (h("smoothly-room", { label: t("balance"), path: "balance" },
              h("customer-balance", { customer: this.customer, orders: this.orders, component: this.component }))),
            this.paths.includes("method") && (h("smoothly-room", { label: t("methods"), path: "method" },
              h("customer-methods", { "api-key": Connection.key, cosmetic: this.cosmetic, customer: this.customer, methods: this.customer.method, onUpdate: (e) => this.updateMethod(e), component: this.component }))),
            this.paths.includes("address") && (h("smoothly-room", { label: t("address"), path: "address" },
              h("customer-address", { customer: this.customer, component: this.component }))),
          ]
          : [
            this.paths.map(path => (h("smoothly-room", { path: path },
              h("customer-error", { component: this.component, unpackedKey: this.unpackedKey })))),
          ],
        h("smoothly-trigger", { slot: "nav-end", type: "link", fill: "clear", name: "logout" },
          h("smoothly-icon", { toolTip: "Log out", name: "log-out", size: "medium", fill: "clear", color: "light" }))))) : !Customer.is(this.customer) ? (h("customer-error", { component: this.component, unpackedKey: this.unpackedKey })) : this.component == "order" && this.paths.includes("order") ? (h("customer-orders", { orders: this.orders, cosmetic: this.cosmetic, receipt: this.whitelistReceipt(), component: this.component })) : this.component == "subscription" && this.paths.includes("subscription") ? (h("customer-subscriptions", { customer: this.customer, cosmetic: this.cosmetic, orders: this.orders, receipt: this.whitelistReceipt(), component: this.component })) : this.component == "balance" && this.paths.includes("balance") ? (h("customer-balance", { customer: this.customer, orders: this.orders, component: this.component })) : this.component == "method" && this.paths.includes("method") ? (h("customer-methods", { cosmetic: this.cosmetic, customer: this.customer, methods: this.customer.method, onUpdate: (e) => this.updateMethod(e), component: this.component })) : this.component == "address" && this.paths.includes("address") ? (h("customer-address", { customer: this.customer, component: this.component })) : (h("customer-error", { component: this.component, unpackedKey: this.unpackedKey }))));
  }
  whitelistReceipt() {
    var _a, _b;
    return ((_a = this.unpackedKey) === null || _a === void 0 ? void 0 : _a.sub) != undefined && ["testtest", "test0123"].includes((_b = this.unpackedKey) === null || _b === void 0 ? void 0 : _b.sub);
  }
  static get is() { return "intergiro-customer"; }
  static get encapsulation() { return "scoped"; }
  static get originalStyleUrls() { return {
    "$": ["style.css"]
  }; }
  static get styleUrls() { return {
    "$": ["style.css"]
  }; }
  static get properties() { return {
    "apiKey": {
      "type": "string",
      "mutable": true,
      "complexType": {
        "original": "string",
        "resolved": "string | undefined",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "api-key",
      "reflect": false
    },
    "component": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "\"app\" | \"order\" | \"subscription\" | \"balance\" | \"address\" | \"method\"",
        "resolved": "\"address\" | \"app\" | \"balance\" | \"method\" | \"order\" | \"subscription\" | undefined",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "component",
      "reflect": false
    },
    "cosmetic": {
      "type": "string",
      "mutable": true,
      "complexType": {
        "original": "| string\n\t\t| {\n\t\t\t\tfontFamily?: string\n\t\t\t\theader?: { background?: string; color?: string }\n\t\t\t\tbody?: { background?: string; color?: string }\n\t\t\t\tsuccess?: { background?: string; color?: string }\n\t\t  }",
        "resolved": "string | undefined | { fontFamily?: string | undefined; header?: { background?: string | undefined; color?: string | undefined; } | undefined; body?: { background?: string | undefined; color?: string | undefined; } | undefined; success?: { background?: string | undefined; color?: string | undefined; } | undefined; }",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "cosmetic",
      "reflect": true
    }
  }; }
  static get states() { return {
    "customer": {},
    "orders": {},
    "unpackedKey": {},
    "login": {},
    "t": {}
  }; }
  static get events() { return [{
      "method": "notice",
      "name": "notice",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "complexType": {
        "original": "Notice",
        "resolved": "Notice",
        "references": {
          "Notice": {
            "location": "import",
            "path": "smoothly"
          }
        }
      }
    }]; }
  static get elementRef() { return "element"; }
  static get listeners() { return [{
      "name": "selectionChanged",
      "method": "onSelectionChanged",
      "target": undefined,
      "capture": false,
      "passive": false
    }, {
      "name": "trigger",
      "method": "handleTrigger",
      "target": undefined,
      "capture": false,
      "passive": false
    }]; }
}
