import API from "../../Utils/API/API";
import ModelAPI from "../../Utils/ModelAPI/ModelAPI";
import PermissionUtil from "../../Utils/Permission";
import User from "../../Utils/User";
import Detail from "../Detail/Detail";
import ErrorMessage from "../ErrorMessage/ErrorMessage";
import Loader, { LoaderType } from "../Loader/Loader";
import { VeryLightGray } from "../../../Types/BrandColors";
import { PermissionHelper } from "../../../Types/Permission";
import React, { useEffect, useState } from "react";
import { useAsyncEffect } from "use-async-effect";
const ModelDetail = (props) => {
    const [fields, setFields] = useState([]);
    const [isLoading, setIsLoading] = useState(true);
    const [error, setError] = useState("");
    const [item, setItem] = useState(null);
    const [onBeforeFetchData, setOnBeforeFetchData] = useState(undefined);
    const getSelectFields = () => {
        const select = {};
        for (const field of props.fields) {
            if (!field.field) {
                continue;
            }
            for (const key of Object.keys(field.field)) {
                select[key] = true;
            }
        }
        for (const field of Object.keys(props.selectMoreFields || {})) {
            const keyofField = field;
            if (typeof field === "string" &&
                field &&
                props.selectMoreFields &&
                props.selectMoreFields[keyofField]) {
                select[keyofField] = props.selectMoreFields[keyofField];
            }
        }
        return select;
    };
    const getRelationSelect = () => {
        const relationSelect = {};
        const model = new props.modelType();
        for (const field of props.fields || []) {
            if (!field.field) {
                continue;
            }
            for (const key of Object.keys(field.field)) {
                if (model.isFileColumn(key)) {
                    relationSelect[key] = {
                        file: true,
                        _id: true,
                        fileType: true,
                        name: true,
                    };
                }
                else if (model.isEntityColumn(key)) {
                    relationSelect[key] = field.field[key];
                }
            }
        }
        return relationSelect;
    };
    const setDetailFields = () => {
        // set fields.
        var _a;
        const userPermissions = PermissionUtil.getAllPermissions();
        const model = new props.modelType();
        const accessControl = model.getColumnAccessControlForAllColumns() || {};
        const fieldsToSet = [];
        for (const field of props.fields) {
            const keys = Object.keys(field.field ? field.field : {});
            if (keys.length > 0) {
                const key = keys[0];
                let fieldPermissions = [];
                fieldPermissions = ((_a = accessControl[key]) === null || _a === void 0 ? void 0 : _a.read) || [];
                const hasPermissions = fieldPermissions &&
                    PermissionHelper.doesPermissionsIntersect(userPermissions, fieldPermissions);
                if (hasPermissions || User.isMasterAdmin()) {
                    fieldsToSet.push(Object.assign(Object.assign({}, field), { key: key, getElement: field.getElement
                            ? (item) => {
                                return field.getElement(item, onBeforeFetchData, fetchItem);
                            }
                            : undefined }));
                }
            }
            else {
                fieldsToSet.push(Object.assign(Object.assign({}, field), { key: null, getElement: field.getElement
                        ? (item) => {
                            return field.getElement(item, onBeforeFetchData, fetchItem);
                        }
                        : undefined }));
            }
        }
        setFields(fieldsToSet);
    };
    useEffect(() => {
        if (props.modelType) {
            setDetailFields();
        }
    }, [onBeforeFetchData, props.modelType]);
    const fetchItem = async () => {
        var _a, _b, _c, _d, _e;
        // get item.
        setIsLoading(true);
        (_a = props.onLoadingChange) === null || _a === void 0 ? void 0 : _a.call(props, true);
        setError("");
        try {
            if (props.onBeforeFetch) {
                const model = await props.onBeforeFetch();
                setOnBeforeFetchData(model);
            }
            const modelAPI = props.modelAPI || ModelAPI;
            const item = await modelAPI.getItem({
                modelType: props.modelType,
                id: props.modelId,
                select: Object.assign(Object.assign({}, getSelectFields()), getRelationSelect()),
            });
            if (!item) {
                setError(`Cannot load ${(((_b = new props.modelType()) === null || _b === void 0 ? void 0 : _b.singularName) || "item").toLowerCase()}. It could be because you don't have enough permissions to read this ${(((_c = new props.modelType()) === null || _c === void 0 ? void 0 : _c.singularName) || "item").toLowerCase()}.`);
            }
            if (props.onItemLoaded && item) {
                props.onItemLoaded(item);
            }
            setItem(item);
        }
        catch (err) {
            setError(API.getFriendlyMessage(err));
            (_d = props.onError) === null || _d === void 0 ? void 0 : _d.call(props, API.getFriendlyMessage(err));
        }
        setIsLoading(false);
        (_e = props.onLoadingChange) === null || _e === void 0 ? void 0 : _e.call(props, false);
    };
    useAsyncEffect(async () => {
        if (props.modelId && props.modelType) {
            await fetchItem();
        }
    }, [props.modelId, props.refresher, props.modelType]);
    if (isLoading) {
        return (React.createElement("div", { className: "row text-center flex justify-center", style: {
                marginTop: "50px",
                marginBottom: "50px",
            } },
            React.createElement(Loader, { loaderType: LoaderType.Bar, color: VeryLightGray, size: 200 })));
    }
    if (error) {
        return (React.createElement("p", { className: "text-center color-light-Gray500", style: {
                marginTop: "50px",
                marginBottom: "50px",
            } },
            error,
            " ",
            React.createElement("br", null),
            " ",
            React.createElement("span", { onClick: async () => {
                    await fetchItem();
                }, className: "underline primary-on-hover" }, "Refresh?")));
    }
    if (!item) {
        return React.createElement(ErrorMessage, { message: "Item not found" });
    }
    return (React.createElement(Detail, { id: props.id, item: item, fields: fields, showDetailsInNumberOfColumns: props.showDetailsInNumberOfColumns }));
};
export default ModelDetail;
//# sourceMappingURL=ModelDetail.js.map