import { Component, Element, Event, h, Host, Listen, Method, Prop, State, Watch } from "@stencil/core";
import { client, Error } from "gracely";
import { Locale } from "isoly";
import { Identifier } from "authly";
import "smoothly";
import { Notice, Trigger } from "smoothly";
import { Customer, ErrorMessage } from "@payfunc/model";
import { VerificationError } from "../card-input/VerificationError";
import * as translation from "./translation";
export class OnboardForm {
  constructor() {
    this.processing = false;
  }
  async componentWillLoad() {
    this.t = translation.create(this.hostElement);
    this.errorMessage = ErrorMessage.create("customer", this.hostElement);
    this.id = Identifier.generate(16);
  }
  onUpdatedNotice(startProcessing) {
    if (this.responseTimer) {
      window.clearTimeout(this.responseTimer);
      this.responseTimer = undefined;
    }
    if (startProcessing) {
      this.responseTimer = window.setTimeout(() => {
        if (this.processing) {
          console.log("Max server response time reached.");
          this.notice.emit(Notice.failed(this.t("No response from payment server within time limit, please try again later.")));
          this.processing = false;
        }
        if (this.responseTimer) {
          window.clearTimeout(this.responseTimer);
          this.responseTimer = undefined;
        }
      }, 30000);
    }
  }
  TriggerListener(event) {
    if (Trigger.is(event.detail) && (event.detail.name == "cardTokenFailed" || event.detail.name == "fail")) {
      if (VerificationError.is(event.detail.value)) {
        if (this.responseTimer) {
          window.clearTimeout(this.responseTimer);
          this.responseTimer = undefined;
        }
      }
      else {
        const message = this.errorMessage.generate(event);
        if (message && message != this.errorMessage.unknown)
          this.notice.emit(Notice.failed(message));
      }
    }
  }
  findInputFields(event) {
    const entries = Object.entries(event.detail);
    const email = entries.find(k => k[0].match(/email/gi));
    const phone = entries.find(k => k[0].match(/phone/gi));
    const name = entries.find(k => k[0].match(/name/gi));
    this.email = email && email[1] != "" ? email[1] : undefined;
    this.phone = phone && phone[1] != "" ? phone[1] : undefined;
    this.name = name && name[1] != "" ? name[1] : undefined;
  }
  async submit(event) {
    this.processing = true;
    this.findInputFields(event);
    const result = await this.submitHelper();
    this.processing = false;
    return result;
  }
  async submitHelper(error) {
    var _a, _b, _c, _d;
    let result;
    const card = await this.element.submit(this.card, error);
    let message;
    if (Error.is(card)) {
      message = this.errorMessage.generate(card);
      result = card;
    }
    else if (!card)
      result = undefined;
    else if (!this.merchant) {
      message = "Unauthorized merchant, contact your merchant.";
      result = client.unauthorized();
    }
    else {
      this.card = card;
      const creatable = {
        id: this.id,
        number: this.number,
        method: [{ card: this.card, type: "token", client: this.getClientData() }],
        contact: {
          name: this.name,
          email: this.email,
          phone: this.phone,
        },
      };
      const response = await fetch(this.merchant.iss +
        "/customer" +
        (((_a = this.customer) === null || _a === void 0 ? void 0 : _a.id) ? "/" + (((_b = this.merchant) === null || _b === void 0 ? void 0 : _b.aud) == "customer" ? "me" : (_c = this.customer) === null || _c === void 0 ? void 0 : _c.id) + "/method" : ""), {
        method: "POST",
        headers: {
          "Content-Type": "application/json; charset=utf-8",
          Authorization: `Bearer ${this.apiKey}`,
        },
        body: JSON.stringify(((_d = this.customer) === null || _d === void 0 ? void 0 : _d.id) ? { card: this.card, type: "token", client: this.getClientData() } : creatable),
      });
      let body = await response.json();
      if (Customer.Method.is(body) && this.customer) {
        this.customer.method.push(body);
        body = this.customer;
      }
      if (VerificationError.is(body))
        result = await this.submitHelper(body);
      else if (Error.is(body)) {
        message = this.errorMessage.generate(body);
        result = body;
      }
      else if (!Customer.is(body)) {
        message = "Unexpected problem occurred; customer couldn't be verified.";
        result = client.invalidContent("Unexpected problem occurred", "customer couldn't be verified");
      }
      else {
        if (!this.createCustomer.emit(body).defaultPrevented)
          this.paymentMethods = body;
        result = body;
      }
    }
    if (Error.is(result) && message)
      this.notice.emit(Notice.failed(message));
    return result;
  }
  getClientData() {
    return {
      browser: {
        colorDepth: screen.colorDepth,
        resolution: [screen.width, screen.height],
        java: navigator.javaEnabled(),
        javascript: true,
        locale: Locale.is(navigator.language) ? navigator.language : "en-GB",
        timezone: new Date().getTimezoneOffset(),
        parent: window.location.origin,
      },
    };
  }
  legacyOutput() {
    var _a;
    return ((_a = this.merchant) === null || _a === void 0 ? void 0 : _a.sub) ? ["BUeG1Dl0", "exZ-5a4T", "6lD8WwPl"].some(id => { var _a; return id == ((_a = this.merchant) === null || _a === void 0 ? void 0 : _a.sub); }) : false;
  }
  componentDidRender() {
    if (this.paymentMethods && this.submitElement) {
      ;
      this.submitElement.submit();
      this.processing = false;
    }
  }
  getCustomCssVariables() {
    var _a, _b, _c, _d;
    const cosmetic = typeof this.cosmetic == "string" ? JSON.parse(this.cosmetic) : this.cosmetic;
    const temp = {
      "--smoothly-primary-color": (_a = cosmetic === null || cosmetic === void 0 ? void 0 : cosmetic.header) === null || _a === void 0 ? void 0 : _a.background,
      "--smoothly-primary-contrast": (_b = cosmetic === null || cosmetic === void 0 ? void 0 : cosmetic.header) === null || _b === void 0 ? void 0 : _b.color,
      "--smoothly-success-color": (_c = cosmetic === null || cosmetic === void 0 ? void 0 : cosmetic.submit) === null || _c === void 0 ? void 0 : _c.background,
      "--smoothly-success-contrast": (_d = cosmetic === null || cosmetic === void 0 ? void 0 : cosmetic.submit) === null || _d === void 0 ? void 0 : _d.color,
      "--smoothly-font-family": cosmetic === null || cosmetic === void 0 ? void 0 : cosmetic.fontFamily,
      "--smoothly-danger-color": cosmetic === null || cosmetic === void 0 ? void 0 : cosmetic.dangerColor,
    };
    const result = {};
    Object.entries(temp).forEach(([key, value]) => {
      value && (result[key] = value);
    });
    return result;
  }
  render() {
    const t = this.t;
    return (h(Host, { style: this.getCustomCssVariables() },
      h("main", null,
        h("header", null,
          h("smoothly-icon", { fill: "solid", name: "checkmark-circle" }),
          h("span", null, t("Card"))),
        h("intergiro-card-input", { cosmetic: this.cosmetic, apiKey: this.apiKey, ref: (element) => (this.element = element) })),
      h("smoothly-submit", { processing: this.processing, disabled: Customer.is(this.paymentMethods), color: "success", prevent: true, expand: "block", onSubmit: (event) => {
          this.submit(event);
          return false;
        }, ref: (element) => (this.submitElement = element) }, t("Submit")),
      this.paymentMethods ? (h("input", { type: "hidden", name: this.legacyOutput() ? "payment-methods" : "customer", value: JSON.stringify(this.paymentMethods) })) : ([])));
  }
  static get is() { return "ig-onboard-form"; }
  static get encapsulation() { return "scoped"; }
  static get originalStyleUrls() { return {
    "$": ["style.scss"]
  }; }
  static get styleUrls() { return {
    "$": ["style.css"]
  }; }
  static get properties() { return {
    "apiKey": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "api-key",
      "reflect": false
    },
    "customer": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "Customer | undefined",
        "resolved": "Customer | undefined",
        "references": {
          "Customer": {
            "location": "import",
            "path": "@payfunc/model"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      }
    },
    "number": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string | undefined",
        "resolved": "string | undefined",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "number",
      "reflect": false
    },
    "merchant": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "Key",
        "resolved": "Key | undefined",
        "references": {
          "Key": {
            "location": "import",
            "path": "@payfunc/model"
          }
        }
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      }
    },
    "responseTimer": {
      "type": "number",
      "mutable": false,
      "complexType": {
        "original": "number",
        "resolved": "number | undefined",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "response-timer",
      "reflect": false
    },
    "cosmetic": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "| string\n\t\t| {\n\t\t\t\theader?: { background?: string; color?: string }\n\t\t\t\ttext?: { background?: string; color?: string }\n\t\t\t\tlineColor?: string\n\t\t\t\tsubmit?: { background?: string; color?: string }\n\t\t\t\tfontFamily?: string\n\t\t\t\tdangerColor?: string\n\t\t  }",
        "resolved": "string | undefined | { header?: { background?: string | undefined; color?: string | undefined; } | undefined; text?: { background?: string | undefined; color?: string | undefined; } | undefined; lineColor?: string | undefined; submit?: { background?: string | undefined; color?: string | undefined; } | undefined; fontFamily?: string | undefined; dangerColor?: string | undefined; }",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "cosmetic",
      "reflect": false
    }
  }; }
  static get states() { return {
    "t": {},
    "errorMessage": {},
    "processing": {},
    "card": {}
  }; }
  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"
          }
        }
      }
    }, {
      "method": "createCustomer",
      "name": "createCustomer",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "complexType": {
        "original": "Customer",
        "resolved": "Customer",
        "references": {
          "Customer": {
            "location": "import",
            "path": "@payfunc/model"
          }
        }
      }
    }]; }
  static get methods() { return {
    "submit": {
      "complexType": {
        "signature": "(event: CustomEvent) => Promise<Customer | Error | undefined>",
        "parameters": [{
            "tags": [],
            "text": ""
          }],
        "references": {
          "Promise": {
            "location": "global"
          },
          "Error": {
            "location": "import",
            "path": "gracely"
          },
          "Customer": {
            "location": "import",
            "path": "@payfunc/model"
          },
          "CustomEvent": {
            "location": "global"
          }
        },
        "return": "Promise<Error | Customer | undefined>"
      },
      "docs": {
        "text": "",
        "tags": []
      }
    }
  }; }
  static get elementRef() { return "hostElement"; }
  static get watchers() { return [{
      "propName": "processing",
      "methodName": "onUpdatedNotice"
    }]; }
  static get listeners() { return [{
      "name": "trigger",
      "method": "TriggerListener",
      "target": undefined,
      "capture": false,
      "passive": false
    }]; }
}
