<template>
    <q-tabs
        v-model="tab"
        active-color="primary"
        indicator-color="primary"
        align="left"
        no-caps
        dense
    >
        <q-tab name="selection" label="1. Product selection" />
        <q-tab name="Customize" label="2. Markdown customization" />
        <q-tab name="results" label="3. Customization results" />
    </q-tabs>

    <q-tab-panels
        v-model="tab"
        animated
        transition-prev="jump-up"
        transition-next="jump-up"
    >
        <q-tab-panel name="selection">
            <ProductsListView />
        </q-tab-panel>

        <q-tab-panel name="Customize" class="spacing">
            <div
                v-if="store.userRanOptimization"
                class="absolute-full column flex-center bg-opacity-50"
                style="z-index: 1000 !important; backdrop-filter: blur(10px)"
            >
                <div>
                    <q-spinner color="primary" size="50px" />
                </div>
                <div>Optimization ongoing ...</div>
            </div>
            <BsDrawer>
                <div class="tab-title bs-font-medium-4-semi-bold">
                    Products to Customize
                </div>
                <BsExpandableSection
                    header-text="Product"
                    selector-label=""
                    :disabled="!productNames.length"
                ><div>
                    <BsWarning text='Select the product to customize'
                style="max-width: 100%;" class="spacing"></BsWarning>
                    <BsSelect
                        :model-value="selectedProduct"
                        @update:model-value="selectRow"
                        :options="productsOptions"
                        clear-icon="clear"
                        @filter="filterFn"
                        use-input
                        clearable
                        input-debounce="0"
                        :disable="!productNames.length"
                    >
                    </BsSelect>
                </div>

                </BsExpandableSection>
                <BsExpandableSection
                    headerText="Optimized products"
                    selector-label=""
                    :expandable="true"
                    v-if="hasModifiedProducts"
                >
                    <SavedVariable
                        v-for="product in customizedProducts"
                        :title="product.initial.product_id"
                        :strategy="product.current.optimization_strategy"
                        @delete-variable="
                            showDialog(product.initial.product_id)
                        "
                        :key="product.initial.product_id"
                        @click="selectRow(product.initial.product_id)"
                        style="cursor: pointer"
                    ></SavedVariable>
                </BsExpandableSection>
                <div
                    class="flex-column-20"
                    style="padding: 12px"
                    v-if="hasModifiedProducts"
                >
                    <BsWarning
                        text='To save your product customization click on the button "Rerun optimization".'
                        style="max-width: 100%;"
                    ></BsWarning>
                    <BsWarning
                        v-if="store.scenarioRunId"
                        text="Optimization ongoing. Rerun is disabled until optimization run is done. 
                    This may take a while.
                    This message will disappear when the current rerun is finished."
                        warningType="warning"
                        style="max-width: 100%;"
                    ></BsWarning>
                    <div class="button-container">
                        <BsButton
                            class="bs-btn dku-text"
                            unelevated
                            padding="4"
                            @click="runOptimization"
                            :disable="scenarioRunning || store.scenarioRunId"
                            >Rerun optimization</BsButton
                        >
                    </div>
                </div>
            </BsDrawer>
            <div>
                <div
                    v-if="!productNames || !productNames.length"
                    class="flex-column-20"
                >
                    <div class="bs-font-medium-4-semi-bold">
                        No product to customize
                    </div>
                    <BsWarning>
                        <div>
                            If you want to customize product values:
                            <ul
                                style="
                                    margin-top: 0px;
                                    padding-inline-start: 20px;
                                "
                            >
                                <li>
                                    go to "Product selection" and select
                                    products to customize
                                </li>
                                <li>
                                    back here, modify the products
                                    characteristics and constrains before saving
                                    an applying
                                </li>
                            </ul>
                        </div>
                    </BsWarning>
                </div>
                <EmptyState
                    v-else-if="!hasSelectedRow"
                    title="Markdown customization"
                    subtitle="Select a product in the left panel to display the customization options"
                >
                </EmptyState>
                <ProductCustomization
                    @update:info="(msg) => notify(msg.type, msg.message)"
                    v-else
                />
            </div>
        </q-tab-panel>
        <q-tab-panel name="results">
            <CustomizationResults />
        </q-tab-panel>
    </q-tab-panels>
</template>
<script lang="ts">
import ProductCustomization from "../ProductCustomization.vue";
import ProductsListView from "./ProductsListView.vue";
import CustomizationResults from "./CustomizationResults.vue";
import BsExpandableSection from "../BsExpandableSection.vue";
import BsWarning from "../BsWarning.vue";
import SavedVariable from "../SavedVariable.vue";
import DialogComponent from "../DialogComponent.vue";
import EmptyState from "../EmptyState.vue";
import useProductStore from "../../store/ProductStore.js";
import { Dialog } from "quasar";
import { API } from "../../Api";
import { useLocalStorage } from "../composables/use-local-storage";

const finalStatusArray = [
    "FAILED",
    "",
    "ABORTED",
    "SUCCESS",
    "WARNING",
    "Error",
];
export default {
    components: {
        ProductCustomization,
        ProductsListView,
        CustomizationResults,
        BsExpandableSection,
        BsWarning,
        SavedVariable,
        DialogComponent,
        EmptyState,
    },
    setup() {
        const { data: scenarioRunId } = useLocalStorage<string>(
            `${useProductStore().webAppId}.scenarioRunId`
        );
        useProductStore().scenarioRunId = scenarioRunId.value;
        return { scenarioRunId };
    },
    data() {
        return {
            tab: "selection",
            selectedProduct: "",
            updateStatus: "",
            intervalId: undefined as undefined | number,
            productsOptions: [] as string[]
        };
    },

    computed: {
        store() {
            return useProductStore();
        },
        hasSelectedRow() {
            return this.store.hasSelectedRow;
        },
        productNames() {
            return this.store.productNames;
        },
        customizedProducts() {
            return [...this.store.customizedProducts.values()].filter(
                (el: any) => !el.result
            );
        },
        hasModifiedProducts() {
            return this.customizedProducts.length > 0;
        },
        scenarioRunning() {
            return finalStatusArray.indexOf(this.updateStatus) < 0;
        },
    },
    watch: {
        productNames: {
            handler() {
                this.selectedProduct = "";
                this.store.selectRowToCustomize(null);
                this.productsOptions = this.productNames;
            },
            deep: true,
        },
        scenarioRunId(newVal) {
            if (newVal) {
                this.runScenarioStatusCheck();
            } else if (this.intervalId) {
                // no need to run interval anymore, scenario is done
                clearInterval(this.intervalId);
            }
            this.store.scenarioRunId = newVal;
        },
    },

    methods: {
        selectRow(newVal: any) {
            this.selectedProduct = newVal;
            this.store.selectRowToCustomize(this.selectedProduct);
        },
        getLastRunInfo() {
            API.getLastRun()
                .then((resp) => {
                    if (resp.running) {
                        this.updateStatus = "init";
                        this.scenarioRunId = resp.id;
                    }
                })
                .catch((err) => console.log("err:", err));
        },
        filterFn(val: string, update: any) {
            update(() => {
                const needle = val.toLowerCase();
                this.productsOptions = this.productNames.filter(
                    (v) => v.toLowerCase().indexOf(needle) > -1
                );
            });
        },
        runOptimization() {
            this.updateStatus = "init";
            this.store.loading = true;
            API.buildAllUpdate(this.store.customizedRows)
                .then((response: any) => {
                    if (response !== "Error") {
                        this.store.userRanOptimization = true;
                        this.scenarioRunId = response;
                    } else {
                        this.updateStatus = "Error";
                        this.notify(
                            "error",
                            `Failed to run optimization as another optimization is ongoing.`
                        );
                        this.getLastRunInfo();
                    }
                })
                .finally(() => (this.store.loading = false));
        },
        showDialog(productId: string) {
            Dialog.create({
                component: DialogComponent,
                componentProps: {
                    element: productId,
                    title: "Delete saved optimized product",
                },
                persistent: true,
                cancel: true,
                html: true,
            }).onOk(() => {
                this.store.deleteCustomizedRow(productId);
            });
        },
        getResults() {
            this.selectRow(null);
            API.getResults()
                .then((resp) => {
                    const rows = resp.rows;
                    this.store.appendResults(rows);
                    this.store.userRanOptimization = false;
                })
                .catch((err) => console.log("error at results", err));
        },
        runScenarioStatusCheck() {
            this.intervalId = setInterval(this.getScenarioStatus, 30000);
        },
        getScenarioStatus() {
            console.log("Checking", this.scenarioRunId);
            console.log("updateStatus", this.updateStatus);
            if (this.scenarioRunId) {
                API.getScenarioStatus(
                    "MKD11BUILD_ALL_FROM_UPDATE",
                    this.scenarioRunId!
                )
                    .then((response: any) => {
                        this.updateStatus = response;
                        console.log("scenario:", response)
                        if (!this.scenarioRunning) {
                            // Scenario is done
                            this.scenarioRunId = null;
                            if (this.updateStatus === "SUCCESS") {
                                this.getResults();
                                this.notify(
                                    "success",
                                    "Optimization successfully ran"
                                    );
                                } else {
                                    this.notify(
                                        "error",
                                        "Last optimization rerun failed"
                                        );
                                        this.store.userRanOptimization = false;
                                    }
                        }
                    })
                    .catch();
            }
        },
        notify(type: string, message: string) {
            this.$emit("update:info", { type, message });
        },
    },
    created() {
        if (this.scenarioRunId) {
            // Got scenario Id in local storage
            this.updateStatus = "init";
            this.runScenarioStatusCheck();
        }
        this.getResults();
    },
    beforeDestroy() {
        if (this.intervalId) {
            clearInterval(this.intervalId);
        }
    },
};
</script>
<style scoped>
.button {
    border-radius: 8px;
    background-color: #4caf50;
    color: white;
}

.button:hover {
    box-shadow: 0 12px 16px 0 rgba(0, 0, 0, 0.24),
        0 17px 50px 0 rgba(0, 0, 0, 0.19);
}

.spacing {
    margin-bottom: 2rem;
}

.container {
    display: flex;
}

.flex_display {
    display: flex;
    flex-direction: row;
    width: 100%;
}

.flex_column {
    display: flex;
    flex-direction: column;
}

.container_grid {
    display: grid;
    grid-template-columns: 0.4fr 0.3fr 0.3fr;
    grid-column-gap: 10px;
    grid-row-gap: 15px;
}

.card {
    width: 300px;
}

.box {
    width: 320px;
    padding: 10px;
    border-left: 5px solid gray;
    margin: 0;
}

.tooltip_box {
    width: 320px;
    padding: 10px;
    background-color: #d6e1fe;
    border-left: 4px solid #27468e;
    margin: 0;
}
.button-container {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding-right: 10px;
}
</style>
