class OneDisplayPairing {
  constructor(apiUrl) {
    this.apiUrl = apiUrl;
    this.deviceID = getDeviceID();
    this.screenKey = null;
    this.paired = false;
    this.verifyTimerId = null;

    // Initialize UI elements
    this.initUIElements();
  }

  initUIElements() {
    this.overlayEl = document.getElementById("pairingOverlay");
    if (this.overlayEl) {
      this.disconnectedEl = this.overlayEl.querySelector(".disconnected");
      this.connectedEl = this.overlayEl.querySelector(".connected");
      this.codeEl = this.overlayEl.querySelector(".player-code");
    } else {
      console.warn("Pairing overlay element not found.");
    }
  }

  updatePairingCode() {
    if (this.codeEl) {
      this.codeEl.textContent = this.deviceID;
    }
  }

  showConnectedState() {
    if (this.disconnectedEl) this.disconnectedEl.style.display = "none";
    if (this.connectedEl) this.connectedEl.style.display = "block";
  }

  hideOverlay() {
    if (this.overlayEl) this.overlayEl.style.display = "none";
  }

  async verifyPairing() {
    try {
      const response = await axios.get(`${this.apiUrl}/play/access?uuid=${this.deviceID}`);
      
      if (response.data.success) {
        this.handleSuccessfulPairing(response);
      } else {
        this.showDisconnectedState();
      }
    } catch (error) {
      console.error("Pairing verification failed:", error);
      this.scheduleNextVerification(10000);
    }
  }

  handleSuccessfulPairing(response) {
	  if(typeof response.data.screen !== 'undefined' && typeof response.data.screen.key !== 'undefined') {
		  this.screenKey = response.data.screen.key;
	      localStorage.setItem("screenKey", this.screenKey);
	  }

    
    this.showConnectedState();
    this.clearVerificationTimer();
    this.paired = true;
    
    this.finalizePairing();
  }

  async finalizePairing() {
    try {
      const layoutPlaybackEl = await this.getLayout();

      // if playbackElement is null, create a playback element and append to body
      if (!layoutPlaybackEl) {
        /*const playbackElement = document.createElement("div");
        playbackElement.id = "playback";
        playbackElement.style.position = "absolute";
        playbackElement.style.width = "100%";
        playbackElement.style.height = "100%";
        playbackElement.style.top = "0";
        playbackElement.style.left = "0";
        document.body.appendChild(playbackElement);*/
        this.hideOverlay();
        this.startPlayer(null);
      } else {
        this.hideOverlay();
        this.startPlayer(layoutPlaybackEl);
      }
      
    } catch (error) {
      console.error("Error finalizing pairing:", error);
      this.hideOverlay();
      this.startPlayer(document.getElementById("playback"));
    }
  }

  async getLayout() {
    if (!this.screenKey) return null;
  
    try {
      // First try to get fresh layout from API
      const response = await axios.get(`${this.apiUrl}/display/${this.screenKey}/layout`);
      
      if(typeof response.data.layout !== 'undefined' && response.data.layout !== null) {
        // Cache the new layout
        localStorage.setItem("layoutObject", JSON.stringify({version: response.data.layout.version, layout: response.data.layout.layout}));
        
        window.layoutObject = new OneDisplayLayout(response.data.layout);
        window.layoutObject.renderLayout();
        
        return document.querySelector('.playback') || null;
      }

      if(response.data && typeof response.data.layout === 'undefined') {
        return null;
      }
      
      // If API returns no data, fall through to cached version
    } catch (error) {
      console.error("Error fetching layout:", error);
      // Continue to try cached version
    }
  


    // Fallback to cached layout if available
    const cachedLayout = localStorage.getItem("layoutObject");
    if (cachedLayout) {
      try {
        const parsedLayout = JSON.parse(cachedLayout);
        window.layoutObject = new OneDisplayLayout(parsedLayout);
        window.layoutObject.renderLayout();
        return document.querySelector('.playback') || null;
      } catch (parseError) {
        console.error("Error parsing cached layout:", parseError);
      }
    }
  
    return null;
  }

  scheduleNextVerification(delay) {
    this.clearVerificationTimer();
    this.verifyTimerId = setTimeout(() => this.verifyPairing(), delay);
  }

  clearVerificationTimer() {
    if (this.verifyTimerId) {
      clearTimeout(this.verifyTimerId);
      this.verifyTimerId = null;
    }
  }

  startPlayer(containerElement) {
    try {
      if(containerElement === null) {
        containerElement = document.createElement('div');
        containerElement.id = 'content';
				containerElement.className = 'content';
				document.body.appendChild(containerElement);
        console.log("Starting player!");
        window.playerObject = new OneDisplayPlayer(containerElement, {settings: {playbackType: 'schedule'}});
      }
      this.initDiagnostics();
      this.initStatistics();
    } catch (error) {
      console.error("Error starting player:", error);
    }
  }

  initDiagnostics() {
    window.diagnosticsObject = new OneDisplayDiagnostics(
      this.apiUrl, 
      getDeviceID(), 
      getScreenKey()
    );
    window.diagnosticsObject.runDiagnostics();
  }

  initStatistics() {
    window.statisticsObject = new OneDisplayStatistics(
      this.apiUrl,
      getDeviceID(),
      getScreenKey()
    );
    window.statisticsObject.publishStatistics();
  }

  async start() {
    if (getScreenKey()) {
      this.screenKey = getScreenKey();
      try {
        const playbackElement = await this.getLayout();
        this.startPlayer(playbackElement || document.getElementById("playback"));
        this.hideOverlay();
      } catch (error) {
        console.error("Error starting with stored screenKey:", error);
        this.startPlayer(document.getElementById("playback"));
      }
    } else {
      this.updatePairingCode();
      this.verifyPairing();
    }
  }
}