import { Cog } from "@styled-icons/boxicons-solid";
import React from "react";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
import { Virtuoso } from "react-virtuoso";
import type { Client, Server } from "revolt.js";
import type { INotificationChecker } from "revolt.js/dist/util/Unreads";
import styled, { css } from "styled-components";

import { isTouchscreenDevice } from "../../../../../lib";
import { useLink } from "../../../../../lib/context";

import { useDndComponents, useDragEndCustomReorder } from "../../../../common";

import { Avatar, OtherIcon } from "../../../atoms";
import { Tooltip } from "../../../atoms/indicators/Tooltip";
import { Item, ItemContainer } from "./Item";
import { FooterProps, ListFooter } from "./ListFooter";
import { ListHeader } from "./ListHeader";

export type Props = {
    /**
     * Client handle
     */
    client: Client;

    /**
     * Function to generate home URL
     */
    home: () => string;

    /**
     * Check whether a channel or server is muted
     */
    permit: INotificationChecker;

    /**
     * Active server ID
     */
    active?: string;

    /**
     * Whether to show discovery icon
     */
    showDiscovery?: boolean;
    isExplore?: boolean;
};

type ParentProps = {
    /**
     * Server ordering
     */
    servers: Server[];

    /**
     * Reordering function
     */
    reorder: (source: number, dest: number) => void;
};

const Base = styled.div<{isExplore?: boolean}>`
    // width: 56px;
    background: #232323;
    width: 80px;
    display: flex;
    flex-direction: column;
    box-shadow: 25px 0 8px #0f0f0fa6;
    z-index: 10;
    // margin: 10px 0 10px 10px;

    .list {
        flex-grow: 1;
        scrollbar-width: none;
    }

    .list::-webkit-scrollbar {
        width: 0;
        height: 0;
    }

    ${(props) =>
        props.isExplore ?
        css`
        margin: 0;
        `
        :
        css`
        margin: 10px 0 10px 10px;
        `
    }

    ${isTouchscreenDevice &&
    css`
        padding-bottom: 50px;
    `}
`;

const Shadow = styled.div`
    height: 0;
    z-index: 1;
    display: relative;

    div {
        height: 12px;
        margin-top: -12px;
        display: absolute;
        background: linear-gradient(to bottom, transparent, var(--background));
    }
`;

const SetIcon = styled.img`
    display: flex;
    margin: auto;
    width: 18px;
    height: 18px;
`;

/**
 * Server List
 */
export function ServerList(props: Props & ParentProps & FooterProps) {
    const { servers, reorder, createServer, showDiscovery, isExplore, ...innerProps } =
        props;
    const { active, permit } = props;

    const Link = useLink();

    return (
        <Base isExplore={isExplore}>
            <DragDropContext onDragEnd={useDragEndCustomReorder(reorder)}>
                <Droppable
                    droppableId="droppable"
                    mode="virtual"
                    renderClone={(provided, snapshot, rubric) => (
                        <Item
                            active={false}
                            permit={permit}
                            provided={provided}
                            isDragging={snapshot.isDragging}
                            item={servers[rubric.source.index]}
                        />
                    )}>
                    {(provided) => {
                        return (
                            <Virtuoso
                                totalCount={servers.length + 2}
                                components={useDndComponents()}
                                className="list"
                                // @ts-expect-error Incompatible types between libraries
                                scrollerRef={provided.innerRef}
                                itemContent={(index) => {
                                    if (index === 0) {
                                        return <ListHeader {...innerProps} />;
                                    }

                                    if (index === servers.length + 1) {
                                        return (
                                            <ListFooter
                                                createServer={createServer}
                                                showDiscover={showDiscovery}
                                            />
                                        );
                                    }

                                    const item = servers[index - 1];

                                    return (
                                        <Draggable
                                            draggableId={item._id}
                                            index={index - 1}
                                            key={item._id}>
                                            {(provided) => (
                                                <Item
                                                    item={item}
                                                    permit={permit}
                                                    active={item._id === active}
                                                    isDragging={false}
                                                    provided={provided}
                                                />
                                            )}
                                        </Draggable>
                                    );
                                }}
                            />
                        );
                    }}
                </Droppable>
            </DragDropContext>
            <ItemContainer head>
                <a onClick={createServer}>
                    <ItemContainer>
                        <Tooltip content="Add a Bubble" div right>
                            <OtherIcon
                                src="/assets_default/icons/addIcon.png"
                                size={50}
                                fallback={<Cog size={18} />}
                                interactive
                            />
                        </Tooltip>
                    </ItemContainer>
                </a>
            </ItemContainer>
            <ItemContainer head>
                <Link to="/explore">
                    <Tooltip content="Bubbles Explorer" div right>
                        <OtherIcon
                            src="/assets_default/icons/searchIcon.png"
                            size={50}
                            fallback={<Cog size={18} />}
                            interactive
                        />
                    </Tooltip>
                </Link>
            </ItemContainer>
            <ItemContainer head>
                <Link to="/settings">
                    <Tooltip i18n="app.settings.title" div right>
                        <OtherIcon
                            src="/assets_default/icons/arrow-down.png"
                            size={50}
                            fallback={<Cog size={18} />}
                            interactive
                            arrow={true}
                        />
                    </Tooltip>
                </Link>
            </ItemContainer>
        </Base>
    );
}
