<script lang="ts">

  import { onMount } from "svelte";
    import { binding_callbacks, empty } from "svelte/internal"; // WTF is this?
  import Button from "../../pieces/Button.svelte";
  import DisplayAUser from "../../pieces/DisplayAUser.svelte";
  import Tabs from "../../pieces/Tabs.svelte";

  let errors = {friendRequest: '',};
  let set = {friendUsername: ''}

  let user;
  let allUsers;
  let myFriendships;
  let requestsMade, requestsRecieved;
  let blockedUsers;
  let usernameBeingViewed;
  let friendshipStatusFull; // id, date, senderUsername, reveiverUsername, status

  /**** Layout variables ****/
  let tabItems: string[] = ['All Users', 'My Friends', 'Friend Requests', 'Blocked Users']
  let activeTabItem: string = 'All Users';


  onMount( async() => {

    // DO I ACTUALLY NEED TO ON MOUNT ALL THIS STUFF?
      // ALSO I COULD JUST USE THE FUNCITONS I MADE...


    // yea no idea what
    // i mean do i fetch user? i will for now
    user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`)
      .then( (x) => x.json() );

    fetchAll();
    // ok this shit works!
    // const interval = setInterval(() => {
		// 	fetchAll();
		// }, 1000);

    // return () => clearInterval(interval);
  });

  const fetchAll = async() => {
    // no need to await i think it can load in the background
    fetchAllUsers();
    fetchMyFriendships();
    fetchRequestsMade();
    fetchRequestsReceived();
    fetchBlockedUsers();
  }

  /*****  Fetch basic things  *****/
  const fetchAllUsers = async() => {
    allUsers = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/all`)
      .then( x => x.json() );
    console.log('got all users ')
    console.log({...allUsers})
  };

  // it's more like fetch friendships
  // then i need to extract the users
  const fetchMyFriendships = async() => {
    myFriendships = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/myfriends`)
      .then( x => x.json() );
    console.log('got my friends ')
    console.log({...myFriendships})
  };

  const fetchRequestsMade = async() => {
    requestsMade = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/pending`)
      .then( x => x.json() );
    console.log('got requests made ')
    console.log({...requestsMade})
  };

  const fetchRequestsReceived = async() => {
    requestsRecieved = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/received`)
      .then( x => x.json() );
    console.log('got requests received ')
    console.log({...requestsRecieved})
  };

  const fetchBlockedUsers = async() => {
    blockedUsers = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/blocked`)
      .then( x => x.json() );
    console.log('got blocked users, is it empty?')
    console.log({...blockedUsers})
    console.log(Object.keys(blockedUsers))
  };
  /**** END OF MAIN FETCH ****/

  // returns everything but BLOCKED
  const fetchFriendshipFull = async(aUsername) => {
    console.log('fetch friendship from a username')
    console.log(aUsername)
    friendshipStatusFull = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/myfriends?username=${aUsername}`)
      .then( x => x.json());
    console.log({...friendshipStatusFull})
  };

  
  const sendFriendRequest = async(aUsername) => {
    console.log('sending a friend request')
    console.log(aUsername)
    const resp = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations`, {
        method : "POST",
        headers: { 'Content-Type': 'application/json'},
          body: JSON.stringify({
          "receiverUsername": aUsername,
          "status": "R"
        })
      })
      .then( x => x.json())
      // .catch( x => console.log({...x}))
      // "status": "A"
      console.log({...resp})
      fetchFriendshipFull(aUsername);
  };

  const viewAUser = async(aUsername) => {
    console.log('Profile Friend updating userBeingViewed')
    usernameBeingViewed = aUsername;

    // friendshipStatusFull = undefined;
    // id, date, senderUsername, reveiverUsername, status
    await fetchFriendshipFull(aUsername);

    console.log('Friendship Status Full')
    console.log({...friendshipStatusFull})
  };

  const acceptFriendRequest = async(relationshipId) => {
    console.log('accept friend request')

    const resp = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations/${relationshipId}/accept`, {
        method: "PATCH"})
      .then( x => x.json());
    // maybe not the most robust things, not super reusable cuz it depends on outside vars but works for now...
    console.log('accepted friend request, now response')
    console.log({...resp})
    await fetchFriendshipFull(usernameBeingViewed);

    // will this make it reload? C'est un peu bourain... do i even need it?
    activeTabItem = activeTabItem;
  };

  const declineFriendRequest = async(relationshipId) => {
    console.log('decline friend request')
    const resp = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations/${relationshipId}/decline`, {
        method: "PATCH"})
      .then( x => x.json());
    // maybe not the most robust things, not super reusable cuz it depends on outside vars but works for now...
    console.log('declined friend request, now response')
    console.log({...resp})
    await fetchFriendshipFull(usernameBeingViewed);
  };

  const unfriend = async(relationshipId) => {
    console.log('Unfriend')
    const resp = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations/${relationshipId}`, {
        method: "DELETE"})
      .then( x => x.json());
    
    // friendshipStatusFull = undefined;
    // OR
    await fetchFriendshipFull(usernameBeingViewed);
    if (Object.keys(friendshipStatusFull).length === 0)
      friendshipStatusFull = undefined;

    // will this make it reload? C'est un peu bourain... do i even need it?
    activeTabItem = activeTabItem;
  };

  const blockANonFriendUser = async(aUsername) => {
    console.log('Block a non friend user, their username')
    console.log(aUsername)

    sentFriendRequest = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations`, {
        method : "POST",
        headers: { 'Content-Type': 'application/json'},
          body: JSON.stringify({
          "receiverUsername": aUsername,
          "status": "B"
        })
      })
      .then( x => x.json())
    await fetchBlockedUsers();
    await fetchAllUsers();
    usernameBeingViewed = undefined;
    friendshipStatusFull = undefined;

    // will this make it reload?
    activeTabItem = activeTabItem;
  };

  const blockAFriend = async(relationshipId) => {
    console.log('blocking a friend, the relationshipID')
    console.log(relationshipId)
    const resp = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/network/relations/${relationshipId}/block`, {method: "PATCH"})
      .then( x => x.json() );
    console.log('blocked a user response')
    console.log({...resp})
    await fetchBlockedUsers();
    await fetchAllUsers();
    usernameBeingViewed = undefined;
    friendshipStatusFull = undefined;

    // will this make it reload?
    activeTabItem = activeTabItem;
  };

  const unblockAUser = async(relationshipId) => {
    // it's basically the same as unfriending someone cuz unfriending them means the relationship is deleted
    await unfriend(relationshipId);
  };

  const switchTab = async(e) => {
    activeTabItem = e.detail;
    if (activeTabItem === 'All Users') {
      await fetchAllUsers();
    } else if (activeTabItem === 'My Friends') {
      await fetchMyFriendships();
    } else if (activeTabItem === 'Friend Requests') {
      await fetchRequestsReceived();
    } else if (activeTabItem === 'Blocked Users') {
      await fetchBlockedUsers();
      console.log('blocked users: ')
      console.log({...blockedUsers})
    }
  };

</script>


<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="top-grid">

  <!-- let tabItems: string[] = ['All Users', 'My Friends', 'Friend Requests']
  let activeTabItem: string = 'All Users'; -->

  <!-- maybe add numbers at the botton? like for how many of each there are? -->

  <div class="sidebar-list">
    <Tabs items={tabItems} activeItem={activeTabItem} size="small" on:tabChange={switchTab}/>
    {#if activeTabItem === 'All Users' && allUsers !== undefined}
      <h3>{activeTabItem}</h3>
      <!-- problem, i can't use user.id since Cherif doesn't want to expost that to the front...
      is there something else i could use? -->
      <!-- add a thing so it doesn't display the current user just all the other users -->

      {#if Object.keys(allUsers).length === 0}
        <div class="tip">You are alone on this platform...</div>
      {/if}
      <!-- does this work? -->
      <!-- {#each allUsers as aUser (aUser.username)} -->
      <!-- {#each allUsers as aUser (aUser.id)} -->
      {#each allUsers as aUser}
        <div class="sidebar-item" on:click={() => viewAUser(aUser.username)}>{aUser.username}</div>
        <!-- i could make an indicator component? like green for connected or something?
        i could use words but color them?
        i could make it so if they're in a game  -->
        <div class="status sidebar-item">{aUser.status}</div>
        <br>
      {/each}
    {:else if activeTabItem === 'My Friends' && myFriendships !== undefined}
      <h3>{activeTabItem}</h3>
      {#if Object.keys(myFriendships).length === 0}
        <div class="tip">You don't have any Friends... Yet!</div>
      {/if}
      <!-- {#each myFriends as aUser (aUser.id)} -->
      {#each myFriendships as aFriendship}
        {#if aFriendship.senderUsername !== user.username}
          <div class="sidebar-item" on:click={() => viewAUser(aFriendship.senderUsername)}>{aFriendship.senderUsername}</div>
        {:else if aFriendship.receiverUsername !== user.username}
          <div class="sidebar-item" on:click={() => viewAUser(aFriendship.receiverUsername)}>{aFriendship.receiverUsername}</div>
        {/if}
        <br>
      {/each}
    {:else if activeTabItem === 'Friend Requests' && requestsRecieved !== undefined}
      <h3>{activeTabItem}</h3>
      {#if Object.keys(requestsRecieved).length === 0}
        <div class="tip">You don't have any Friend Requests</div>
      {/if}
      <!-- {#each requestsRecieved as aUser (aUser.id)} -->
      {#each requestsRecieved as aUser}
        <div class="sidebar-item" on:click={() => viewAUser(aUser.senderUsername)}>{aUser.senderUsername}</div>
        <div class="status sidebar-item">{aUser.status}</div>
        <br>
      {/each}
    {:else if activeTabItem === 'Blocked Users' && blockedUsers !== undefined}
      <h3>{activeTabItem}</h3>
      <!-- seems a little excessive... maybe a lighter way of doing this? doesn't seem like it, i hate it but at least only happens sometimes.default... -->
      {#if Object.keys(blockedUsers).length === 0}
        <div class="tip">You have not Blocked any Users</div>
      {/if}
      <!-- {#each blockedUsers as aUser (aUser.id)} -->
      {#each blockedUsers as aUser}
        <div class="sidebar-item" on:click={() => viewAUser(aUser.receiverUsername)}>{aUser.receiverUsername}</div>
        <div class="status sidebar-item">{aUser.status}</div>
        <br>
      {/each}
    {/if}
  </div>


  <div class="main-display">
    {#if usernameBeingViewed !== undefined}
      <!-- <DisplayAUser aUsername={usernameBeingViewed}/> -->
      <DisplayAUser aUsername={usernameBeingViewed}/>

      <div class="buttons-area">
        {#if friendshipStatusFull && friendshipStatusFull.id}
          {#if friendshipStatusFull.status === 'R'}
            {#if friendshipStatusFull.senderUsername === user.username}
              <div class="tile">Friend Request Sent</div>
            {:else}
              <!-- <Button type="secondary" on:click={() => acceptFriendRequest(usernameBeingViewed)}>Unfriend</Button> -->
              <Button type="secondary" on:click={() => acceptFriendRequest(friendshipStatusFull.id)}>Accept Friend Request</Button>
              <Button on:click={() => declineFriendRequest(friendshipStatusFull.id)}>Decline Friend Request</Button>
            {/if}
            <Button on:click={() => blockAFriend(friendshipStatusFull.id)}>Block User</Button>
          {:else if friendshipStatusFull.status === 'A'}
            <div class="tile">You are Friends</div>
            <Button on:click={() => unfriend(friendshipStatusFull.id)}>Unfriend</Button>
            <Button on:click={() => blockAFriend(friendshipStatusFull.id)}>Block User</Button>
          {:else if friendshipStatusFull.status === 'D'}
            {#if friendshipStatusFull.senderUsername === user.username}
              <div class="tile">Your friend request was declined, hang in there bud.</div>
            {:else}
              <div class="tile">You declined the friend request, but you could still change your mind</div>
              <Button on:click={() => acceptFriendRequest(friendshipStatusFull.id)}>Accept Friend Request</Button>
            {/if}
            <Button on:click={() => blockAFriend(friendshipStatusFull.id)}>Block User</Button>
          {:else if friendshipStatusFull.status === 'B'}
            {#if friendshipStatusFull.senderUsername === user.username}
              <Button on:click={() => unblockAUser(friendshipStatusFull.id)}>Unblock User</Button>
            {/if}
          {/if}
        {:else}
          <Button type="secondary" on:click={() => sendFriendRequest(usernameBeingViewed)}>Add Friend</Button>
          <Button on:click={() => blockANonFriendUser(usernameBeingViewed)}>Block User</Button>
        {/if}
        <!-- <Button type="secondary" on:click={() => sendFriendRequest(usernameBeingViewed)}>Add Friend</Button> -->
      </div>
    {:else}
      <div class="placeholder">
        <h1>Click on a user!</h1>
        <h4>You'll see them displayed here</h4>
      </div>
    {/if}

  </div>
</div>

<style>

/* ok so i want a 12 column grid with a sidebar */

  div.top-grid{
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    /* max-height: calc(100vh - 30vh); */
    height: 85vh;
    /* margin: 0; */
  }

  div.sidebar-list{
    grid-column: 1 / span 2;
    background: white;
  }

  div.sidebar-item{
    /* yea i mean that seems fine... */
    display: inline-block;
    /* somehting about the buttons too, smaller ? */
  }
  div.status{
    font-size: 0.6em;
    font-weight: bold;
  }
  /* selector attributes to get only divs with .a-user */
  /* you gotta be careful with Svelte cuz it tacks classes on to the end of basically all elems! */
  div[class^="sidebar-item"]:hover{
    text-decoration: underline;
    font-weight: bold;
    cursor: pointer;
  }

  div.main-display{
    grid-column: 3 / span 10;
  }

  div.placeholder{
    color: darkgray;
    text-align: center;
  }

  div.buttons-area{
    text-align: center;
  }

  div.tip{
    color: darkgray;
    font-size: 0.8em;
    font-weight: bold;
  }


  .error{
    font-size: 0.8em;
    font-weight: bold;
    color: red;
  }
</style>
