import { h } from "@stencil/core";
import { Chart, BarController, Colors, BarElement, CategoryScale, LinearScale, Legend, Tooltip, Title, } from "chart.js";
import { ReportsService } from "../../api/services/reports.service";
import { makeGetGrossPaymentChartData } from "../../actions/gross-payment/get-gross-payment-chart-data";
import { ErrorState } from "../../ui-components/details/utils";
import { ComponentErrorCodes, ComponentErrorSeverity } from "../../api/ComponentError";
import JustifiAnalytics from "../../api/Analytics";
import { checkPkgVersion } from "../../utils/check-pkg-version";
import { generateChartOptions } from "./chart-utils";
import Spinner from "../../ui-components/spinner";
import { StyledHost } from "../../ui-components";
Chart.register(Colors, BarController, BarElement, CategoryScale, LinearScale, Legend, Tooltip, Title);
export class JustifiGrossPaymentChart {
    constructor() {
        this.loading = true;
        this.errorMessage = '';
        this.wrapperErrorMessage = null;
    }
    componentWillLoad() {
        checkPkgVersion();
        this.analytics = new JustifiAnalytics(this);
        this.initializeGetGrossPayment();
    }
    componentDidLoad() {
        if (this.getGrossPayment) {
            this.fetchData();
        }
    }
    disconnectedCallback() {
        var _a;
        (_a = this.analytics) === null || _a === void 0 ? void 0 : _a.cleanup();
        if (this.chart) {
            this.chart.destroy();
        }
    }
    authPropChanged() {
        this.initializeGetGrossPayment();
        if (this.getGrossPayment) {
            this.fetchData();
        }
    }
    grossVolumeReportChanged(grossVolumeReport) {
        if (grossVolumeReport) {
            if (!this.chart) {
                this.initChart(grossVolumeReport);
            }
            else {
                this.updateChartData(grossVolumeReport);
            }
        }
    }
    initializeGetGrossPayment() {
        if (this.accountId && this.authToken) {
            this.wrapperErrorMessage = null;
            this.errorMessage = '';
            this.getGrossPayment = makeGetGrossPaymentChartData({
                id: this.accountId,
                authToken: this.authToken,
                service: new ReportsService(),
            });
        }
        else {
            this.getGrossPayment = undefined;
            this.wrapperErrorMessage = 'Account ID and Auth Token are required';
            this.errorEvent.emit({
                errorCode: ComponentErrorCodes.MISSING_PROPS,
                message: this.wrapperErrorMessage,
                severity: ComponentErrorSeverity.ERROR,
            });
        }
    }
    async fetchData() {
        this.loading = true;
        this.getGrossPayment({
            onSuccess: (data) => {
                this.loading = false;
                this.grossVolumeReport = data;
            },
            onError: ({ error, code, severity }) => {
                this.loading = false;
                this.errorMessage = error;
                this.errorEvent.emit({
                    errorCode: code,
                    message: error,
                    severity,
                });
            },
        });
    }
    initChart(grossVolumeReport) {
        const { dates, total } = grossVolumeReport;
        const reversedDates = dates.reverse();
        const endDate = reversedDates[dates.length - 1].date;
        const chartOptions = generateChartOptions(total, reversedDates, endDate);
        this.chart = new Chart(this.chartRef.getContext('2d'), chartOptions);
    }
    updateChartData(grossVolumeReport) {
        const newData = grossVolumeReport.dates.map((date) => date.value);
        this.chart.data.datasets.forEach((dataset) => {
            dataset.data = newData;
        });
        this.chart.update();
    }
    render() {
        if (this.wrapperErrorMessage) {
            return h(StyledHost, null, ErrorState(this.wrapperErrorMessage));
        }
        return (h(StyledHost, null, this.loading && h(Spinner, null), !this.errorMessage ? (h("canvas", { id: "chart", ref: (elem) => (this.chartRef = elem) })) : (ErrorState(this.errorMessage))));
    }
    static get is() { return "justifi-gross-payment-chart"; }
    static get encapsulation() { return "shadow"; }
    static get properties() {
        return {
            "accountId": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "account-id"
            },
            "authToken": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "auth-token"
            }
        };
    }
    static get states() {
        return {
            "getGrossPayment": {},
            "grossVolumeReport": {},
            "loading": {},
            "errorMessage": {},
            "wrapperErrorMessage": {}
        };
    }
    static get events() {
        return [{
                "method": "errorEvent",
                "name": "error-event",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "ComponentErrorEvent",
                    "resolved": "ComponentErrorEvent",
                    "references": {
                        "ComponentErrorEvent": {
                            "location": "import",
                            "path": "../../api/ComponentEvents",
                            "id": "src/api/ComponentEvents.ts::ComponentErrorEvent"
                        }
                    }
                }
            }];
    }
    static get watchers() {
        return [{
                "propName": "accountId",
                "methodName": "authPropChanged"
            }, {
                "propName": "authToken",
                "methodName": "authPropChanged"
            }, {
                "propName": "grossVolumeReport",
                "methodName": "grossVolumeReportChanged"
            }];
    }
}
