<script lang="ts">
  import * as Collapsible from '$lib/components/ui/collapsible/index.js';
  import * as Sidebar from '$lib/components/ui/sidebar/index.js';
  import * as Dialog from '$lib/components/ui/dialog/index.js';
  import * as Tabs from '$lib/components/ui/tabs/index.js';
  import * as Card from '$lib/components/ui/card/index.js';
  import MessagesSquare from '@lucide/svelte/icons/messages-square';
  import MinusIcon from '@lucide/svelte/icons/minus';
  import PlusIcon from '@lucide/svelte/icons/plus';
  import UserRoundPlus from '@lucide/svelte/icons/user-round-plus';
  import UsersRound from '@lucide/svelte/icons/users-round';
  import CirclePlus from '@lucide/svelte/icons/circle-plus';
  import Input from './ui/input/input.svelte';
  import * as ContextMenu from '$lib/components/ui/context-menu/index.js';
  import Button, { buttonVariants } from './ui/button/button.svelte';
  import User from './extra/User.svelte';
  import type { SessionValidationResult } from '$lib/server/auth';
  import { Status, type AppPSD, type OverviewUser } from '$lib';
  import Label from './ui/label/label.svelte';
  import { toast } from 'svelte-sonner';
  import { enhance } from '$app/forms';
  import { invalidateAll } from '$app/navigation';
  import { fill_overview_data } from '$lib/state.svelte';

  import { overview_data } from '$lib/state.svelte';

  let {
    currentPage = $bindable<string | null>(),
    subPage = $bindable<string | null>(),
    psd,
    user,
    ...restProps
  }: {
    currentPage: string | null;
    subPage: string | null;
    psd: AppPSD;
    user: SessionValidationResult['user'];
  } = $props();
</script>

<Sidebar.Root {...restProps}>
  <Sidebar.Header>
    <Sidebar.Menu>
      <Sidebar.MenuItem>
        <Sidebar.MenuButton size="lg">
          <div
            class="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground"
          >
            <MessagesSquare class="size-4" />
          </div>
          <div class="flex flex-col gap-0.5 leading-none">
            <span class="font-medium">chat.sad.ovh</span>
          </div>
        </Sidebar.MenuButton>
        <div class="flex w-full justify-center gap-2">
          <Dialog.Root>
            <Dialog.Trigger>
              <Button
                variant={user!.friendRequests.length > 0 ? 'destructive' : 'outline'}
                size="icon"
              >
                <UserRoundPlus />
              </Button>
            </Dialog.Trigger>

            <Dialog.Content class="sm:max-w-106.25">
              <Dialog.Header>
                <Dialog.Title>Add a friend</Dialog.Title>
                <Dialog.Description>
                  Add a friend using their username or manage pending requests.
                </Dialog.Description>
              </Dialog.Header>

              <!-- input to add a new friend -->
              <form
                method="POST"
                action="?/addFriend"
                class="mb-4"
                use:enhance={() => {
                  return async ({ result }) => {
                    if (result.type == 'success') {
                      toast.success('Friend request sent successfully');
                    }

                    if (result.type == 'error' || result.type == 'failure') {
                      toast.error(
                        'Could not send friend request: ' +
                          (result.type === 'error' ? result.error : result.data?.error)
                      );
                    }

                    await invalidateAll();
                    await fill_overview_data(psd);
                  };
                }}
              >
                <Input name="username" placeholder="username" required class="mb-2" />
                <Dialog.Footer>
                  <Dialog.Close class={buttonVariants({ variant: 'outline' })}>Cancel</Dialog.Close>
                  <Button type="submit">Send request</Button>
                </Dialog.Footer>
              </form>

              <!-- Tabs for Friend Requests -->
              <Tabs.Root value="outgoing">
                <Tabs.List>
                  <Tabs.Trigger value="outgoing">Outgoing</Tabs.Trigger>
                  <Tabs.Trigger value="incoming">Incoming</Tabs.Trigger>
                  <Tabs.Trigger value="manage">Manage Friends</Tabs.Trigger>
                </Tabs.List>

                <!-- Outgoing Requests -->
                <Tabs.Content value="outgoing">
                  {#if user!.friendRequests.filter((r) => r.fromUser === user!.id).length === 0}
                    <p class="text-sm text-muted-foreground">No outgoing requests</p>
                  {:else}
                    {#each user!.friendRequests.filter((r) => r.fromUser === user!.id) as request (request.id)}
                      <Card.Root class="mb-2">
                        <Card.Header>
                          <Card.Title>{request.toUsername}</Card.Title>
                          <Card.Description>Request sent</Card.Description>
                        </Card.Header>
                        <Card.Footer>
                          <form
                            method="POST"
                            action="?/cancelFriendRequest"
                            use:enhance={() => {
                              return async ({ result }) => {
                                if (result.type == 'success') {
                                  toast.success('Cancelled friend request successfully');
                                }

                                if (result.type == 'error' || result.type == 'failure') {
                                  toast.error(
                                    'Could not cancel friend request: ' +
                                      (result.type === 'error' ? result.error : result.data?.error)
                                  );
                                }

                                await invalidateAll();
                                await fill_overview_data(psd);
                              };
                            }}
                          >
                            <input type="hidden" name="requestId" value={request.id} />
                            <Button type="submit" variant="outline" size="sm">Cancel</Button>
                          </form>
                        </Card.Footer>
                      </Card.Root>
                    {/each}
                  {/if}
                </Tabs.Content>

                <!-- Incoming Requests -->
                <Tabs.Content value="incoming">
                  {#if user!.friendRequests.filter((r) => r.toUser === user!.id).length === 0}
                    <p class="text-sm text-muted-foreground">No incoming requests</p>
                  {:else}
                    {#each user!.friendRequests.filter((r) => r.toUser === user!.id) as request (request.id)}
                      <Card.Root class="mb-2">
                        <Card.Header>
                          <Card.Title>{request.fromUsername}</Card.Title>
                          <Card.Description>Sent you a friend request</Card.Description>
                        </Card.Header>
                        <Card.Footer class="flex gap-2">
                          <!-- accept friend -->
                          <form
                            method="POST"
                            action="?/addFriend"
                            use:enhance={() => {
                              return async ({ result }) => {
                                if (result.type == 'success') {
                                  toast.success('Accepted friend request successfully');
                                }

                                if (result.type == 'error' || result.type == 'failure') {
                                  toast.error(
                                    'Could not accept friend request: ' +
                                      (result.type === 'error' ? result.error : result.data?.error)
                                  );
                                }

                                await invalidateAll();
                                await fill_overview_data(psd);
                              };
                            }}
                          >
                            <input type="hidden" name="userId" value={request.fromUser} />
                            <Button type="submit" size="sm">Accept</Button>
                          </form>
                          <!-- decline friend -->
                          <form
                            method="POST"
                            action="?/cancelFriendRequest"
                            use:enhance={() => {
                              return async ({ result }) => {
                                if (result.type == 'success') {
                                  toast.success('Cancelled friend request successfully');
                                }

                                if (result.type == 'error' || result.type == 'failure') {
                                  toast.error(
                                    'Could not cancel friend request: ' +
                                      (result.type === 'error' ? result.error : result.data?.error)
                                  );
                                }

                                await invalidateAll();
                                await fill_overview_data(psd);
                              };
                            }}
                          >
                            <input type="hidden" name="requestId" value={request.id} />
                            <Button type="submit" variant="outline" size="sm">Decline</Button>
                          </form>
                        </Card.Footer>
                      </Card.Root>
                    {/each}
                  {/if}
                </Tabs.Content>
                <Tabs.Content value="manage">
                  {#if overview_data.friends.length === 0}
                    <p class="text-sm text-muted-foreground">You have no friends added.</p>
                  {:else}
                    {#each overview_data.friends as friend (friend.id)}
                      <Card.Root class="mb-2">
                        <Card.Header>
                          <Card.Title>{friend.username}</Card.Title>
                          <Card.Description>Currently your friend</Card.Description>
                        </Card.Header>
                        <Card.Footer>
                          <form
                            method="POST"
                            action="?/removeFriend"
                            use:enhance={() => {
                              return async ({ result }) => {
                                if (result.type == 'success') {
                                  toast.success('Removed friend successfully');
                                }

                                if (result.type == 'error' || result.type == 'failure') {
                                  toast.error(
                                    'Could not remove friend: ' +
                                      (result.type === 'error' ? result.error : result.data?.error)
                                  );
                                }

                                await invalidateAll();
                                await fill_overview_data(psd);
                              };
                            }}
                          >
                            <input type="hidden" name="userId" value={friend.id} />
                            <Button type="submit" variant="destructive" size="sm">
                              Remove Friend
                            </Button>
                          </form>
                        </Card.Footer>
                      </Card.Root>
                    {/each}
                  {/if}
                </Tabs.Content>
              </Tabs.Root>
            </Dialog.Content>
          </Dialog.Root>

          <Dialog.Root>
            <Dialog.Trigger>
              <Button variant="outline" size="icon">
                <UsersRound />
              </Button>
            </Dialog.Trigger>

            <Dialog.Content class="sm:max-w-106.25">
              <form
                method="POST"
                action="?/createGroup"
                use:enhance={() => {
                  return async ({ result }) => {
                    if (result.type == 'success') {
                      toast.success('Created group successfully');
                    }

                    if (result.type == 'error' || result.type == 'failure') {
                      toast.error(
                        'Could not create group: ' +
                          (result.type === 'error' ? result.error : result.data?.error)
                      );
                    }

                    await invalidateAll();
                    await fill_overview_data(psd);
                  };
                }}
              >
                <Dialog.Header>
                  <Dialog.Title>Create a group</Dialog.Title>
                  <Dialog.Description>Add friends into your group!</Dialog.Description>
                </Dialog.Header>

                {#each overview_data.friends as friend (friend.id)}
                  <label class="flex items-center gap-2">
                    <input type="checkbox" name="member" value={friend.id} />
                    <User crown={false} user={friend} />
                  </label>
                {/each}

                <Dialog.Footer>
                  <Dialog.Close class={buttonVariants({ variant: 'outline' })}>Cancel</Dialog.Close>
                  <Button type="submit">Create group</Button>
                </Dialog.Footer>
              </form>
            </Dialog.Content>
          </Dialog.Root>

          <Dialog.Root>
            <Dialog.Trigger>
              <Button variant="outline" size="icon">
                <CirclePlus />
              </Button>
            </Dialog.Trigger>

            <Dialog.Content class="sm:max-w-106.25">
              <form
                method="POST"
                action="?/joinServer"
                use:enhance={() => {
                  return async ({ result }) => {
                    console.log(result);
                    if (result.type == 'success') {
                      toast.success('Joined server successfully');
                    }

                    if (result.type == 'error' || result.type == 'failure') {
                      toast.error(
                        'Could not join server: ' +
                          (result.type === 'error' ? result.error : result.data?.error)
                      );
                    }

                    await invalidateAll();
                    await fill_overview_data(psd);
                  };
                }}
              >
                <Dialog.Header>
                  <Dialog.Title>Join a server</Dialog.Title>
                  <Dialog.Description>Enter an invite link.</Dialog.Description>
                </Dialog.Header>

                <Input name="invite" placeholder="invite link" required />

                <Dialog.Footer>
                  <Dialog.Close class={buttonVariants({ variant: 'outline' })}>Cancel</Dialog.Close>
                  <Button type="submit">Join</Button>
                </Dialog.Footer>
              </form>
            </Dialog.Content>
          </Dialog.Root>

          <Dialog.Root>
            <Dialog.Trigger>
              <Button variant="outline" size="icon">
                <PlusIcon />
              </Button>
            </Dialog.Trigger>

            <Dialog.Content class="sm:max-w-106.25">
              <form
                method="POST"
                action="?/createServer"
                use:enhance={() => {
                  return async ({ result }) => {
                    if (result.type == 'success') {
                      toast.success('Created server successfully');
                    }

                    if (result.type == 'error' || result.type == 'failure') {
                      toast.error(
                        'Could not create server: ' +
                          (result.type === 'error' ? result.error : result.data?.error)
                      );
                    }

                    await invalidateAll();
                    await fill_overview_data(psd);
                  };
                }}
              >
                <Dialog.Header>
                  <Dialog.Title>Create a server</Dialog.Title>
                  <Dialog.Description>Name your new server.</Dialog.Description>
                </Dialog.Header>

                <Input name="name" placeholder="Server name" required />

                <Dialog.Footer>
                  <Dialog.Close class={buttonVariants({ variant: 'outline' })}>Cancel</Dialog.Close>
                  <Button type="submit">Create</Button>
                </Dialog.Footer>
              </form>
            </Dialog.Content>
          </Dialog.Root>
        </div>
      </Sidebar.MenuItem>
    </Sidebar.Menu>
  </Sidebar.Header>
  <Sidebar.Content>
    <Sidebar.Group>
      <Sidebar.Menu>
        <Collapsible.Root open={true} class="group/collapsible">
          <Sidebar.MenuItem>
            <Collapsible.Trigger>
              <Sidebar.MenuButton>
                Friends
                <PlusIcon class="ms-auto group-data-[state=open]/collapsible:hidden" />
                <MinusIcon class="ms-auto group-data-[state=closed]/collapsible:hidden" />
              </Sidebar.MenuButton>
            </Collapsible.Trigger>
            <Collapsible.Content>
              <Sidebar.MenuSub>
                {#each overview_data.friends as friend (friend.id)}
                  <Sidebar.MenuSubItem>
                    <Sidebar.MenuSubButton>
                      <User
                        onclick={(e) => {
                          e.preventDefault();
                          currentPage = friend.id;
                          subPage = null;
                        }}
                        user={friend}
                        crown={false}
                      ></User>
                    </Sidebar.MenuSubButton>
                  </Sidebar.MenuSubItem>
                {/each}
              </Sidebar.MenuSub>
            </Collapsible.Content>
          </Sidebar.MenuItem>
        </Collapsible.Root>

        <Collapsible.Root open={true} class="group/collapsible">
          <Sidebar.MenuItem>
            <Collapsible.Trigger>
              <Sidebar.MenuButton>
                Groups
                <PlusIcon class="ms-auto group-data-[state=open]/collapsible:hidden" />
                <MinusIcon class="ms-auto group-data-[state=closed]/collapsible:hidden" />
              </Sidebar.MenuButton>
            </Collapsible.Trigger>
            <Collapsible.Content>
              <Sidebar.MenuSub>
                {#each overview_data.groups as group (group.id)}
                  <Sidebar.MenuSubItem>
                    <Sidebar.MenuSubButton>
                      <a
                        onclick={(e) => {
                          e.preventDefault();
                          currentPage = group.id;
                          subPage = null;
                        }}
                        href="##"
                      >
                        {group.name} ({group.members} members)
                      </a>
                    </Sidebar.MenuSubButton>
                  </Sidebar.MenuSubItem>
                {/each}
              </Sidebar.MenuSub>
            </Collapsible.Content>
          </Sidebar.MenuItem>
        </Collapsible.Root>

        <Collapsible.Root open={true} class="group/collapsible">
          <Sidebar.MenuItem>
            <Collapsible.Trigger>
              <Sidebar.MenuButton>
                Servers
                <PlusIcon class="ms-auto group-data-[state=open]/collapsible:hidden" />
                <MinusIcon class="ms-auto group-data-[state=closed]/collapsible:hidden" />
              </Sidebar.MenuButton>
            </Collapsible.Trigger>
            <Collapsible.Content>
              <Sidebar.MenuSub>
                {#each overview_data.servers as server (server.id)}
                  <Dialog.Root>
                    <ContextMenu.Root>
                      <ContextMenu.Trigger
                        ><Sidebar.MenuSubItem>
                          <Sidebar.MenuSubButton
                            onclick={(e) => {
                              e.preventDefault();
                              currentPage = server.id;
                              subPage = null;
                            }}
                          >
                            <img
                              src={'https://api.dicebear.com/9.x/glass/svg?seed=' + server.name}
                              alt={server.name}
                              class="size-6 rounded-full"
                            />
                            {server.name}
                          </Sidebar.MenuSubButton>
                        </Sidebar.MenuSubItem>
                      </ContextMenu.Trigger>
                      <ContextMenu.Content>
                        <ContextMenu.Item>
                          <Dialog.Trigger>Create channel</Dialog.Trigger>
                        </ContextMenu.Item>
                      </ContextMenu.Content>
                    </ContextMenu.Root>

                    <Dialog.Content>
                      <form
                        method="POST"
                        action="?/createChannel"
                        use:enhance={() => {
                          return async ({ result }) => {
                            if (result.type == 'success') {
                              toast.success('Created channel successfully');
                            }

                            if (result.type == 'error' || result.type == 'failure') {
                              toast.error(
                                'Could not create channel: ' +
                                  (result.type === 'error' ? result.error : result.data?.error)
                              );
                            }

                            await invalidateAll();
                            await fill_overview_data(psd);
                          };
                        }}
                      >
                        <Dialog.Header>
                          <Dialog.Title>Create a channel</Dialog.Title>
                          <Dialog.Description>Add a new channel to this server.</Dialog.Description>
                        </Dialog.Header>

                        <div class="space-y-1">
                          <Label for="channelName">Channel name</Label>
                          <Input
                            id="channelName"
                            name="channelName"
                            placeholder="Channel name"
                            required
                            minlength={1}
                            maxlength={32}
                          />
                          <input type="hidden" name="serverId" value={server.id} />
                        </div>

                        <Dialog.Footer>
                          <Dialog.Close class={buttonVariants({ variant: 'outline' })}
                            >Cancel</Dialog.Close
                          >
                          <Button type="submit">Create</Button>
                        </Dialog.Footer>
                      </form>
                    </Dialog.Content>
                  </Dialog.Root>
                  {#each server.channels as channel (channel.id)}
                    <Dialog.Root>
                      <ContextMenu.Root>
                        <ContextMenu.Trigger>
                          <a
                            onclick={(e) => {
                              e.preventDefault();
                              currentPage = server.id;
                              subPage = channel.id;
                            }}
                            href="##"
                            class="flex items-center gap-2"
                          >
                            {channel.name}
                          </a>
                        </ContextMenu.Trigger>
                        <ContextMenu.Content>
                          <ContextMenu.Item class="text-red-500 underline">
                            <Dialog.Trigger>Delete channel</Dialog.Trigger>
                          </ContextMenu.Item>
                        </ContextMenu.Content>
                      </ContextMenu.Root>

                      <Dialog.Content>
                        <form
                          method="POST"
                          action="?/deleteChannel"
                          use:enhance={() => {
                            return async ({ result }) => {
                              if (result.type == 'success') {
                                toast.success('Deleted channel successfully');
                              }

                              if (result.type == 'error' || result.type == 'failure') {
                                toast.error(
                                  'Could not delete channel: ' +
                                    (result.type === 'error' ? result.error : result.data?.error)
                                );
                              }

                              await invalidateAll();
                              await fill_overview_data(psd);
                            };
                          }}
                        >
                          <input type="hidden" name="serverId" value={server.id} />
                          <input type="hidden" name="channelId" value={channel.id} />

                          <Dialog.Header>
                            <Dialog.Title>Delete this channel</Dialog.Title>
                            <Dialog.Description
                              >This action is IRREVERSIBLE and will delete all messages in the
                              channel. Are you sure you want to proceed?</Dialog.Description
                            >
                          </Dialog.Header>

                          <Dialog.Footer>
                            <Dialog.Close class={buttonVariants({ variant: 'outline' })}
                              >No</Dialog.Close
                            >
                            <Button variant="destructive" type="submit">Yes</Button>
                          </Dialog.Footer>
                        </form>
                      </Dialog.Content>
                    </Dialog.Root>
                  {/each}
                {/each}
              </Sidebar.MenuSub>
            </Collapsible.Content>
          </Sidebar.MenuItem>
        </Collapsible.Root>
      </Sidebar.Menu>
    </Sidebar.Group>
  </Sidebar.Content>
  <Sidebar.Footer class="border-t-2 p-2">
    <Dialog.Root>
      <Dialog.Trigger>
        <User user={user as unknown as OverviewUser} crown={false} />
      </Dialog.Trigger>

      <Dialog.Content>
        <form
          method="POST"
          action="?/updateProfile"
          use:enhance={() => {
            return async ({ result }) => {
              if (result.type == 'success') {
                toast.success('Edited profile successfully');
              }

              if (result.type == 'error' || result.type == 'failure') {
                toast.error(
                  'Could not edit profile: ' +
                    (result.type === 'error' ? result.error : result.data?.error)
                );
              }

              await invalidateAll();
              await fill_overview_data(psd);
            };
          }}
        >
          <Dialog.Header>
            <Dialog.Title>Edit profile</Dialog.Title>
            <Dialog.Description>Update how others see you.</Dialog.Description>
          </Dialog.Header>

          <div class="">
            <Label for="userName">Username</Label>
            <Input
              id="userName"
              name="userName"
              placeholder="Your name"
              value={user?.username}
              required
              minlength={2}
              maxlength={32}
            />
          </div>

          <!-- Presence -->
          <div class="space-y-1">
            <Label for="status">Status</Label>
            <select id="status" name="status" class="input" required>
              <option value={Status.ONLINE} selected={user?.statusOverwrite === Status.ONLINE}
                >Online</option
              >
              <option value={Status.DND} selected={user?.statusOverwrite === Status.DND}
                >Do Not Disturb</option
              >
              <option value={Status.OFFLINE} selected={user?.statusOverwrite === Status.OFFLINE}
                >Offline</option
              >
            </select>
          </div>

          <div class="space-y-1">
            <Label for="statusMessage">Status message</Label>
            <Input
              id="statusMessage"
              name="statusMessage"
              placeholder="What's going on?"
              value={user?.statusMessage ?? ''}
              maxlength={64}
            />
          </div>

          <Dialog.Footer>
            <Dialog.Close class={buttonVariants({ variant: 'outline' })}>Cancel</Dialog.Close>
            <Button type="submit">Save</Button>
          </Dialog.Footer>
        </form>
      </Dialog.Content>
    </Dialog.Root>
  </Sidebar.Footer>
  <Sidebar.Rail />
</Sidebar.Root>
