const { app, BrowserWindow, ipcMain, screen } = require('electron');
const { exec } = require('child_process');
const https = require('https');
const http = require('http');
const path = require('path');

let win;
let lastSong = "";
let lastPaused = true;

app.whenReady().then(() => {
    createWindow();
    checkNowPlaying();
    setInterval(checkNowPlaying, 2500);

    // Start polling for Plex now-playing details
    checkPlexNowPlaying();
    setInterval(checkPlexNowPlaying, 3000);

    // Start an HTTP server to receive notification requests (POST /notify)
    http.createServer((req, res) => {
        if(req.method === 'POST' && req.url === '/notify'){
            let body = '';
            req.on('data', chunk => body += chunk);
            req.on('end', () => {
                try {
                    const notifData = JSON.parse(body);
                    if(win){
                        win.webContents.send('notification', notifData);
                    }
                    res.writeHead(200, {"Content-Type": "application/json"});
                    res.end(JSON.stringify({status:"ok"}));
                } catch(e){
                    console.error("Notification parse error:", e);
                    res.writeHead(400);
                    res.end();
                }
            });
        } else {
            res.writeHead(404);
            res.end();
        }
    }).listen(3000, () => {
        console.log("Notification server listening on port 3000");
    });

    app.on('activate', () => {
        if (BrowserWindow.getAllWindows().length === 0) {
            createWindow();
        }
    });
});

function createWindow() {
    const displays = screen.getAllDisplays();
    const externalDisplay = displays[3] || displays[0];
    const x = externalDisplay.bounds.x;
    const y = externalDisplay.bounds.y;

    win = new BrowserWindow({
        x: x,
        y: y,
        fullscreen: true,
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false,
        }
    });

    win.removeMenu();
    // win.webContents.openDevTools();
    win.loadURL('data:text/html;charset=UTF-8,' + encodeURIComponent(getMainPageHTML()));
    win.on('closed', () => {
        win = null;
    });
}

async function checkNowPlaying() {
    const result = await checkOwnSong();
    if (result.updated && win) {
      win.webContents.send('song-update', result.data);
    }
}

function checkOwnSong() {
    return new Promise((resolve) => {
      exec(`powershell -ExecutionPolicy Bypass -File get-media.ps1`, async (error, stdout) => {
        if (error) {
          console.error("PowerShell error:", error);
          resolve({ updated: false });
          return;
        }
  
        try {
          const data = JSON.parse(stdout);
  
          // If there's NO valid data => user is paused/stopped
          if (!data.title && !data.artist) {
            // If we weren't already paused, now we are => update
            if (!lastPaused) {
              lastPaused = true;
              resolve({
                updated: true,
                data: { paused: true }
              });
            } else {
              // Still paused, no change
              resolve({ updated: false });
            }
          } else {
            // We DO have valid song data => the user is playing something
            const currentSong = `${data.title} - ${data.artist}`;
  
            // If we were paused, or the song changed, send an update
            if (lastPaused || currentSong !== lastSong) {
              lastPaused = false;
              lastSong = currentSong;
  
              const albumArt = await fetchAlbumArt(data.title, data.artist);
              resolve({
                updated: true,
                data: {
                  paused: false,
                  title: data.title,
                  artist: data.artist,
                  albumArt
                }
              });
            } else {
              // No change in paused/playing state, no change in track
              resolve({ updated: false });
            }
          }
        } catch (err) {
          console.error("JSON parse error:", stdout, err);
          resolve({ updated: false });
        }
      });
    });
}

function checkPlexNowPlaying() {
    const plexToken = "kbGwoiA_QEGzw7MgSZrY"; // <-- replace with your Plex token
    const plexHost = "spyro.corp.bbrunson.com";   // <-- adjust if needed
    const url = `http://${plexHost}:32400/status/sessions?X-Plex-Token=${plexToken}`;
    http.get(url, (res) => {
         let data = "";
         res.on('data', chunk => data += chunk);
         res.on('end', () => {
             // For simplicity we check for a known tag in the XML response.
             let nowPlaying = "No media playing";
             if(data.includes("MediaContainer") && data.includes("Video")) {
                nowPlaying = "Plex is playing media";
             }
             if(win){
                win.webContents.send('plex-update', { details: nowPlaying });
             }
         });
    }).on('error', err => {
         console.error("Error fetching Plex now playing:", err);
    });
}

function fetchAlbumArt(title, artist) {
    return new Promise((resolve) => {
        const query = encodeURIComponent(`${artist} ${title}`);
        const url = `https://itunes.apple.com/search?term=${query}&limit=1`;

        https.get(url, (res) => {
            let body = '';
            res.on('data', chunk => (body += chunk));
            res.on('end', () => {
                try {
                    const results = JSON.parse(body).results;
                    if (results.length > 0) {
                        // Replace 100x100 with 300x300 for better quality
                        const art = results[0].artworkUrl100.replace('100x100bb', '300x300bb');
                        resolve(art);
                    } else {
                        resolve("https://via.placeholder.com/100");
                    }
                } catch (e) {
                    console.error("Album art fetch error:", e);
                    resolve("https://via.placeholder.com/100");
                }
            });
        }).on('error', () => {
            resolve("https://via.placeholder.com/100");
        });
    });
}

ipcMain.on('media-control', (event, command) => {
    if (command) {
        exec(`MediaControl.exe ${command}`, (error, stdout, stderr) => {
            if (error) {
                console.error(`Error running MediaControl.exe:`, error);
            } else {
                console.log(`Media command executed: ${stdout || command}`);
            }
        });
    }
});

ipcMain.on('minimize-app', (event) => {
    const window = BrowserWindow.getFocusedWindow();
    if (window) window.minimize();
});  

ipcMain.on('close-app', (event) => {
    win.close();
    // or app.quit();
});

function getMainPageHTML() {
    return `
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Now Playing</title>
        <style>
            body {
                margin: 0;
                padding: 0;
                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                background: #121212;
                color: #ffffff;
                overflow: hidden;
            }
            /* Close and minimize buttons styles... */
            .close-button,
            .minimize-button {
                position: fixed;
                top: 10px;
                background: none;   
                border: none;
                color: #ffffff;
                font-size: 24px;
                cursor: pointer;
                opacity: 0;
                transition: opacity 0.3s ease;
                z-index: 9999;
                pointer-events: auto;
            }
            .minimize-button { right: 50px; }
            .close-button { right: 10px; }
            body:hover .close-button,
            body:hover .minimize-button {
                opacity: 1;
            }
            /* Top bar (Plex or Notification) */
            #plexSection {
                position: fixed;
                top: 0;
                width: 100%;
                background: #333;
                color: #fff;
                padding: 10px;
                text-align: center;
                z-index: 1000;
            }
            /* Container */
            .container {
                position: relative;
                width: 100vw;
                height: 100vh;
            }
            /* Card styles – note the constant translate for centering */
            .card {
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -60%);
                background-color: #1e1e1e;
                border-radius: 16px;
                padding: 50px 60px;
                box-shadow: 0 10px 30px rgba(0, 0, 0, 0.6);
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                gap: 0;
                min-width: 700px;
                max-width: 900px;
                transition: top 0.3s ease;
            }
            /* New fade animations (only opacity changes) */
            @keyframes fadeOut {
                from { opacity: 1; }
                to   { opacity: 0; }
            }
            @keyframes fadeIn {
                from { opacity: 0; }
                to   { opacity: 1; }
            }
            .fade-out {
                animation: fadeOut 0.3s ease-out forwards;
            }
            .fade-in {
                animation: fadeIn 0.3s ease-out forwards;
            }
            /* Show lyrics state */
            .container.show-lyrics .card {
                top: 20%;
                transform: translate(-50%, -20%);
            }
            /* Info and album art */
            .info {
                display: flex;
                align-items: center;
                gap: 40px;
                transition: transform 0.3s ease;
            }
            body:hover .info { transform: translateY(-20px); }
            .album-art {
                width: 150px;
                height: 150px;
                background: #333;
                border-radius: 12px;
                object-fit: cover;
            }
            .text-info {
                display: flex;
                flex-direction: column;
                justify-content: center;
                text-align: left;
            }
            .title { font-size: 32px; font-weight: bold; margin-bottom: 8px; }
            .artist { font-size: 28px; color: #bbbbbb; }
            /* Controls */
            .controls {
                display: flex;
                gap: 20px;
                opacity: 0;
                pointer-events: none;
                transform: translateY(20px);
                transition: opacity 0.3s ease, transform 0.3s ease;
            }
            body:hover .controls {
                opacity: 1;
                pointer-events: auto;
                transform: translateY(0);
            }
            .controls button {
                background-color: #333;
                border: none;
                color: white;
                padding: 10px 16px;
                font-size: 24px;
                border-radius: 8px;
                cursor: pointer;
                transition: background-color 0.2s ease;
            }
            .controls button:hover { background-color: #555; }
            /* Lyrics */
            .lyrics {
                position: absolute;
                bottom: 100px;
                width: 100%;
                text-align: center;
                font-size: 24px;
                color: #bbbbbb;
                opacity: 0;
                transition: opacity 0.3s ease;
            }
            .container.show-lyrics .lyrics { opacity: 1; }
            /* Arrow button */
            .arrow-button {
                position: absolute;
                bottom: 20px;
                left: 50%;
                transform: translateX(-50%);
                background: none;
                border: none;
                font-size: 36px;
                color: #ffffff;
                cursor: pointer;
                opacity: 0;
                transition: opacity 0.3s ease;
            }
            body:hover .arrow-button { opacity: 0; }
            /* Notification overlay */
            .notification-overlay {
                position: fixed;
                top: 0;
                left: 0;
                width: 100vw;
                height: 100vh;
                background: rgba(0, 0, 0, 0.8);
                display: flex;
                align-items: center;
                justify-content: center;
                flex-direction: column;
                color: #fff;
                text-align: center;
                z-index: 10000;
                opacity: 0;
                transition: opacity 0.5s ease;
                pointer-events: none;
            }
            .notification-overlay.show {
                opacity: 1;
                pointer-events: auto;
            }
        </style>
    </head>
    <body>
        <!-- Top bar for Plex Now Playing or Notification -->
        <div id="plexSection">
            Plex Now Playing: <span id="plexNowPlaying">Loading...</span>
        </div>
        <!-- Fixed minimize and close buttons -->
        <button class="minimize-button" onclick="minimizeApp()">–</button>
        <button class="close-button" onclick="closeApp()">✕</button>
        <div class="container" id="container" style="padding-top: 60px;">
            <div class="card" id="card">
                <div class="info">
                    <img class="album-art" id="albumArt" src="https://via.placeholder.com/150" alt="Album Art">
                    <div class="text-info">
                        <div class="title" id="songTitle">Loading...</div>
                        <div class="artist" id="songArtist"></div>
                    </div>
                </div>
                <div class="controls">
                    <button onclick="sendControl('previous')">⏮</button>
                    <button id="playPauseButton" onclick="sendControl('playpause')">⏯</button>
                    <button onclick="sendControl('next')">⏭</button>
                </div>
            </div>
            <div class="lyrics" id="lyricsLine">
                “Hello, is it me you’re looking for?”
            </div>
            <button class="arrow-button" id="arrowButton" onclick="toggleLyrics()">▲</button>
        </div>
        <div class="notification-overlay" id="notificationOverlay">
            <div class="notification-content">
                <h1 id="notificationTitle"></h1>
                <p id="notificationMessage"></p>
            </div>
        </div>
        <script>
            const { ipcRenderer } = require('electron');
            let notificationActive = false;
            let notificationTimeoutId = null;

            ipcRenderer.on('song-update', (event, data) => {
                const songTitleElem   = document.getElementById('songTitle');
                const songArtistElem  = document.getElementById('songArtist');
                const albumArtElem    = document.getElementById('albumArt');
                const playPauseButton = document.getElementById('playPauseButton');
                const cardElem        = document.getElementById('card');

                if (data.paused) {
                    playPauseButton.textContent = "▶️";
                } else {
                    playPauseButton.textContent = "⏸️";
                    // Start fade-out animation
                    cardElem.classList.remove('fade-in', 'fade-out');
                    cardElem.classList.add('fade-out');

                    cardElem.addEventListener('animationend', function handler(e) {
                        if (e.animationName === 'fadeOut') {
                            // Update the content once fade-out completes
                            songTitleElem.innerText  = data.title  ?? "Unknown Title";
                            songArtistElem.innerText = data.artist ?? "Unknown Artist";
                            albumArtElem.src         = data.albumArt ?? "https://via.placeholder.com/150";

                            // Fade the card in with the new data
                            cardElem.classList.remove('fade-out');
                            cardElem.classList.add('fade-in');
                            cardElem.removeEventListener('animationend', handler);
                        }
                    });
                }
            });

            ipcRenderer.on('notification', (event, data) => {
                const overlay = document.getElementById('notificationOverlay');
                const titleElem = document.getElementById('notificationTitle');
                const messageElem = document.getElementById('notificationMessage');
                
                titleElem.innerText = data.title || "Notification";
                messageElem.innerText = data.message || "";
                overlay.classList.add('show');

                // Hide the overlay after 5 seconds (unchanged)
                setTimeout(() => {
                    overlay.classList.remove('show');
                }, 5000);

                // Show notification on top bar for 60 seconds and reposition card
                const plexSection = document.getElementById('plexSection');
                notificationActive = true;
                plexSection.innerHTML = (data.title || "Notification") + ' - ' + (data.message || "");
                plexSection.style.display = "block";
                // Clear any pre-existing timer for top bar notification
                if (notificationTimeoutId) {
                    clearTimeout(notificationTimeoutId);
                }
                notificationTimeoutId = setTimeout(() => {
                    plexSection.style.display = "none";
                    notificationActive = false;

                    // Re-position the card in the middle of the screen
                    const cardElem = document.getElementById('card');
                    cardElem.style.top = "50%";
                    cardElem.style.transform = "translate(-50%, -60%)";
                }, 60000);
            });

            // Prevent plex updates while a notification is actively displayed on the top bar
            ipcRenderer.on('plex-update', (event, data) => {
                if(!notificationActive){
                    const plexElem = document.getElementById('plexNowPlaying');
                    plexElem.textContent = data.details;
                }
            });

            function sendControl(command) {
                ipcRenderer.send('media-control', command);
            }

            function closeApp() {
                ipcRenderer.send('close-app');
            }

            function minimizeApp() {
                ipcRenderer.send('minimize-app');
            }

            function toggleLyrics() {
                const container = document.getElementById('container');
                const arrowBtn = document.getElementById('arrowButton');
                container.classList.toggle('show-lyrics');
                arrowBtn.textContent = container.classList.contains('show-lyrics') ? '▼' : '▲';
            }
        </script>
    </body>
    </html>
    `;
}
