class OneDisplayDiagnostics {
    constructor(apiUrl, deviceId, screenKey) {
        this.apiUrl = apiUrl;
        this.deviceId = deviceId;
        this.screenKey = screenKey;
        this.diagnostics = {};

        this.timers = {
            showMemoryTimer: null,
            showDiskTimer: null,
            showVersionTimer: null,
            publishDiagnosticsTimer: null,
            captureScreenTimer: null
        }
    }

    /**
     * Checks if the environment is Tizen.
     */
    isTizen() {
        return typeof window.tizen !== "undefined";
    }

    /**
     * Fetches a system property value from Tizen.
     * @param {string} type - The system property type.
     * @returns {Promise<any>} - A Promise resolving to the property value.
     */
    getPropertyValue(type) {
        return new Promise((resolve, reject) => {
            if (this.isTizen()) {
                window.tizen.systeminfo.getPropertyValue(type, resolve, reject);
            } else {
                reject(new Error("Tizen not detected"));
            }
        });
    }

    async captureScreen() {
        //const preview = document.getElementById('preview'); // Ensure this element exists
    
        if (this.isTizen()) {
            const onSuccess = (val) => {
                preview.innerHTML = '<img id="screenshot" src="' + val + '?r=' + Math.random() + '">';
                const screenshot = document.getElementById('screenshot');
                blobUtil.imgSrcToBlob(screenshot.src).then((blob) => {
                    this.uploadScreenshot(blob);
                });
            };
    
            const onError = (error) => {
                console.error("[getScreenCapture] code :" + error.code + " error name: " + error.name + "  message " + error.message);
            };
    
            b2bcontrol.captureScreen(onSuccess, onError);
        } else {
            console.log("Capture web screenshot");
    
            try {
                const canvas = await html2canvas(document.body); // You can change this selector
                const dataUrl = canvas.toDataURL("image/png");
                preview.innerHTML = `<img id="screenshot" src="${dataUrl}">`;
    
                const blob = await (await fetch(dataUrl)).blob();
                this.uploadScreenshot(blob);
            } catch (error) {
                console.error("Error capturing screenshot:", error);
            }
        }
    
        // Loop capture every 30 seconds
        this.timers.captureScreenTimer = setTimeout(() => {
            this.captureScreen();
        }, 30000);
    }
/*
    async captureScreen() {
        if(this.isTizen()) {
            const onSuccess = (val) => {
                preview.innerHTML = '<img id="screenshot" src="' + val + '?r=' + Math.random() + '">';
                var screenshot = document.getElementById('screenshot');
                blobUtil.imgSrcToBlob(screenshot.src).then((blob) => {
                    this.uploadScreenshot(blob)
                });
                //console.log("[getScreenCapture]success to call asyncFunction: " + val);
            };
    
            const onError = (error) => {
                console.error("[getScreenCapture] code :" + error.code + " error name: " + error.name + "  message " + error.message);
            };
    
            b2bcontrol.captureScreen(onSuccess, onError);
        }
        if (!this.isTizen()) {
            console.log("Capture web screenshot");
            //console.warn("Screenshot collection skipped: Not running on Tizen.");
            return;
        }

        

        this.timers.captureScreenTimer = setTimeout(() => {
            this.captureScreen();
        }, 30000);
    }*/

    async uploadScreenshot(blob) {
        const formData = new FormData();
        formData.append("screenshot", blob, "screenshot.png");
        const url = `${this.apiUrl}/screenshot/${this.deviceId}${this.screenKey ? `/${this.screenKey}` : ""}?type=${this.isTizen() ? 'tizen' : 'web'}`;
        const response = await axios({ url: url, method: 'post', data: formData, headers: { "Content-Type": "multipart/form-data" } });
    }


    async showMemoryUsage() {
        if (!this.isTizen()) {
            return;
        }

        try {
            let memTotal = tizen.systeminfo.getTotalMemory();
            let memAvailable = tizen.systeminfo.getAvailableMemory();
            if (document.getElementById('debug-ram') !== null) {
                document.getElementById('debug-ram').innerHTML = "RAM: " + ((memTotal - memAvailable) / 1024 / 1024).toFixed(2) + "MB / " + (((memTotal - memAvailable) / memTotal) * 100).toFixed(2) + "%";
            }
            ////console.log("Used memory: " + ( (memTotal-memAvailable) / 1024 / 1024).toFixed(2) + "MB / " + (((memTotal - memAvailable) / memTotal) * 100).toFixed(2) + "%" );

            this.timers.showMemoryTimer = setTimeout(() => {
                this.showMemoryUsage();
            }, 10000);
        } catch (err) {

        }
    }

    async showVersionNumber() {
        if (document.getElementById('debug-version') !== null) {
            document.getElementById('debug-version').innerHTML = "Ver: " + playerVersion;
        }

        this.timers.showVersionTimer = setTimeout(() => {
            this.showVersionNumber();
        }, 60000);
    }

    async showDiskUsage() {
        if (!this.isTizen()) {
            //console.warn("Diagnostics collection skipped: Not running on Tizen.");
            return;
        }

        try {

            tizen.systeminfo.getPropertyValue("STORAGE", function (storages) {
                storages.units.forEach((disk) => {
                    if (disk.type == 'INTERNAL') {
                        var totalSpace = disk.capacity;
                        var availableSpace = disk.availableCapacity;
                        var usedSpace = totalSpace - availableSpace;

                        // Convert total and used space from bytes to MB
                        var totalSpaceMB = totalSpace / (1024 * 1024); // MB
                        var usedSpaceMB = usedSpace / (1024 * 1024); // MB

                        // Calculate the percentage of used space
                        var usedPercentage = (usedSpace / totalSpace) * 100;

                        // Update the content of the div with disk information
                        let diskElement = document.getElementById('debug-disk');
                        if (diskElement) {
                            diskElement.innerHTML = "DISK: " + usedSpaceMB.toFixed(2) + "MB / " + usedPercentage.toFixed(2) + "%";
                        }
                    }
                });
                // Get total disk space in bytes and used space in bytes

            }, function (error) {
                console.log("Could not get disk usage", error);
            });


            this.timers.showDiskTimer = setTimeout(() => {
                this.showDiskUsage();
            }, 60000);
        } catch (err) {
            console.log("Not getting disk", err);
        }
    }

    async getTizenDiagnostics() {
        if (!this.isTizen()) {
            //console.warn("Diagnostics collection skipped: Not running on Tizen.");
            return;
        }

        try {
            let self = this;
            // Fetch system information properties
            const buildInfo = await this.getPropertyValue("BUILD");
            this.diagnostics.deviceTime = new Date().toLocaleString();
            this.diagnostics.runningFirmware = webapis.productinfo.getFirmware();
            this.diagnostics.firmwareVersion = buildInfo.buildVersion;
            this.diagnostics.model = buildInfo.model;
            this.diagnostics.manufacturer = buildInfo.manufacturer;
            this.diagnostics.playerVersion = playerVersion;

            const cpuInfo = await this.getPropertyValue("CPU");
            this.diagnostics.cpuLoad = cpuInfo.load;

            const localeInfo = await this.getPropertyValue("LOCALE");
            this.diagnostics.locale = localeInfo;
            this.diagnostics.memory = {
                totalBytes: tizen.systeminfo.getTotalMemory(),
                availableBytes: tizen.systeminfo.getAvailableMemory(),
                usedPercentage: (((tizen.systeminfo.getTotalMemory() - tizen.systeminfo.getAvailableMemory()) / tizen.systeminfo.getTotalMemory()) * 100).toFixed(1)
            };
            this.diagnostics.disk = {};
            tizen.systeminfo.getPropertyValue("STORAGE", function (storages) {
                storages.units.forEach((disk) => {
                    if (disk.type == 'INTERNAL') {
                        self.diagnostics.disk.totalBytes = disk.capacity;
                        self.diagnostics.disk.availableBytes = disk.availableCapacity;
                        self.diagnostics.disk.usedPercentage = (((disk.capacity - disk.availableCapacity) / disk.capacity) * 100).toFixed(1);
                    }
                });
            }, function (error) {
                console.log("Could not get disk usage", error);
            });
            
            
            const networkInfo = await this.getPropertyValue("NETWORK");
            this.diagnostics.network = networkInfo;

            const displayInfo = await this.getPropertyValue("DISPLAY");
            this.diagnostics.display = displayInfo;

            const orientationInfo = await this.getPropertyValue("DEVICE_ORIENTATION");
            this.diagnostics.orientation = orientationInfo;

            const ethernetInfo = await this.getPropertyValue("ETHERNET_NETWORK");
            this.diagnostics.ethernet = ethernetInfo;

            const wifiInfo = await this.getPropertyValue("WIFI_NETWORK");
            this.diagnostics.wifi = wifiInfo;

            // Initialize the files array
            this.diagnostics.files = [];

            // Wrap the asynchronous file listing in a Promise
            await new Promise((resolve, reject) => {
                tizen.filesystem.resolve(
                    'downloads',
                    (dirEntry) => {
                        dirEntry.listFiles(
                            (files) => {
                                files.forEach((file) => {
                                    this.diagnostics.files.push(file.name);
                                });
                                resolve();
                            },
                            (error) => {
                                console.error("Error listing files:", error);
                                reject(error);
                            }
                        );
                    },
                    (error) => {
                        console.error("Error resolving downloads directory:", error);
                        reject(error);
                    },
                    "r" // mode: read
                );
            });
            
            const mediaUsage = getStoredValue("mediaUsageObject");
            if (mediaUsage !== null) {
    			try {
    				this.diagnostics.filesUsage = JSON.parse(mediaUsage);
    			} catch(err) {
    				
    			}
    		}
            
        } catch (error) {
            //console.error("Error fetching Tizen diagnostics:", error);
        }
    }

    /**
     * Fetches system properties for non-Tizen devices (regular browsers, desktops, mobile devices).
     */
    async getBrowserDiagnostics() {
        // Detect OS & Browser
        const userAgent = navigator.userAgent;
        const platform = navigator.platform;
        const browserInfo = this.detectBrowser(userAgent);
        const osInfo = this.detectOS(platform, userAgent);

        // Screen & Display Information
        this.diagnostics.screenResolution = `${screen.width}x${screen.height}`;
        this.diagnostics.viewportSize = `${window.innerWidth}x${window.innerHeight}`;
        this.diagnostics.pixelRatio = window.devicePixelRatio;

        // Hardware Information
        this.diagnostics.cpuCores = navigator.hardwareConcurrency || "Unknown";
        this.diagnostics.memory = navigator.deviceMemory ? `${navigator.deviceMemory} GB` : "Unknown";

        // Browser & OS
        this.diagnostics.browser = browserInfo;
        this.diagnostics.os = osInfo;

        // Network
        this.diagnostics.networkType = navigator.connection ? navigator.connection.effectiveType : "Unknown";
        this.diagnostics.onlineStatus = navigator.onLine ? "Online" : "Offline";

        // Battery Status (if available)
        if (navigator.getBattery) {
            const battery = await navigator.getBattery();
            this.diagnostics.batteryLevel = `${Math.round(battery.level * 100)}%`;
            this.diagnostics.charging = battery.charging ? "Charging" : "Not Charging";
        }
    }

    /**
     * Helper to detect browser name and version.
     */
    detectBrowser(userAgent) {
        if (userAgent.includes("Firefox")) return "Mozilla Firefox";
        if (userAgent.includes("Edg")) return "Microsoft Edge";
        if (userAgent.includes("Chrome")) return "Google Chrome";
        if (userAgent.includes("Safari")) return "Apple Safari";
        if (userAgent.includes("Opera") || userAgent.includes("OPR")) return "Opera";
        return "Unknown";
    }

    /**
     * Helper to detect the OS based on platform and user agent.
     */
    detectOS(platform, userAgent) {
        if (/Windows/i.test(platform)) return "Windows";
        if (/Mac/i.test(platform)) return "MacOS";
        if (/Linux/i.test(platform)) return "Linux";
        if (/iPhone|iPad|iPod/i.test(userAgent)) return "iOS";
        if (/Android/i.test(userAgent)) return "Android";
        return "Unknown";
    }

    /**
     * Run diagnostics collection and sending.
     */
    async collectDiagnostics() {
        if (this.isTizen()) {
            await this.getTizenDiagnostics();
        } else {
            await this.getBrowserDiagnostics();
        }

        await this.sendDiagnostics();
        setTimeout(() => {
            this.collectDiagnostics();
        }, 60000);
    }


    /**
     * Sends collected diagnostics data to the server.
     */
    async sendDiagnostics() {
        try {
            const url = `${this.apiUrl}/diagnostics/${this.deviceId}${this.screenKey ? `/${this.screenKey}` : ""}`;
            const response = await axios.post(url, { diagnostics: this.diagnostics });
        } catch (error) {

        }
    }

    /**
     * Collects and sends diagnostics data.
     */
    async runDiagnostics() {
        await this.collectDiagnostics();
        await this.captureScreen();
    }

    async showDiagnostics() {
        this.showVersionNumber();
        this.showMemoryUsage();
        this.showDiskUsage();
    }

    async stopShowDiagnostics() {
        clearTimeout(this.timers.showVersionTimer);
        this.timers.showVersionTimer = null;

        clearTimeout(this.timers.showMemoryTimer);
        this.timers.showMemoryTimer = null;

        clearTimeout(this.timers.showDiskTimer);
        this.timers.showDiskTimer = null;
    }

    async stopDiagnostics() {

    }
}