import { Component, Element, Event, h, Listen, Prop, State } from "@stencil/core";
import * as gracely from "gracely";
import { Date, DateTime } from "isoly";
import * as tidily from "tidily";
import * as authly from "authly";
import { Notice } from "smoothly";
import { Connection, Item, Schedule } from "@payfunc/model";
import * as translation from "./translation";
export class IntergiroSubscriptionCreate {
  constructor() {
    this.frequency = "monthly";
    this.currency = "SEK";
    this.advanced = false;
    this.itemCount = 0;
    this.itemsVisible = false;
    this.items = [];
  }
  componentWillLoad() {
    this.t = translation.create(this.element);
    this.subscriptionNumber = authly.Identifier.generate(4);
    this.calculateSchedule();
  }
  componentDidRender() {
    const divisor = document.getElementById("divisor");
    const start = document.getElementById("start");
    const end = document.getElementById("end");
    const handle = (e) => {
      this.calculateSchedule();
      e.stopPropagation();
      e.preventDefault();
    };
    if (divisor)
      divisor.addEventListener("focusout", handle);
    if (start)
      start.addEventListener("focusout", handle);
    if (end)
      end.addEventListener("focusout", handle);
  }
  submitSubscription(e) {
    const subscription = {
      number: e.detail.number,
      items: this.items.length > 0 ? this.items : tidily.parse(e.detail.price, "price", this.currency),
      currency: this.currency,
      schedule: {
        frequency: this.frequency,
        divisor: e.detail.divisor ? Schedule.extractDivisor(e.detail.divisor) : undefined,
        offset: this.offset ? Schedule.extractOffset(this.offset, this.frequency) : undefined,
      },
      start: Date.is(e.detail.start) ? e.detail.start : undefined,
      end: Date.is(e.detail.end) ? e.detail.end : undefined,
    };
    const idArray = Object.keys(this.customers);
    this.notice.emit(Notice.execute(this.t("Creating subscription..."), async () => {
      let result;
      const response = await Promise.all(idArray.map(id => Connection.post(`customer/${id}/subscription`, subscription)));
      const [succeeded, failed] = response.reduce(([s, f], e) => (gracely.Error.is(e) ? [s, ++f] : [++s, f]), [0, 0]);
      if (succeeded > 0)
        result = [
          true,
          idArray.length > 1
            ? this.t("$0 of $1 subscriptions were created.", succeeded, idArray.length)
            : this.t("Subscription was created."),
        ];
      else
        result = [
          false,
          idArray.length > 1
            ? this.t("Failed to create $0 of $1 subscriptions.", failed, idArray.length)
            : this.t("Failed to create subscription."),
        ];
      return result;
    }));
  }
  calculateSchedule() {
    let divisor, endDate, startDate;
    if (this.advanced) {
      const divisorInput = document.getElementById("divisor");
      divisor = hasValue(divisorInput) ? divisorInput.value : undefined;
    }
    if (document.getElementById("start") && document.getElementById("end")) {
      const start = document.getElementById("start");
      startDate = hasValue(start) && DateTime.localize(start.value) ? start.value : DateTime.now();
      const end = document.getElementById("end");
      endDate = hasValue(end) ? DateTime.localize(end.value) : undefined;
    }
    this.schedule = {
      frequency: this.frequency,
      divisor: divisor ? Schedule.extractDivisor(divisor) : undefined,
      offset: this.offset ? Schedule.extractOffset(this.offset, this.frequency) : undefined,
    };
    this.dueDates = Schedule.calculateDueDates(this.schedule, 5, startDate, endDate);
  }
  onSelectionChanged(e) {
    if (e.detail.identifier == "frequency") {
      this.frequency = e.detail.value;
      this.calculateSchedule();
    }
    if (e.detail.identifier == "currency")
      this.currency = e.detail.value;
  }
  deleteItem(e) {
    const items = [];
    this.price = (Number(this.price) - Item.amount(this.items[e.detail.index])).toFixed(2);
    for (let i = 0; i < this.items.length; i++)
      if (i != e.detail.index)
        items.push(this.items[i]);
    this.items = items;
  }
  changeItem(e) {
    e.preventDefault();
    e.stopPropagation();
    this.items[this.items.length - 1] = e.detail;
    this.price = Item.amount(this.items).toFixed(2);
  }
  changeOffset(e) {
    e.preventDefault();
    e.stopPropagation();
    this.offset = e.detail;
    this.calculateSchedule();
  }
  addItem(e) {
    e.preventDefault();
    e.stopPropagation();
    this.items = [...this.items, {}];
    this.price = Item.amount(this.items).toFixed(2);
    this.itemCount++;
    this.itemsVisible = true;
  }
  render() {
    return [
      h("form", null,
        h("section", null,
          h("smoothly-input", { type: "text", name: "number", value: this.subscriptionNumber }, this.t("Subscription number")),
          h("ig-total-amount", { price: this.price, itemsvisible: this.itemCount > 1, onAddItem: e => this.addItem(e) }),
          h("smoothly-select", { identifier: "frequency", background: "transparent" }, Schedule.frequencies.map(option => (h("option", { value: option, selected: this.frequency == option }, this.t(option))))),
          h("smoothly-trigger", null,
            h("smoothly-icon", { toolTip: this.t("Advanced"), onClick: () => (this.advanced = !this.advanced), name: "arrow-forward-circle-outline", fill: "clear", size: "small", color: "medium", class: this.advanced ? "opened" : "" })),
          h("smoothly-submit", { color: "primary", fill: "clear", prevent: true, onSubmit: (e) => this.submitSubscription(e) },
            h("smoothly-icon", { toolTip: this.t("Create subscription"), name: "add-circle", fill: "clear", size: "medium", color: "success" }))),
        this.advanced
          ? [
            h("section", null,
              h("ig-select-offset", { frequency: this.frequency, onOffsetChanged: e => this.changeOffset(e) }),
              h("smoothly-input", { type: "divisor", id: "divisor", name: "divisor", value: "0 / 1" }, this.t("Divisor"))),
          ]
          : [],
        h("main", null,
          h("content", null,
            h("section", null,
              h("smoothly-input", { type: "date", name: "start", id: "start", value: DateTime.localize(DateTime.parse(DateTime.now())).slice(0, 10) }, this.t("Start date")),
              h("smoothly-input", { type: "date", name: "end", id: "end" }, this.t("End date"))),
            h("ig-item-list", { items: this.items.slice(0, this.items.length - 1), currency: this.currency }),
            this.itemsVisible ? h("ig-item-input", { key: this.itemCount, item: {} }) : []),
          h("ig-future-due-dates", { dates: this.dueDates }))),
    ];
  }
  static get is() { return "ig-subscription-create"; }
  static get encapsulation() { return "scoped"; }
  static get originalStyleUrls() { return {
    "$": ["style.css"]
  }; }
  static get styleUrls() { return {
    "$": ["style.css"]
  }; }
  static get properties() { return {
    "customers": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "{ [id: string]: Customer | undefined }",
        "resolved": "{ [id: string]: Customer | undefined; }",
        "references": {
          "Customer": {
            "location": "import",
            "path": "@payfunc/model"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      }
    }
  }; }
  static get states() { return {
    "t": {},
    "frequency": {},
    "currency": {},
    "offset": {},
    "schedule": {},
    "dueDates": {},
    "advanced": {},
    "itemCount": {},
    "itemsVisible": {},
    "price": {},
    "items": {}
  }; }
  static get events() { return [{
      "method": "notice",
      "name": "notice",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "complexType": {
        "original": "any",
        "resolved": "any",
        "references": {}
      }
    }]; }
  static get elementRef() { return "element"; }
  static get listeners() { return [{
      "name": "selectionChanged",
      "method": "onSelectionChanged",
      "target": undefined,
      "capture": false,
      "passive": false
    }, {
      "name": "itemDeleted",
      "method": "deleteItem",
      "target": undefined,
      "capture": false,
      "passive": false
    }, {
      "name": "itemChanged",
      "method": "changeItem",
      "target": undefined,
      "capture": false,
      "passive": false
    }, {
      "name": "offsetChanged",
      "method": "changeOffset",
      "target": undefined,
      "capture": false,
      "passive": false
    }]; }
}
function hasValue(element) {
  return typeof element.value === "string";
}
