class RealtimeTableComponent {
    render(container, component, width, height, configs) {
        this.container = container;
        this.component = component;

        this.factorData = {};
        this.devices = [];
        this.deviceState = {};

        this.container.style.overflow = "hidden";

        for (const config of configs) {
            this.updateConfigWithoutSet(config);
        }

        this.renderTable();
    }

    resize(width, height) {

    }

    updateConfig(config) {
        this.updateConfigWithoutSet(config);

        this.renderTable();
    }
    updateConfigWithoutSet(config) {
        switch (config.k) {
            case "showHead":
                this.showHead = config.v === "1";
                break;
            case "showDataTime":
                this.showDataTime = config.v === "1";
                break;
            case "showUnit":
                this.showUnit = config.v === "1";
                break;
            case "factors":
                this.factors = config.v.split(",");
                break;
            case "showDeviceName":
                this.showDeviceName = config.v === "1";
                break;
            case "dateTimeFormat":
                this.dateTimeFormat = config.v;
                break;
            case "fontSize":
                this.fontSize = config.v;
                break;
            case "normalTextColor":
                this.normalTextColor = config.v;
                break;
            case "importantTextColor":
                this.importantTextColor = config.v;
                break;
            case "itemBackground":
                this.itemBackground = config.v;
                break;
            case "titleDividerColor":
                this.titleDividerColor = config.v;
                break;
            case "titleText":
                this.titleText = config.v;
                break;
        }
    }

    updateTableData(key, value, devices) {
        this.factorData[key] = { value: value, time: new Date() };
        this.devices = devices;

        this.renderTable();
    }
    updateDeviceState(device, state) {
        this.deviceState[device] = state;

        this.renderTable();
    }

    renderTable() {
        let w1 = 180, w2 = 100, w3 = 150;
        if (Number(this.fontSize) >= 28) {
            w1 = 240;
            w2 = 150;
            w3 = 250;
        }
        else if (Number(this.fontSize) >= 24) {
            w1 = 210;
            w2 = 130;
            w3 = 210;
        }
        else if (Number(this.fontSize) >= 21) {
            w1 = 200;
            w2 = 120;
            w3 = 180;
        }

        const titleTexts = this.titleText.split("|");

        let str = "";
        if (this.showHead) {
            str += `<div style='display:flex;border-bottom:1px solid ${this.titleDividerColor};color:${this.normalTextColor};padding:8px 0;margin-bottom:4px;font-size:${this.fontSize}px;'>`;
            str += `<div style='width:${w1}px;padding-left:15px;'>${titleTexts[0]}</div>`;
            str += `<div style='width:${w2}px'>${titleTexts[1]}</div>`;
            if (this.showUnit) {
                str += `<div style='width:${w2}px'>${titleTexts[2]}</div>`;
            }
            if (this.showDataTime) {
                str += `<div style='width:${w3}px'>${titleTexts[3]}</div>`;
            }
            str += "</div>";
        }
        for (const factor of this.factors) {
            const fd = this.factorData[factor];
            if (!fd) {
                continue;
            }

            const dotPos = factor.indexOf('.');
            const deviceName = factor.substring(0, dotPos);
            const devState = this.deviceState[deviceName];
            let value;
            switch (devState) {
                case "LinkError":
                case "NoReply":
                case "DataError":
                case "Unknown":
                    value = "---";
                    break;
                default:
                    value = this.transferValue(factor, fd.value);
                    break;
            }

            str += `<div style='display:flex;background:${this.itemBackground};margin:8px 0;padding:6px 0;font-size:${this.fontSize}px'>`;
            str += `<div style='width:${w1}px;color:${this.importantTextColor};padding-left:15px;'>${this.transferFactorName(factor)}</div>`;
            str += `<div style='width:${w2}px;color:${this.importantTextColor}'>${value}</div>`;
            if (this.showUnit) {
                str += `<div style='width:${w2}px;color:${this.normalTextColor}'>${this.getUnit(factor)}</div>`;
            }
            if (this.showDataTime) {
                str += `<div style='width:${w3}px;color:${this.normalTextColor}'>${this.transferDateTime(fd.time)}</div>`;
            }
            str += "</div>";
        }
        this.container.innerHTML = str;
    }
    transferFactorName(name) {
        if (this.showDeviceName) {
            return name;
        }
        else {
            const pos = name.indexOf('.');
            return name.substring(pos + 1);
        }
    }
    transferValue(key, value) {
        const pos = key.indexOf('.');
        const deviceName = key.substring(0, pos);
        const factorName = key.substring(pos + 1);

        const f = this.devices.find(p => p.Name === deviceName).Factors.find(p => p.Name === factorName);

        if (f.Digit === -1) {
            return value;
        }
        return Number(value).toFixed(f.Digit);
    }
    getUnit(key) {
        const pos = key.indexOf('.');
        const deviceName = key.substring(0, pos);
        const factorName = key.substring(pos + 1);

        const f = this.devices.find(p => p.Name === deviceName).Factors.find(p => p.Name === factorName);

        return f.Unit;
    }
    transferDateTime(time) {
        let str = this.dateTimeFormat.replace("yyyy", this.fixNumber(time.getFullYear(), 4));
        str = str.replace("MM", this.fixNumber(time.getMonth() + 1, 2));
        str = str.replace("dd", this.fixNumber(time.getDate(), 2));
        str = str.replace("HH", this.fixNumber(time.getHours(), 2));
        str = str.replace("mm", this.fixNumber(time.getMinutes(), 2));
        str = str.replace("y", time.getFullYear().toString());
        str = str.replace("M", (time.getMonth() + 1).toString());
        str = str.replace("d", time.getDate().toString());
        str = str.replace("H", time.getHours().toString());
        str = str.replace("m", time.getMinutes().toString());
        return str;
    }
    fixNumber(num, digit) {
        let str = num.toString();
        while (str.length < digit) {
            str = "0" + str;
        }
        return str;
    }
}