import React, { useContext, useEffect, useMemo } from "react";
import { Table } from "antd";
import { assert } from "oak-domain/es/utils/assert";
import { get } from "oak-domain/es/utils/toolkit";
import { getWidth, getValue, getLabel, getType, getAlign, getLinkUrl, getFixed, isAttributeType, } from "../../utils/usefulFn";
import ActionBtn from "../actionBtn";
import TableCell from "./renderCell";
import { TableContext } from "../listPro";
import Pagination from "../pagination";
export default function Render(props) {
    const { methods, data: oakData } = props;
    const { t, getColor } = methods;
    const { loading, entity, schema, extraActions, data, disabledOp = false, tablePagination, onAction, rowSelection, attributes, i18n, hideHeader, disableSerialNumber, judgeAttributes, size = "large", scroll, empty, opWidth, actionMaxVisibleCount, actionWrap, actionLabelMaxWidth, oakPagination, oakFullpath, } = oakData;
    const { tableAttributes, setSchema } = useContext(TableContext);
    // Recompute columns after locale payload updates.
    const zhCNKeys = i18n?.store?.data?.zh_CN && Object.keys(i18n.store.data.zh_CN).length;
    const selectedRowKeys = rowSelection?.selectedRowKeys || [];
    const showScroll = attributes && attributes.length >= 8;
    const tableScroll = showScroll || scroll
        ? Object.assign({}, showScroll && {
            scrollToFirstRowOnChange: true,
            x: 1200,
        }, scroll)
        : undefined;
    useEffect(() => {
        setSchema && setSchema(schema);
    }, [schema, setSchema]);
    const tableColumns = useMemo(() => {
        if (!schema) {
            return [];
        }
        let showAttributes = judgeAttributes;
        if (tableAttributes) {
            showAttributes = tableAttributes
                .filter((ele) => ele.show)
                .map((ele) => ele.attribute);
        }
        const columns = showAttributes?.map((ele) => {
            if (ele.entity === "notExist") {
                assert(ele.attribute.width, `non-schema attr ${ele.attr} requires width`);
                assert(ele.attribute.type, `non-schema attr ${ele.attr} requires type`);
                assert(ele.attribute.label, `non-schema attr ${ele.attr} requires label`);
            }
            const title = getLabel(ele.attribute, ele.entity, ele.attr, t);
            const width = getWidth(ele.attribute, ele.attrType);
            const type = getType(ele.attribute, ele.attrType);
            const attribute2 = isAttributeType(ele.attribute);
            const align = getAlign(ele.attribute);
            const fixed = getFixed(ele.attribute);
            const column = {
                key: ele.path,
                title,
                align,
                fixed,
                render: (_value, row) => {
                    if (typeof ele.attribute !== "string" &&
                        ele.attribute.render) {
                        return ele.attribute.render(row);
                    }
                    const value = getValue(row, ele.path, ele.entity, ele.attr, ele.attrType, t);
                    const stateValue = get(row, ele.path);
                    let href = "";
                    if ([null, undefined, ""].includes(stateValue)) {
                        return <></>;
                    }
                    const color = getColor(ele.attr, stateValue);
                    if (type === "enum" && !color) {
                        console.warn(color, `${ele.entity} entity ${ele.attr} is missing a color definition`);
                    }
                    if (type === "link") {
                        href = getLinkUrl(ele.attribute, {
                            oakId: row?.id,
                        });
                    }
                    return (<TableCell color={color} value={value} type={type} linkUrl={href}/>);
                },
            };
            if (width) {
                Object.assign(column, { width });
            }
            else {
                Object.assign(column, {
                    ellipsis: {
                        showTitle: false,
                    },
                });
            }
            if (attribute2?.ellipsis) {
                Object.assign(column, {
                    ellipsis: {
                        showTitle: false,
                    },
                });
            }
            return column;
        });
        if (!disableSerialNumber && oakPagination) {
            columns.unshift({
                fixed: "left",
                align: "left",
                title: "#",
                key: "#",
                width: 100,
                render: (_value, row) => row["#"],
            });
        }
        if (!disabledOp) {
            columns.push({
                fixed: "right",
                align: "left",
                title: t("common::operate"),
                key: "operation",
                width: opWidth || 140,
                render: (_value, row) => {
                    const oakActions = row?.["#oakLegalActions"];
                    const extraActions2 = typeof extraActions === "function"
                        ? extraActions(row)
                        : extraActions;
                    return (<ActionBtn entity={entity} extraActions={extraActions2} actions={oakActions} cascadeActions={row?.["#oakLegalCascadeActions"]} onAction={(action, cascadeAction) => onAction &&
                            onAction(row, action, cascadeAction)} actionMaxVisibleCount={actionMaxVisibleCount} actionWrap={actionWrap} actionLabelMaxWidth={actionLabelMaxWidth}/>);
                },
            });
        }
        return columns;
    }, [
        actionLabelMaxWidth,
        actionMaxVisibleCount,
        actionWrap,
        disableSerialNumber,
        disabledOp,
        entity,
        extraActions,
        getColor,
        i18n,
        judgeAttributes,
        oakPagination,
        opWidth,
        onAction,
        schema,
        t,
        tableAttributes,
        zhCNKeys,
    ]);
    return (<>
            <Table rowKey="id" rowSelection={rowSelection?.type && {
            type: rowSelection?.type,
            selectedRowKeys,
            onChange: (nextSelectedRowKeys, row, info) => {
                rowSelection?.onChange &&
                    rowSelection?.onChange(nextSelectedRowKeys, row, info);
            },
        }} size={size} loading={loading} dataSource={!disableSerialNumber && oakPagination
            ? data?.map((ele, index) => {
                const pageSize = oakPagination.pageSize || 20;
                const current = oakPagination.currentPage || 1;
                ele["#"] =
                    pageSize * (current - 1) + (index + 1);
                return ele;
            })
            : data} columns={tableColumns} pagination={false} locale={{ emptyText: empty }} scroll={tableScroll} onRow={(record) => {
            return {
                onClick: () => {
                    const index = selectedRowKeys.findIndex((ele) => ele === record.id);
                    let keys = selectedRowKeys;
                    if (rowSelection?.type === "checkbox") {
                        if (index !== -1) {
                            keys.splice(index, 1);
                        }
                        else {
                            keys.push(record.id);
                        }
                    }
                    else {
                        keys = [record.id];
                    }
                    const rows = data.filter((ele) => keys.includes(ele.id));
                    rowSelection?.onChange &&
                        rowSelection?.onChange(keys, rows, {
                            type: "all",
                        });
                },
            };
        }} showHeader={!hideHeader}></Table>
            {tablePagination ? (tablePagination) : tablePagination !== false && data?.length > 0 ? (<div style={{
                display: "flex",
                flexDirection: "row-reverse",
                alignItems: "center",
                marginTop: 8,
                marginBottom: 8,
            }}>
                    <Pagination oakPath={oakFullpath} entity={entity} oakAutoUnmount={true} showQuickJumper={true}/>
                </div>) : null}
        </>);
}
