class OneDisplayLayout {
    constructor(layout = null) {
      this.screenKey = getScreenKey();
      this.layoutData = layout.layout;
      this.version = layout.version;
      this.layoutId = layout.id;
      this.checkInterval = 10000; // Check every 30 seconds
      this.checkIntervalId = null;
      this.initialize();
    }

    // Here i want to check if the layout version has changed
    async fetchScreenLayout() {
      try {
        const response = await axios.get(`https://api.onedisplay.se/display/${this.screenKey}/layout`);
        if (response.data) {
          if(typeof response.data.layout === 'undefined' && this.version !== null) { 
            this.version = null;
            window.location.reload();
            return;
          }
          if(typeof response.data.layout !== 'undefined' && response.data.layout.id !== this.layoutId) {
            this.version = response.data.layout.version;
            this.layoutId = response.data.layout.id;
            window.location.reload();
            return;
          }
          if(response.data.layout.version !== this.version) {
            this.version = response.data.layout.version;
            window.location.reload();
            return;
          }
        }
      } catch (error) {
        console.error('Error fetching layout:', error);
      }
    }

    async initialize() {
      this.startVersionCheck();
    }

    startVersionCheck() {
      this.checkIntervalId = setInterval(
        () => this.fetchScreenLayout(), 
        this.checkInterval
      );
    }

    renderLayout() {
      const layoutContainer = document.createElement('div');
      layoutContainer.style.width = `${this.layoutData.settings.width}px`;
      layoutContainer.style.height = `${this.layoutData.settings.height}px`;
      layoutContainer.style.position = 'relative';
      
      // Apply background settings
      if (this.layoutData.settings.background) {
        const bg = this.layoutData.settings.background;
        
        switch (bg.type) {
          case 'color':
            layoutContainer.style.background = bg.color || '#ffffff';
            break;
            
          case 'gradient':
            if (bg.gradient) {
              if (bg.gradient.type === 'linear') {
                const colors = bg.gradient.colors
                  .sort((a, b) => a.stop - b.stop)
                  .map(c => `${c.color} ${c.stop}%`)
                  .join(', ');
                layoutContainer.style.background = `linear-gradient(${bg.gradient.angle || 90}deg, ${colors})`;
              } else {
                const colors = bg.gradient.colors
                  .sort((a, b) => a.stop - b.stop)
                  .map(c => `${c.color} ${c.stop}%`)
                  .join(', ');
                layoutContainer.style.background = `radial-gradient(circle, ${colors})`;
              }
            }
            break;
            
          case 'image':
            if (bg.image) {
              layoutContainer.style.backgroundImage = `url('${bg.image}')`;
              layoutContainer.style.backgroundSize = bg.imageSize || 'cover';
              layoutContainer.style.backgroundRepeat = 'no-repeat';
              layoutContainer.style.backgroundPosition = 'center';
            }
            break;
          case 'video':
            if (bg.video) {
              let videoBg = document.createElement('video');
              videoBg.src = bg.video;
              videoBg.style.width = '100%';
              videoBg.style.height = '100%';
              videoBg.autoplay = true;
              videoBg.muted = true;
              videoBg.loop = true;
              layoutContainer.appendChild(videoBg);
            }
            break;
        }
      }
      let countPlaybackAreas = 0;

      this.layoutData.elements.forEach(element => {
        let el;
  
        switch (element.type) {
          case 'playback':
            el = this.createPlaybackElement(element);
            window.playerObject = new OneDisplayPlayer(el, element);
            countPlaybackAreas++;
            break;
          case 'widget':
            el = this.createWidgetElement(element);
            break;
          case 'overlay':
            el = this.createOverlayElement(element);
            break;
          default:
            return;
        }
  
        el.style.position = 'absolute';
        el.style.left = `${element.x}px`;
        el.style.top = `${element.y}px`;
        el.style.width = `${element.width}px`;
        el.style.height = `${element.height}px`;
        el.style.zIndex = element.zIndex;

        layoutContainer.appendChild(el);
      });
      
      window.debugObject.numPlaybackAreas = countPlaybackAreas;
    

      document.body.appendChild(layoutContainer);
    
    }

    getBackgroundColorWithAlpha(rgb, alpha) {
        // Convert hex color (RGB) to RGBA format and return
      const r = parseInt(rgb.slice(1, 3), 16);
      const g = parseInt(rgb.slice(3, 5), 16);
      const b = parseInt(rgb.slice(5, 7), 16);
      const a = alpha / 100;  // Convert opacity to a decimal (0-1 scale)

      return `rgba(${r}, ${g}, ${b}, ${a})`;
    }
  
    createPlaybackElement(element) {
      const playbackElement = document.createElement('div');
      playbackElement.className = 'playback';
      //playbackElement.style.backgroundColor = element.settings.backgroundColor;
      playbackElement.style.backgroundColor = this.getBackgroundColorWithAlpha(element.settings.backgroundColor, element.settings.backgroundColorAlpha);
      playbackElement.style.borderRadius = element.settings.borderRadius + "px";
      playbackElement.innerHTML = ``;
      playbackElement.style.fontFamily = 'Arial, sans-serif'
      playbackElement.style.textAlign = 'center';
      playbackElement.style.display = 'flex';
      playbackElement.style.justifyContent = 'center';
      playbackElement.style.alignItems = 'center';
      if(element.settings.padding !== 0) {
        playbackElement.style.boxSizing = 'border-box';
        playbackElement.style.padding = `${element.settings.padding}px`;
      }
      
      // Add more playback logic, such as embedding videos or a media player
      
      return playbackElement;
    }
  
    createWidgetElement(element) {
      const widgetElement = document.createElement('div');
      widgetElement.className = 'widget';
      
      if(element.settings.widgetType !== 'image' && element.settings.widgetType !== 'video') {
        widgetElement.style.backgroundColor = this.getBackgroundColorWithAlpha(element.settings.backgroundColor, element.settings.backgroundColorAlpha);
      }
      widgetElement.style.borderRadius = element.settings.borderRadius + "px";
      widgetElement.style.padding = `${element.settings.padding}px`;
      widgetElement.style.fontSize = `${element.settings.fontSize}px`;
  
      switch (element.settings.widgetType) {
        case 'date':
          this.renderDateWidget(widgetElement, element);
          break;
        case 'time':
          this.renderTimeWidget(widgetElement, element);
          break;
        case 'text':
          this.renderTextWidget(widgetElement, element);
          break;
        case 'rss':
          this.renderRssWidget(widgetElement, element);
          break;
        case 'finance':
          this.renderFinanceWidget(widgetElement, element);
          break;
        case 'weather':
          this.renderWeatherWidget(widgetElement, element);
          break;
        case 'website':
          this.renderWebsiteWidget(widgetElement, element);
          break;
        case 'video':
          this.renderVideoWidget(widgetElement, element);
          break;
        case 'image':
          this.renderImageWidget(widgetElement, element);
          break;
        default:
          break;
      }
  
      return widgetElement;
    }

    formatDate(date, format) {
      const day = date.getDate() + '';
      const month = (date.getMonth() + 1) + '';
      const year = date.getFullYear();
      const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
      const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
      
      // Add ordinal suffix
      const getOrdinal = (n) => {
        // Handle special cases first (11th, 12th, 13th)
        if (n % 100 >= 11 && n % 100 <= 13) {
          return n + 'th';
        }
        
        // Handle all other cases
        switch (n % 10) {
          case 1: return n + 'st';
          case 2: return n + 'nd';
          case 3: return n + 'rd';
          default: return n + 'th';
        }
      };
    
      const replacements = {
        'YYYY': year,
        'YY': String(year).slice(-2),
        'MMMM': months[date.getMonth()],
        'MMM': months[date.getMonth()].slice(0, 3),
        'MM': month.length < 2 ? '0' + month : month,
        'M': month,
        'DD': day.length < 2 ? '0' + day : day,
        'D': day,
        'Do': getOrdinal(day),
        'dddd': days[date.getDay()],
        'ddd': days[date.getDay()].slice(0, 3),
      };
    
      return format.replace(/(YYYY|MMMM|dddd|MMM|ddd|Do|YY|MM|DD|M|D)/g, match => replacements[match]);
    }

    renderDateWidget(widgetElement, element) {
      // Function to update the date
      const updateDate = () => {
        const currentDate = new Date();
        const format = element.settings.format || 'DD/MM/YYYY'; // Default format
        const formattedDate = this.formatDate(currentDate, format);
        
        widgetElement.innerHTML = formattedDate;
        widgetElement.style.color = (element.settings.theme == 'light') ? '#000000' : '#ffffff';
        widgetElement.style.fontFamily = element.settings.fontFamily || 'Arial, sans-serif';
        widgetElement.style.fontSize = element.settings.fontSize ? `${element.settings.fontSize}px` : '16px';
        widgetElement.style.textAlign = element.settings.align || 'center';
        widgetElement.style.display = 'flex';
        widgetElement.style.justifyContent = 'center';
        widgetElement.style.alignItems = 'center';
        widgetElement.style.padding = `${element.settings.padding || 0}px`;
      };
    
      // Initial update
      updateDate();
    
      // Set interval to update the date every minute
      setInterval(updateDate, 60000);
    }
      
      renderTimeWidget(widgetElement, element) {
        // Function to update the time
        const updateTime = () => {
          const currentTime = this.getCurrentTime(element.settings.showSeconds);
          widgetElement.innerHTML = currentTime;
          widgetElement.style.color = (element.settings.theme == 'light') ? '#000000' : '#ffffff'; //element.settings.color;
          widgetElement.style.fontFamily = 'Arial, sans-serif'
          widgetElement.style.textAlign = 'center';
          widgetElement.style.display = 'flex';
          widgetElement.style.justifyContent = 'center';
          widgetElement.style.alignItems = 'center';
          widgetElement.style.padding = `${element.settings.padding}px`;
        };
      
        // Initial update
        updateTime();
      
        // Set interval to update the time every second (1000ms)
        setInterval(updateTime, 1000); // 1000ms = 1 second
      }
      
      
      renderTextWidget(widgetElement, element) {
        
          widgetElement.innerHTML = `<div>${element.settings.content}</div>`;
          //widgetElement.style.color = (element.settings.theme == 'light') ? '#000000' : '#ffffff'; //element.settings.color;
          widgetElement.style.color = element.settings.color;
          widgetElement.style.padding = `${element.settings.padding}px`;

      }

      renderVideoWidget(widgetElement, element) {
        const videoElement = document.createElement('video');
        videoElement.src = element.settings.videoUrl; // assuming source is the path to the PNG
        videoElement.id = `videoWidget-${Math.random().toString(36).substr(2, 9)}`;
        videoElement.style.width = '100%';
        videoElement.style.height = '100%';
        videoElement.style.opacity = element.settings.opacity / 100;
        videoElement.autoplay = true;
        videoElement.muted = true;
        videoElement.loop = true;
        widgetElement.appendChild(videoElement);
      }

      renderImageWidget(widgetElement, element) {
        const imageElement = document.createElement('img');
        imageElement.src = element.settings.imageUrl; // assuming source is the path to the PNG
        imageElement.id = `imageWidget-${Math.random().toString(36).substr(2, 9)}`;
        imageElement.style.width = '100%';
        imageElement.style.height = '100%';
        imageElement.style.objectFit = 'contain';
        imageElement.style.opacity = element.settings.opacity / 100;
        widgetElement.appendChild(imageElement);
      }
  
    createOverlayElement(element) {
      const overlayContainer = document.createElement('div');
      overlayContainer.style = `
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      `;
      const overlayElement = document.createElement('img');
      overlayElement.src = element.settings.imageUrl; // assuming source is the path to the PNG
      overlayElement.className = 'overlay';
      overlayElement.style = `
      width: 100%;
      height: 100%;
      object-fit: contain;
      `;
      overlayContainer.appendChild(overlayElement);
      return overlayContainer;
    }
  
    getCurrentDate() {
      const date = new Date();
      return date.toLocaleDateString();
    }
  
    getCurrentTime(showSeconds) {
      const time = new Date();
      return showSeconds ? time.toLocaleTimeString() : time.toLocaleTimeString().substring(0,5);
    }

    renderWebsiteWidget(widgetElement, element) {
      const websiteWidgetContainer = document.createElement('div');
      websiteWidgetContainer.id = `websiteWidgetContainer-${Math.random().toString(36).substr(2, 9)}`;
      websiteWidgetContainer.style.cssText = `
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
          width: 100%;
          height: 100%;
          overflow: hidden;
          margin: 0;
          padding: 0;
          border-radius: ${element.settings.borderRadius}px;
      `;
  
      const iframe = document.createElement('iframe');
      iframe.style.cssText = `
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          border: none;
          margin: 0;
          padding: 0;
          overflow: hidden;
          border-radius: ${element.settings.borderRadius}px;
      `;
      iframe.src = element.settings.url;
      iframe.setAttribute('frameborder', '0');
      iframe.setAttribute('allowfullscreen', '');
      iframe.setAttribute('allow', 'fullscreen *');
      iframe.setAttribute('scrolling', 'no');
  
      websiteWidgetContainer.appendChild(iframe);
      widgetElement.appendChild(websiteWidgetContainer);
  
      const resizeObserver = new ResizeObserver(() => {
          iframe.style.width = `${widgetElement.offsetWidth}px`;
          iframe.style.height = `${widgetElement.offsetHeight}px`;
      });
      resizeObserver.observe(widgetElement);
  
      let reloadTimeout = null;
      let wasOffline = false;
  
      // More reliable network status check
      const checkNetworkStatus = () => {
          const isOnline = navigator.onLine;
          
          if (!isOnline) {
              wasOffline = true;
              console.log('[WebsiteWidget] Network is offline');
              return;
          }
  
          // Only reload if we were previously offline
          if (wasOffline) {
              console.log('[WebsiteWidget] Network came back online');
              if (reloadTimeout) clearTimeout(reloadTimeout);
              
              // Add a delay to ensure network is fully stable
              reloadTimeout = setTimeout(() => {
                  console.log('[WebsiteWidget] Reloading iframe after network recovery');
                  // Force reload by adding timestamp to URL
                  iframe.src = `${element.settings.url}${element.settings.url.includes('?') ? '&' : '?'}_=${Date.now()}`;
                  wasOffline = false;
              }, 5000); // 5 seconds delay
          }
      };
  
      // Multiple ways to detect network changes
      window.addEventListener('online', checkNetworkStatus);
      window.addEventListener('offline', checkNetworkStatus);
      
      // Periodic check as fallback (every 30 seconds)
      const networkCheckInterval = setInterval(checkNetworkStatus, 30000);
  
      // Cleanup function to remove event listeners
      const cleanup = () => {
          window.removeEventListener('online', checkNetworkStatus);
          window.removeEventListener('offline', checkNetworkStatus);
          clearInterval(networkCheckInterval);
          if (reloadTimeout) clearTimeout(reloadTimeout);
          resizeObserver.disconnect();
      };
  
      // Return cleanup function if needed by parent component
      return cleanup;
  }
    
  
    renderRssWidget(widgetElement, element) {
      const rssWidgetContainer = document.createElement('div');
      rssWidgetContainer.id = `rssWidgetContainer-${Math.random().toString(36).substr(2, 9)}`; // Unique ID
  
      // Create the RSS reader for this container
      const RSSReader = new OneDisplayRSS(rssWidgetContainer, {
        url: `https://api.onedisplay.se/rss2json?url=${encodeURIComponent(element.settings.source)}`,
        theme: element.settings.theme,
        timeout: element.settings.rssTimeout
      });
  
      // Start the RSS Reader
      RSSReader.start();
  
      // Append the RSS widget container to the widgetElement
      widgetElement.appendChild(rssWidgetContainer);
    }

    renderFinanceWidget(widgetElement, element) {
      const financeWidgetContainer = document.createElement('div');
      financeWidgetContainer.id = `financeWidgetContainer-${Math.random().toString(36).substr(2, 9)}`; // Unique ID

      // Create the RSS reader for this container
      const FinanceReader = new OneDisplayFinancial(financeWidgetContainer, {
        url: `https://api.onedisplay.se/yahoo2json?symbols=${encodeURIComponent(element.settings.symbols)}`,
        symbols: element.settings.symbols.split(","),
        theme: element.settings.theme,
        marquee: element.settings.marquee,
        marqueeSpeed: 150,
        containerHeight: element.height,
        fontSize: element.settings.fontSize
      });
  
      // Start the RSS Reader
      FinanceReader.start();
  
      // Append the RSS widget container to the widgetElement
      widgetElement.appendChild(financeWidgetContainer);
    }

    renderWeatherWidget(widgetElement, element) {
        const weatherWidgetContainer = document.createElement('div');
        weatherWidgetContainer.id = `weatherWidgetContainer-${Math.random().toString(36).substr(2, 9)}`; // Unique ID
        weatherWidgetContainer.style = 'height: 100%;'

        const weatherWidget = new OneDisplayWeather(weatherWidgetContainer, {
            city: element.settings.searchQuery,
            theme: element.settings.theme, // or 'light'
            units: 'metric', // or 'metric'
            currentWeather: element.settings.currentWeather,
            forecastDays: element.settings.forecastDays,
            showDescription: element.settings.showDescription,
          });
          weatherWidget.start();

          widgetElement.appendChild(weatherWidgetContainer);        
      }
  }
  
