<script lang="ts">
    import { onMount } from "svelte";
    import axios from "axios";

    let username: string = "PLACEHOLDER";

    let dev = true;

    let checkGo = false;

    let showRules = false;

    let start: boolean = false;

    let promptInput: string;

    let locked: boolean = false;

    let shareBoard: boolean = false;
    let sbi: number = 0;
    let shareTarget: string = 'now';
    //let shareBlock: any[] = [];

    let score: number = 0;
    let gameEnding: boolean = false;
    let gameOver: boolean = false;
    let day: number = 100000;

    let fdef: any[] = [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3];
    let cdef: any[] = [3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3];
    let mdef: any[] = [3, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 1, 3];
    let cubeDefault: any[] = [
        [...fdef],
        [...cdef],
        [...cdef],
        [...cdef],
        [...cdef],
        [...mdef],
        [...mdef],
        [...mdef],
        [...mdef],
        [...cdef],
        [...cdef],
        [...cdef],
        [...cdef],
        [...fdef],
    ];

    let cube: any[] = [...cubeDefault];
    let futureCube: any[] = [...cube];

    //let block:any[] = [[0,0,1,0, 0,0,3,0, 1,1,1,1, 0,1,1,1],[0,1,0,0, 1,1,0,0, 1,1,3,1, 1,1,0,0],[1,1,1,0, 1,1,1,1, 0,3,0,0, 0,1,0,0],[0,0,1,1, 1,3,1,1, 0,0,1,1, 0,0,1,0]]
    let blocks: any[] = [
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    ];

    let defBlock: any[] = [
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    ];

    let root: any[] = [7, 7];
    let current: number = 0;

    let block: any[] = [defBlock, defBlock, defBlock, defBlock];

    let rotation: number = 0;

    let colors: any[] = [
        "255,255,0",
        "255,0,255",
        "0,255,255",
        "255,0,0",
        "0,0,255",
        "255,0,255",
        "0,255,0",
        "255,191,0",
        "128,255,0",
        "0,128,255",
        "0,255,128",
        "0,255,64",
        "191,0,255",
        "0,255,192",
        "255,128,128",
        "128,0,255",
        "255,128,0",
        "128,255,255",
    ];

    let sbs: any[] = [];
    let scoreboard = {now: sbs, prev: sbs, hof: sbs };

    export let daily: any[] = Array.from({ length: 25 }, (_, index) => index);

    function makeRot(b: any) {
        let rotated = [];
        for (let col = 0; col < 4; col++) {
            for (let row = 3; row >= 0; row--) {
                //console.log(b);
                rotated.push(b[row * 4 + col]);
            }
        }
        return rotated;
    }

    function genBlock(b: any) {
        let rotations = [b]; // Start with the original block (0-degree rotation)
        let rotated90 = makeRot(b);
        rotations.push(rotated90); // 90-degree rotation
        let rotated180 = makeRot(rotated90);
        rotations.push(rotated180); // 180-degree rotation
        let rotated270 = makeRot(rotated180);
        rotations.push(rotated270); // 270-degree rotation
        //console.log(rotations);
        return rotations;
    }

    async function gameSetup() {
        await axios.get('/api/blocks').then((res) => {
            blocks = res.data.blocks;
            day = res.data.day;
            //console.log(day);
        })
        .catch((error) => {
            if(error.code != 'ERR_INVALID_URL') console.error('Error fetching data:', error);
        });

        let cacheData = localStorage.getItem("gameState");
        let cacheGame = cacheData
            ? JSON.parse(cacheData)
            : {
                  daily: Array.from({ length: 25 }, (_, index) => index),
                  day: 100000,
              };
        if (cacheGame.day == day) {
            //playing = cacheGame.playing; gameOver instead of playing
            cube = cacheGame.cube || cube;
            current = cacheGame.current || 0;
            gameOver = cacheGame.gameOver || false;
            if (gameOver) score = cacheGame.score || 0;
        }
        //console.log(current, blocks[current]);
        block = genBlock(blocks[current]);
    }

    let makeCube = (x: number) => {
        //console.log(x);
        let c = colors[x % 100];
        let a = 1 - x / 1400;
        let val = "background-color: rgba(255, 255, 255, .9)";
        if (x == 3) val = "background-color: rgba(255, 255, 255, .5)";
        if (x > 99) val = `background-color: rgba(${c}, ${a})`;
        return val;
    };

    let onShare = (i: number, x: string) => {
        if(sbi == i && shareTarget == x && shareBoard) {
          shareBoard = false;
        }else{
          sbi = i;
          shareTarget = x;
          shareBoard = true;
          //console.log(sbi, shareTarget);
          //console.log(scoreboard[shareTarget][sbi].cube);
        }
    }

    let onEnter = (pI: string) => {
        username = pI;
        localStorage.setItem("username", username);
        start = true;
    };

    let nudgeY = (n: number) => {
        root[0] = root[0] + n;
        if (root[0] > 10) root[0] = 10;
        if (root[0] < 0) root[0] = 0;
    };

    let nudgeX = (n: number) => {
        root[1] = root[1] + n;
        if (root[1] > 10) root[1] = 10;
        if (root[1] < 0) root[1] = 0;
    };

    let rotate = (n: number) => {
        rotation = rotation + n;
        if (rotation < 0) rotation = 3;
        if (rotation > 3) rotation = 0;
    };

    let place = (n: number) => {
        let checkPlace = true;
        let placeCube: any[] = [];
        if (locked) {
            locked = false;
        } else {
            placeCube = cube.map((row) => [...row]);
            block[rotation].forEach((v: number, i: number) => {
                let x = 0;
                let y = 0;
                if ([4, 5, 6, 7].includes(i)) x = 1;
                if ([1, 5, 9, 13].includes(i)) y = 1;
                if ([8, 9, 10, 11].includes(i)) x = 2;
                if ([2, 6, 10, 14].includes(i)) y = 2;
                if ([12, 13, 14, 15].includes(i)) x = 3;
                if ([3, 7, 11, 15].includes(i)) y = 3;
                let r = root[0] + x;
                let c = root[1] + y;
                if (v != 0) {
                    if (cube[r][c] > 9) checkPlace = false;
                    //console.log(cube[r][c]);
                    placeCube[r][c] = placeCube[r][c] * v * 100 + current;
                    //console.log(futureCube[r][c] * v * 100);
                    //console.log(r,c);
                }
            });
            if (checkPlace) {
                futureCube = placeCube;
                locked = true;
            } else {
                locked = false;
            }
        }
    };

    let commit = (n: number) => {
        locked = false;
        cube = [];
        cube = [...futureCube];
        root = [7, 7];
        current++;
        block = genBlock(blocks[current]);
        let gameState = {
            cube: cube,
            current: current,
            gameOver: gameOver,
            daily: daily,
            score: score,
            day: day,
        };
        localStorage.setItem("gameState", JSON.stringify(gameState));
    };

    let endGame = () => {
        locked = true;
        gameOver = true;
        let total = cube.flat().reduce((acc, num) => acc + num, 0);
        score = total;
        let gameState = {
            cube: cube,
            current: current,
            gameOver: gameOver,
            daily: daily,
            score: score,
            day: day,
        };
        localStorage.setItem("gameState", JSON.stringify(gameState));
        let data = {
            "username": username,
            "count": current,
            "score": score,
            "cube": JSON.stringify(cube),
        }
        axios.post('/api/score', data).then((res) => {
            console.log(res.data);
        })
        .catch((error) => {
            console.error('Error fetching data:', error);
        });
    };

    let reset = () => {
        cube = cubeDefault;
        current = 0;
        gameOver = false;
        score = 0;
        day = 0;


        let gameState = {
            cube: cube,
            current: current,
            gameOver: gameOver,
            daily: daily,
            score: score,
            day: day,
        };
        localStorage.setItem("gameState", JSON.stringify(gameState));
        gameSetup();
    };

    axios.get('/api/scoreboard').then((res) => {
        scoreboard = res.data;
    })
    .catch((error) => {
        if(error.code != 'ERR_INVALID_URL') console.error('Error fetching scoreboard:', error);
    });

    onMount(() => {
        username = localStorage.getItem("username") || "";
        if (username.length > 2) promptInput = username;

        gameSetup();
    });
</script>

<div class="queueb">
    {#if !start}
        <div class="fullscreen-prompt">
            <div class="prompt-content">
                <div class="footer">
                    <img
                        style="height: 1.5em; margin: 1.7em 2px 2px 2px"
                        src="/PBS_LOGO_NT.svg"
                        alt="LOGO"
                    />
                    <h1 class="prompt-text">QueueB Beta</h1>
                </div>

                <p class="prompt-text">
                    Welcome! QueueB is a daily spacial puzzle game. Each day everyone
                    recieves the daily queue of blocks and you must decide
                    where to place them to maximize your score!  Future updates will
                    include an all time top scores chart and a 1 vs 1 challenge mode where
                    you can take turns with a friend competing for the most points on a shared
                    board!
                </p>

                <button
                    class="prompt-input"
                    on:click={() => (showRules = !showRules)}
                >
                    {#if showRules}
                        <p class="prompt-text">
                            Nudge and rotate each block you are given
                            into position.  Once satisfied with a blocks location
                            click Place and then Confirm!  Each square on the blocks
                            you confirm will be added to the board scoring at least
                            100pts. Your blocks cannot be placed on colored squares that you already
                            occupy and placement will be prevented. The dark grey squares
                            on the board multiply your colored block squares by 3x when stacked.
                            Blocks may also have a unique multiplier square which also rewards 3x.
                            When the unique block square is placed on a grey board square, these
                            two multipliers can stack for 9x points!  You must balance
                            maximizing the number of blocks you place on the board with the
                            position of those multiplier squares on both the board and your blocks
                            to get the most points!  Once you can no longer place any blocks click
                            Review Board and then Score Your Game!
                        </p>
                    {:else}
                        <div class="prompt-text">How To Play? Touch Here!</div>
                    {/if}
                </button>

                <h1 class="prompt-text">Your Username</h1>

                <input
                    type="text"
                    maxlength="12"
                    placeholder="INPUT NAME HERE"
                    bind:value={promptInput}
                    class="prompt-input"
                />
                <button
                    disabled={promptInput == undefined ||
                        promptInput.length < 3}
                    class="prompt-input prompt-button"
                    on:click={() => onEnter(promptInput)}
                >
                    ENTER
                </button>

                <a href="https://studio.paradisbend.com">
                    <p class="prompt-text">Created By Paradis Bend Studio</p>
                </a>
            </div>
        </div>
    {/if}

    <h1>Welcome {username}</h1>

    <div class="cubeGrid" style="--col-count: {cube[0].length}">
        {#each cube as c, index}
            {#each c as x, i}
                <div class="cube" style={makeCube(x)}>
                    {#if root[0] == index && root[1] == i && !gameEnding && !gameOver && start}
                        <div class="activeBlock">
                            {#each block[rotation] as b}
                                <div
                                    class="{b > 0 ? 'blocks' : 'noblocks'} {b ==
                                    3
                                        ? 'b2'
                                        : null}"
                                    style={b > 0
                                        ? `background-color: rgba(${colors[current]}, 0.7)`
                                        : ""}
                                >
                                    {#if b == 2}{/if}
                                </div>
                            {/each}
                        </div>
                    {/if}
                </div>
            {/each}
        {/each}
    </div>

    {#if gameOver}
        <h1>Score: {score}</h1>
        <h1>Thanks For Playing!</h1>
    {/if}

    <div class="controls">
        <div class="controlRow">
            <button
                class="control"
                on:click={() => rotate(-1)}
                disabled={locked}>Rotate L</button
            >
            <button
                class="control"
                on:click={() => nudgeY(-1)}
                disabled={locked}>Up</button
            >
            <button class="control" on:click={() => rotate(1)} disabled={locked}
                >Rotate R</button
            >
        </div>
        <div class="controlRow">
            <button
                class="control"
                on:click={() => nudgeX(-1)}
                disabled={locked}>Left</button
            >
            <button class="control" on:click={() => nudgeY(1)} disabled={locked}
                >Down</button
            >
            <button class="control" on:click={() => nudgeX(1)} disabled={locked}
                >Right</button
            >
        </div>
        <div class="controlRow">
            <button
                class="control"
                disabled={gameOver}
                on:click={() => place(0)}
                >{!locked ? "Place" : "Pick Up"}</button
            >
            <button
                class="control"
                disabled={!locked || gameOver}
                on:click={() => commit(0)}>Confirm</button
            >
        </div>
        <div class="controlRow">
            <button
                class="control"
                disabled={gameOver}
                on:click={() => (gameEnding = !gameEnding)}
                >{gameEnding ? 'Keep Playing':'Review Board'}: {current}</button
            >
            <button
                class="control"
                disabled={!gameEnding || gameOver}
                on:click={endGame}>Score Your Game</button
            >
        </div>
    </div>

    <div class='scores'>
        <div class="fifty">
            <h2>Todays Top 10</h2>
            <div>
                <div class='scoreTile underline'>
                    <div class="username">Player</div>
                    <div class="score">Count</div>
                    <div class="score">Score</div>
                </div>
                {#each scoreboard.now as sc, i}
                    <div class='scoreTile'
                        tabindex="0"
                        role="button"
                        style="cursor: pointer;"
                        on:click={()=>onShare(i,'now')}
                        on:keydown={(e) => {
                        if (e.key === 'Enter' || e.key === ' ') {
                            onShare(i,'now');
                        }
                    }}>
                        <div class="username">{sc.username}</div>
                        <div class="score">{sc.count}</div>
                        <div class="score">{sc.score}</div>
                    </div>
                {/each}
            </div>
        </div>

        <div class="fifty">
            <h2>Last Top 10</h2>
            <div>
                <div class='scoreTile underline'>
                    <div class="username">Player</div>
                    <div class="score">Count</div>
                    <div class="score">Score</div>
                </div>
                {#each scoreboard.prev as sc}
                    <div class='scoreTile'>
                        <div class="username">{sc.username}</div>
                        <div class="score">{sc.count}</div>
                        <div class="score">{sc.score}</div>
                    </div>
                {/each}
            </div>
        </div>
    </div>

    {#if gameOver}
        <div tabindex="0"
          role="button"
          style="cursor: pointer;"
          on:click={() => { if (shareBoard) onShare(sbi, shareTarget); }}
          on:keydown={(e) => {
            if ((e.key === 'Enter' || e.key === ' ') && shareBoard) {
              onShare(sbi, shareTarget);
            }
          }}>
            <h3>{shareBoard ? 'Click Here to Hide Board Below!' : 'Click Someones Score To View Their Board!'}</h3>
        </div>
    {/if}

    {#if gameOver && shareBoard && scoreboard[shareTarget].length > 0}
        <h2>{`${scoreboard[shareTarget][sbi].username}'s #${sbi+1} Board ${shareTarget == 'now' ? 'Today' : 'Yesterday'}: ${scoreboard[shareTarget][sbi].count} Blocks`}</h2>
        <div class="cubeGrid" style="--col-count: {cube[0].length}">
            {#each JSON.parse(scoreboard[shareTarget][sbi].cube) as c, index}
                {#each c as x, i}
                    <div class="cube" style={makeCube(x)}></div>
                {/each}
            {/each}
        </div>
    {/if}

    <div class="scores hof">
        <h2>Hall Of Fame</h2>
        <div class='scoreTile underline hof2'>
            <div class="username">Player</div>
            <div class="score">Date</div>
            <div class="score">Count</div>
            <div class="score">Score</div>
        </div>
        {#each scoreboard.hof as sc}
            <div class='scoreTile hof2'>
                <div class="username">{sc.username}</div>
                <div class="score">{sc.day}</div>
                <div class="score">{sc.count}</div>
                <div class="score">{sc.score}</div>
            </div>
        {/each}
        <p>**WIP - Hall of Fame Updates Daily**</p>
    </div>

    <div class="controls">
        <div class="controlRow">
            <button class="control" on:click={reset}>Dev Reset</button>
        </div>
    </div>

    <div class="footer">
        <img
            style="height: 1rem; margin: 1rem 2px 2px 2px"
            src="/PBS_LOGO_NT.svg"
            alt="LOGO"
        />
        <a href="https://studio.paradisbend.com">
            <p>Paradis Bend Studio | QueueB</p>
        </a>
    </div>
</div>

<style>
    h1,
    h2,
    h3,
    p, .scores{
        font-family: "Roboto", sans-serif;
        text-align: center;
        color: white;
    }

    .queueb {
        margin: auto;
        width: 30rem;
        max-width: 100vw;
        text-align: center;
    }

    .cubeGrid {
        display: grid;
        grid-template-columns: repeat(var(--col-count), minmax(1rem, 1fr));
        width: 100%;
        gap: 0;
    }

    .cube {
        border: 1px solid rgb(88, 88, 88);
        background-color: rgba(255, 255, 255, 0.7);
        max-width: 2.2rem;
        height: 2rem;
        position: relative;
        overflow: visible;
    }

    .activeBlock {
        display: grid;
        grid-template-columns: repeat(4, minmax(1rem, 1fr));
        width: 100%;
        gap: 0;
        position: relative;
        overflow: auto;
        z-index: 9998;
        width: 420%;
        height: 420%;
    }

    .blocks {
        z-index: 9999;
        width: 100%;
        height: 100%;
    }

    .noblocks {
        z-index: 9999;
        width: 100%;
        height: 100%;
    }

    .b2 {
        outline: 8px solid rgba(1, 1, 1, 0.208);
        outline-offset: -12px;
    }

    .controls {
        display: flex;
        flex-direction: column;
        width: 100%;
        margin: 1.5rem 0;
    }

    .controlRow {
        display: flex;
        flex-direction: row;
        justify-content: center;
        text-align: center;
    }

    .control {
        flex-grow: 1;
        width: 8rem;
        height: 4rem;
    }

    .footer {
        display: flex;
        justify-content: center;
    }

    .fullscreen-prompt {
        position: fixed;
        top: 0;
        left: 0;
        width: 100vw;
        height: 100vh;
        background-color: rgba(0, 0, 0, 0.7); /* Semi-transparent background */
        display: flex;
        justify-content: center;
        z-index: 1000; /* Ensure it's on top of other elements */
    }

    .prompt-content {
        display: flex;
        flex-direction: column;
        background: white;
        width: 80vw;
        padding: 2rem;
        margin: 1rem;
        margin-bottom: auto;
        border-radius: 10px;
        text-align: center;
        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        max-height: 70vh;
        overflow-y: auto;
    }

    .prompt-text {
        color: rgb(40, 60, 80);
    }

    .prompt-input {
        color: rgb(40, 60, 80);
        border: 1px solid rgb(55, 83, 124);
        margin-bottom: 1rem;
        padding: 0.5rem 1rem;
        border-radius: 5px;
        cursor: pointer;
        min-width: 50vw;
    }

    .prompt-button {
        background-color: rgb(40, 60, 80);
        color: white;
    }

    .prompt-button:disabled {
        background-color: grey;
    }

    button:hover {
        background-color: rgba(0, 0, 0, 0.1);
        color: white;
    }

    .scores {
        display: flex;
        flex-direction: row;
        flex-basis: auto;
        width: 100%;
        padding-bottom: 2em;
        margin-bottom: 5em;
        justify-content: space-around;
    }

    .fifty {
        display: flex;
        flex-direction: column;
        text-align: center;
    }

    .scoreTile {
        display: flex;
        flex-direction: row;
        width: 80vw;
        max-width: 12em;
    }
    .score {
        text-align: right;
        width: 30%;
    }
    .username {
        flex-grow: 3;
        text-align: left;
    }
    .underline {
        border-bottom: 2px solid #ccc;
    }

    .hof{
        flex-direction: column;
    }

    .hof2{
        width: 90%;
        max-width: 90%;
        align-self: center;

    }
</style>
