import { __assign, __awaiter, __generator } from "tslib";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useState } from "react";
import { Box, Title, Text, Textarea, Stack, Group, Space, useMantineTheme, } from "@mantine/core";
import axios from "axios";
import { formatCurrency, slugToSentenceCase } from "../../../utils";
import { Table } from "../../../components";
import { ProductTableSnippet } from "./ProductTableSnippet";
import { FeaturesList } from "../components";
var BASE_URL = "https://dynamic-formly-backend.vercel.app/api/v1/product";
var features = [
    "Advanced Example",
    "CRUD Operations enabled",
    "Customize Table using various options and based on props",
    "Empty State & Loading State",
    "Variants in Filter",
    "Drag & Re-order Rows",
    "Drag & Re-order Columns",
    "Row Details Panel",
    "Column Footer & Aggregations",
];
export var ProductsTable = function () {
    var theme = useMantineTheme();
    var _a = useState([]), productsApiData = _a[0], setProductsApiData = _a[1];
    var _b = useState(false), isLoading = _b[0], setIsLoading = _b[1];
    // product data used in edit row
    var _c = useState({}), productData = _c[0], setProductData = _c[1];
    var categoryList = Array.from(new Set(productsApiData.map(function (p) { return slugToSentenceCase(p.category); })));
    var fetchProductsApi = useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
        var data, products, success;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    setIsLoading(true);
                    return [4 /*yield*/, axios.get("".concat(BASE_URL, "/"))];
                case 1:
                    data = (_a.sent()).data;
                    products = data.data;
                    return [4 /*yield*/, new Promise(function (resolve) {
                            return setTimeout(function () {
                                setProductsApiData(products);
                                resolve(true);
                            }, 2000);
                        })];
                case 2:
                    success = _a.sent();
                    if (success) {
                        setIsLoading(false);
                    }
                    return [2 /*return*/];
            }
        });
    }); }, []);
    var updatedProductApi = useCallback(function (payload) { return __awaiter(void 0, void 0, void 0, function () {
        var data;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, axios.post("".concat(BASE_URL, "/update"), __assign({ id: payload.id }, payload))];
                case 1:
                    data = (_a.sent()).data;
                    fetchProductsApi();
                    if (data) {
                        return [2 /*return*/, true];
                    }
                    return [2 /*return*/, false];
            }
        });
    }); }, [fetchProductsApi]);
    var deleteProductApi = useCallback(function (values) { return __awaiter(void 0, void 0, void 0, function () {
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, axios.delete("".concat(BASE_URL, "/delete/").concat(values.id))];
                case 1:
                    _a.sent();
                    fetchProductsApi();
                    return [2 /*return*/];
            }
        });
    }); }, [fetchProductsApi]);
    var addProductApi = useCallback(function (values) { return __awaiter(void 0, void 0, void 0, function () {
        var data;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, axios.post("".concat(BASE_URL, "/add"), __assign({ id: productsApiData.length + 1 }, values))];
                case 1:
                    data = (_a.sent()).data;
                    fetchProductsApi();
                    if (data) {
                        return [2 /*return*/, true];
                    }
                    return [2 /*return*/, false];
            }
        });
    }); }, [fetchProductsApi, productsApiData.length]);
    useEffect(function () {
        fetchProductsApi();
    }, [fetchProductsApi]);
    var aggregatedData = useMemo(function () {
        var _a;
        var total = productsApiData.reduce(function (sum, product) { return sum + product.price; }, 0);
        var maxPrice = productsApiData.reduce(function (max, product) { return (product.price > max ? product.price : max); }, 0);
        var minPrice = productsApiData.reduce(function (min, product) { return (product.price < min ? product.price : min); }, 0);
        var avgTotal = productsApiData.reduce(function (avg, product) { return avg + product.rating; }, 0);
        var avgRating = avgTotal / ((_a = productsApiData.length) !== null && _a !== void 0 ? _a : 1);
        return { total: total, maxPrice: maxPrice, minPrice: minPrice, avgRating: avgRating };
    }, [productsApiData]);
    var CustomCellRenderer = useCallback(function (value) { return _jsx(Text, { children: value }); }, []);
    var DescriptionEditComponent = useCallback(function () { return (_jsx(Textarea, { placeholder: "Add description", label: "Description", size: "md", value: productData.description, onChange: function (event) {
            return setProductData(__assign(__assign({}, productData), { description: event.target.value }));
        } })); }, [productData]);
    var AggregatedFooterComponent = useCallback(function () { return (_jsxs(Stack, { children: [_jsxs(Group, { children: ["Total Price:", _jsx(Box, { color: "orange", children: formatCurrency(aggregatedData.total) })] }), _jsxs(Group, { children: ["Max Price:", _jsx(Box, { color: "orange", children: formatCurrency(aggregatedData.maxPrice) })] }), _jsxs(Group, { children: ["Min Price:", _jsx(Box, { color: "orange", children: formatCurrency(aggregatedData.minPrice) })] })] })); }, [aggregatedData.maxPrice, aggregatedData.minPrice, aggregatedData.total]);
    var columns = useMemo(function () { return [
        {
            accessorKey: "title",
            header: "Product Name",
            mantineEditTextInputProps: {
                withAsterisk: true,
            },
            enableClickToCopy: true,
        },
        {
            accessorKey: "brand",
            header: "Brand",
            maxSize: 140,
        },
        {
            accessorKey: "description",
            header: "Description",
            Cell: function (_a) {
                var cell = _a.cell;
                return CustomCellRenderer(cell.getValue().slice(0, 20) + "...");
            },
            Edit: DescriptionEditComponent,
        },
        {
            accessorKey: "price",
            aggregationFn: "sum",
            header: "Price",
            filterVariant: "range-slider",
            mantineFilterRangeSliderProps: {
                showLabelOnHover: true,
                min: Math.min.apply(Math, productsApiData.map(function (product) { return product.price; })),
                max: Math.max.apply(Math, productsApiData.map(function (product) { return product.price; })),
            },
            mantineEditTextInputProps: {
                withAsterisk: true,
            },
            Cell: function (_a) {
                var cell = _a.cell;
                return CustomCellRenderer(formatCurrency(cell.getValue()));
            },
            Footer: AggregatedFooterComponent,
        },
        {
            accessorKey: "rating",
            header: "Rating (out of 5)",
            Footer: function () {
                return CustomCellRenderer("Average Rating: ".concat(aggregatedData.avgRating.toFixed(2)));
            },
        },
        {
            accessorKey: "category",
            header: "Category",
            editVariant: "select",
            mantineEditSelectProps: {
                data: categoryList,
                withAsterisk: true,
            },
            filterVariant: "select",
            mantineFilterSelectProps: {
                data: categoryList,
            },
            Cell: function (_a) {
                var cell = _a.cell;
                return CustomCellRenderer(slugToSentenceCase(cell.getValue()));
            },
        },
    ]; }, [
        DescriptionEditComponent,
        productsApiData,
        AggregatedFooterComponent,
        categoryList,
        CustomCellRenderer,
        aggregatedData.avgRating,
    ]);
    var tableOptions = {
        enableRowActions: true,
        enableRowSelection: true,
        enableColumnActions: true,
        enableExpanding: true,
        enableRowNumbers: true,
        enableColumnDragging: true,
        enableColumnOrdering: true,
        enableColumnResizing: true,
        enableRowDragging: true,
        enableRowOrdering: true,
    };
    return (_jsxs(Box, { mx: 32, children: [_jsx(Title, { order: 2, my: 20, color: theme.colorScheme === "dark"
                    ? theme.colors.blue[3]
                    : theme.colors.blue[7], children: "Products Table" }), _jsx(Title, { order: 4, my: 10, children: "Features" }), _jsx(FeaturesList, { features: features }), _jsx(Table, { columns: columns, data: productsApiData, tableName: "Product", isLoading: isLoading, crudOptions: {
                    tableRowObject: productData,
                    setTableRowObject: setProductData,
                    onCreateRow: addProductApi,
                    onEditSaveRow: updatedProductApi,
                    onDeleteRow: deleteProductApi,
                }, rowActionsPosition: "start", renderDetailPanel: function (row) { return (_jsx(Text, { children: row.description || "No Description Provided... Yet..." })); }, tableOptions: tableOptions }), _jsx(Space, { h: 20 }), _jsx(Title, { order: 4, my: 20, children: "Code Snippet (Products Table)" }), _jsx(ProductTableSnippet, {}), _jsx(Space, { h: 40 })] }));
};
