import { isDemo } from "@saasquatch/component-boilerplate";
import { withHooks } from "@saasquatch/stencil-hooks";
import { useEffect, useMemo, useReducer } from "@saasquatch/universal-hooks";
import { Component, h, Prop } from "@stencil/core";
import deepmerge from "deepmerge";
import { GenericTableView, } from "../../tables/GenericTableView";
import { useRequestRerender, useRerenderListener, } from "../../tables/re-render";
import { useChildElements } from "../../tables/useChildElements";
import mockRewardData from "./mockRewardData";
import { tryMethod, useRewardsTable } from "./useRewardsTable";
/**
 * @uiName Reward Table
 * @validParents ["sqm-portal-container","div","sqm-divided-layout","sqm-brand","template","sqm-hero","sqm-tab","sqb-program-section","sqb-conditional-section"]
 * @exampleGroup Rewards
 * @slots [{"name":"", "title":"Table Row"},{"name":"empty", "title":"Empty"},{"name":"loading","title":"Loading"}]
 * @example Reward Table - <sqm-rewards-table per-page="4" prev-label="Prev" more-label="Next" hidden-columns="0" sm-breakpoint="599" md-breakpoint="799" ><sqm-rewards-table-status-column column-title="Status" status-text="{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} PENDING_REVIEW {Pending} PAYOUT_APPROVED {Payout Approved} PROCESSING {Payment Processing} PAYOUT_CANCELLED {Payout Cancelled} PAYOUT_FAILED {Payout Failed} EXPIRED {Expired} REDEEMED {Redeemed} DENIED {Denied} other {Not available} }" expiry-text="Expires on " pending-us-tax="W-9 required" pending-scheduled="Until" pending-unhandled="Fulfillment error" pending-review-text="Awaiting review" denied-text="Detected self-referral" pending-tax-review="Awaiting tax form review." pending-new-tax-form="Invalid tax form. Submit a new form to receive your rewards." pending-tax-submission="Submit your tax documents to receive your rewards." pending-partner-creation="Complete your tax and cash payout setup to receive your rewards." payout-failed="Payout failed due to a fulfillment issue and is currently being retried." payout-cancelled="If you think this is a mistake, contact our Support team." payout-approved="Reward was scheduled for payment based on your settings, barring any account holds." ></sqm-rewards-table-status-column> <sqm-rewards-table-source-column column-title="Source" anonymous-user="Your Friend" deleted-user="Deleted User" reward-exchange-text="Reward Exchange" referral-text="{rewardSource, select, FRIEND_SIGNUP {Referral to} REFERRED {Referred by} other {}}" reward-source-text="{rewardSource, select, MANUAL {Manual} AUTOMATED {{programName}} other {}}" ></sqm-rewards-table-source-column ><sqm-rewards-table-reward-column column-title="Reward" redeemed-text="{redeemedAmount} redeemed" available-text="{availableAmount} remaining" copy-text="Copied!" ></sqm-rewards-table-reward-column ><sqm-rewards-table-date-column column-title="Date received" date-shown="dateGiven" ></sqm-rewards-table-date-column ><sqm-rewards-table-customer-note-column column-title="Note" ></sqm-rewards-table-customer-note-column ><sqm-empty slot="empty" empty-state-image="https://res.cloudinary.com/saasquatch/image/upload/v1644360953/squatch-assets/empty_reward2.png" empty-state-header="View your rewards" empty-state-text="Complete program tasks to view the details of your rewards" ></sqm-empty ></sqm-rewards-table>
 */
export class RewardsTable {
  constructor() {
    /** @uiName Rewards per page */
    this.perPage = 4;
    /** @uiName Hide column labels */
    this.hideLabels = false;
    /** @uiName Previous button text  */
    this.prevLabel = "Prev";
    /** @uiName View more button text  */
    this.moreLabel = "Next";
    /**
     * Provide the column numbers (0 indexed) that should not be displayed in mobile views. Ex. 0,2,3
     *
     *  @uiName Mobile hidden columns  */
    this.hiddenColumns = "0";
    /** @uiName Mobile breakpoint  */
    this.smBreakpoint = 599;
    /** @uiName Tablet breakpoint  */
    this.mdBreakpoint = 799;
    withHooks(this);
  }
  disconnectedCallback() { }
  render() {
    const empty = h(EmptySlot, null);
    const loading = h(LoadingSlot, null);
    const { states, data, callbacks, elements } = isDemo()
      ? useRewardsTableDemo(this, empty, loading)
      : useRewardsTable(this, empty, loading);
    useRequestRerender([this.perPage]);
    return (h(GenericTableView, { states: states, data: data, callbacks: callbacks, elements: elements }));
  }
  static get is() { return "sqm-rewards-table"; }
  static get encapsulation() { return "shadow"; }
  static get properties() { return {
    "programId": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "text": "Program",
            "name": "uiName"
          }, {
            "text": "programSelector",
            "name": "uiWidget"
          }],
        "text": "Filters to only show rewards in this program. Will default to filtering by the program context where\nthis table lives. If no program ID is set or provided by context, then shows all rewards from all programs."
      },
      "attribute": "program-id",
      "reflect": false
    },
    "perPage": {
      "type": "number",
      "mutable": false,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "text": "Rewards per page",
            "name": "uiName"
          }],
        "text": ""
      },
      "attribute": "per-page",
      "reflect": false,
      "defaultValue": "4"
    },
    "hideLabels": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [{
            "text": "Hide column labels",
            "name": "uiName"
          }],
        "text": ""
      },
      "attribute": "hide-labels",
      "reflect": false,
      "defaultValue": "false"
    },
    "prevLabel": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [{
            "text": "Previous button text",
            "name": "uiName"
          }],
        "text": ""
      },
      "attribute": "prev-label",
      "reflect": false,
      "defaultValue": "\"Prev\""
    },
    "moreLabel": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [{
            "text": "View more button text",
            "name": "uiName"
          }],
        "text": ""
      },
      "attribute": "more-label",
      "reflect": false,
      "defaultValue": "\"Next\""
    },
    "hiddenColumns": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [{
            "text": "Mobile hidden columns",
            "name": "uiName"
          }],
        "text": "Provide the column numbers (0 indexed) that should not be displayed in mobile views. Ex. 0,2,3"
      },
      "attribute": "hidden-columns",
      "reflect": false,
      "defaultValue": "\"0\""
    },
    "smBreakpoint": {
      "type": "number",
      "mutable": false,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [{
            "text": "Mobile breakpoint",
            "name": "uiName"
          }],
        "text": ""
      },
      "attribute": "sm-breakpoint",
      "reflect": false,
      "defaultValue": "599"
    },
    "mdBreakpoint": {
      "type": "number",
      "mutable": false,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [{
            "text": "Tablet breakpoint",
            "name": "uiName"
          }],
        "text": ""
      },
      "attribute": "md-breakpoint",
      "reflect": false,
      "defaultValue": "799"
    },
    "demoData": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "DemoData<GenericTableViewProps> & {\n    mockData?: { data: Referral[] };\n  }",
        "resolved": "Partial<Pick<GenericTableViewProps, \"states\" | \"data\" | \"elements\">> & { mockData?: { data: Referral[]; }; }",
        "references": {
          "DemoData": {
            "location": "import",
            "path": "../../global/demo"
          },
          "GenericTableViewProps": {
            "location": "import",
            "path": "../../tables/GenericTableView"
          },
          "Referral": {
            "location": "import",
            "path": "../../saasquatch"
          }
        }
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [{
            "text": undefined,
            "name": "undocumented"
          }, {
            "text": "object",
            "name": "uiType"
          }],
        "text": ""
      }
    }
  }; }
}
function EmptySlot() {
  return (h("slot", { name: "empty" },
    h("sqm-empty", { "empty-state-image": "https://res.cloudinary.com/saasquatch/image/upload/v1644360953/squatch-assets/empty_reward2.png", "empty-state-header": "View your rewards", "empty-state-text": "Refer friends and complete tasks to view the details of your rewards" })));
}
function LoadingSlot() {
  return (h("slot", { name: "loading" },
    h(LoadingRow, null),
    h(LoadingRow, null),
    h(LoadingRow, null),
    h(LoadingRow, null)));
}
function LoadingRow() {
  return (h("sqm-table-row", null,
    h("sqm-table-cell", { colspan: 5 },
      h("sqm-skeleton", null))));
}
function useRewardsTableDemo(props, emptyElement, loadingElement) {
  const [content, setContent] = useReducer((state, next) => ({
    ...state,
    ...next,
  }), {
    columns: [],
    rows: [],
    loading: false,
    page: 0,
  });
  const tick = useRerenderListener();
  const { data } = useMemo(() => { var _a; return ((_a = props.demoData) === null || _a === void 0 ? void 0 : _a.mockData) || mockRewardData(props.perPage); }, [props.perPage]);
  const components = useChildElements();
  async function getComponentData(components) {
    let componentData = data;
    componentData = data.slice(0, props.perPage);
    // filter out loading and empty states from columns array
    const columnComponents = components.filter((component) => {
      var _a, _b;
      return component.slot !== "loading" &&
        component.slot !== "empty" &&
        ((_a = component === null || component === void 0 ? void 0 : component.firstElementChild) === null || _a === void 0 ? void 0 : _a.getAttribute("slot")) !== "loading" &&
        ((_b = component === null || component === void 0 ? void 0 : component.firstElementChild) === null || _b === void 0 ? void 0 : _b.getAttribute("slot")) !== "empty";
    });
    // get the column titles (renderLabel is asynchronous)
    const columnsPromise = columnComponents === null || columnComponents === void 0 ? void 0 : columnComponents.map(async (c, idx) => {
      var _a;
      const slot = (_a = c === null || c === void 0 ? void 0 : c.firstElementChild) === null || _a === void 0 ? void 0 : _a.getAttribute("slot");
      // Custom plop targets
      if (c.tagName === "RAISINS-PLOP-TARGET" &&
        slot !== "loading" &&
        slot !== "empty") {
        c.style.position = "absolute";
        c.setAttribute("slot", "column-" + idx);
        // Replace add text with a simple + button
        const plopTarget = c.firstElementChild.childNodes[1];
        plopTarget.innerHTML = "＋";
        plopTarget.style.lineHeight = "20px";
        return tryMethod(c, () => c.renderLabel(idx));
      }
      return tryMethod(c, () => c.renderLabel());
    });
    // get the column cells (renderCell is asynchronous)
    //@ts-ignore
    const cellsPromise = componentData === null || componentData === void 0 ? void 0 : componentData.map(async (r) => {
      const cellPromise = columnComponents === null || columnComponents === void 0 ? void 0 : columnComponents.map(async (c) => tryMethod(c, () => c.renderCell(r, undefined, {})));
      const cells = (await Promise.all(cellPromise));
      return cells;
    });
    const rows = cellsPromise && (await Promise.all(cellsPromise)).filter((i) => i);
    // @ts-ignore
    setContent({ rows });
    const columns = columnsPromise && (await Promise.all(columnsPromise));
    // Set the content to render and finish loading components
    setContent({ columns, loading: false, page: 0 });
  }
  useEffect(() => {
    setContent({ loading: true });
    data && getComponentData(components);
  }, [data, components, tick]);
  const demoProps = deepmerge({
    states: {
      hasPrev: false,
      hasNext: false,
      loading: false,
      show: "rows",
    },
    callbacks: {
      prevPage: () => console.log("Prev"),
      nextPage: () => console.log("Next"),
    },
    data: {
      textOverrides: {
        showLabels: !props.hideLabels,
        prevLabel: props.prevLabel,
        moreLabel: props.moreLabel,
      },
      referralData: [],
      mdBreakpoint: 799,
      smBreakpoint: 599,
    },
    elements: {
      columns: content.columns,
      rows: content.rows,
      emptyElement,
      loadingElement,
    },
  }, props.demoData || {}, { arrayMerge: (_, a) => a });
  return demoProps;
}
