import { useRosettaColors } from "@/app/hooks/useRosettaColors";
import { Avatar, Badge, Box, Divider, Flex, Loader, Skeleton, Text, useComputedColorScheme, useMantineTheme } from "@mantine/core";
import { IconAlertCircle, IconBellOff, IconCheck, IconChecks, IconClock, IconPin, IconUsers } from "@tabler/icons-react";
import { DeliveredMessageState } from "@/app/providers/DialogProvider/DialogProvider";
import { dotMessageIfNeeded, isMessageDeliveredByTime } from "@/app/utils/utils";
import { usePacket } from "@/app/providers/ProtocolProvider/usePacket";
import { useEffect, useState } from "react";
import { PacketTyping } from "@/app/providers/ProtocolProvider/protocol/packets/packet.typeing";
import { useAvatars } from "@/app/providers/AvatarProvider/useAvatars";
import { TextParser } from "../TextParser/TextParser";
import { useMemory } from "@/app/providers/MemoryProvider/useMemory";
import { DialogRow } from "@/app/providers/DialogListProvider/DialogListProvider";
import { useGroupInformation } from "@/app/providers/InformationProvider/useGroupInformation";
import { useDialogInfo } from "@/app/providers/DialogListProvider/useDialogInfo";
import { useUserInformation } from "@/app/providers/InformationProvider/useUserInformation";
import { useDialogContextMenu } from "@/app/hooks/useDialogContextMenu";
import { useDialogMute } from "@/app/providers/DialogStateProvider.tsx/useDialogMute";
import { useDialogPin } from "@/app/providers/DialogStateProvider.tsx/useDialogPin";
import { useMentions } from "@/app/providers/DialogStateProvider.tsx/useMentions";

export interface DialogProps extends DialogRow {
    onClickDialog: (dialog: string) => void;
}

export function GroupDialog(props : DialogProps) {
    const colors = useRosettaColors();
    const theme = useMantineTheme();
    const computedTheme = useComputedColorScheme();

    /**
     * Принимает #group:group_id, для 
     * диалогов между пользователями есть просто public_key собеседника
     */
    const groupId = props.dialog_id; 
    const {isMuted} = useDialogMute(groupId);
    const {isPinned} = useDialogPin(groupId);
 
    const {groupInfo} = useGroupInformation(groupId);

    const {lastMessage, unreaded, loading} = useDialogInfo(props);
    const lastMessageFromMe = lastMessage.from_me == 1;

    const [usersTypeing, setUsersTypeing] = useState<{
        timeout: NodeJS.Timeout | null,
        fromPublicKey: string
    }[]>([]);

    const avatars = useAvatars(groupId);
    const [сurrentDialogPublicKeyView] = useMemory("current-dialog-public-key-view", "", true);
    const [userInfo] = useUserInformation(lastMessage.from_public_key);
    const [typingUser] = useUserInformation(usersTypeing[0]?.fromPublicKey || '');

    const isInCurrentDialog = props.dialog_id == сurrentDialogPublicKeyView;
    const currentDialogColor = computedTheme == 'dark' ? '#2a6292' :'#438fd1';
    const {openContextMenu} = useDialogContextMenu();
    const {isMentioned} = useMentions();


    useEffect(() => {
        clearUsersTypeing();
    }, [props.dialog_id]);

    const clearUsersTypeing = () => {
        usersTypeing.forEach(ut => {
            if(ut.timeout){
                clearTimeout(ut.timeout);
            }
        });
        setUsersTypeing([]);
    }

    usePacket(0x0B, (packet : PacketTyping) => {
        if(packet.getToPublicKey() == props.dialog_id){
            setUsersTypeing((prev) => [...prev, {
                fromPublicKey: packet.getFromPublicKey(),
                timeout: setTimeout(() => {
                    setUsersTypeing((prev) => {
                        return prev.filter(ut => ut.fromPublicKey != packet.getFromPublicKey());
                    });
                }, 3000)
            }]);
        }
    }, [props.dialog_id]);

    return (
        <Box style={{
            cursor: 'pointer',
            userSelect: 'none',
            backgroundColor: isInCurrentDialog ? currentDialogColor : 'unset',
        }} onClick={() => props.onClickDialog(props.dialog_id)} onContextMenu={() => {
            openContextMenu(props.dialog_id)
        }}>
            <Flex p={'sm'} gap={'sm'}>
                <Box style={{ position: 'relative', display: 'inline-block' }}>
                    <Avatar src={avatars.length > 0 ? avatars[0].avatar : undefined} variant={isInCurrentDialog ? 'filled' : 'light'} name={groupInfo.title} size={50} color={'initials'} />
                </Box>
                <Flex w={'100%'} justify={'space-between'} direction={'row'} gap={'sm'}>
                    <Flex direction={'column'} gap={3}>
                        <Flex align={'center'} gap={5}>
                            <Text size={'sm'} c={computedTheme == 'light' && !isInCurrentDialog ? 'black' : 'white'} fw={500}>
                                {dotMessageIfNeeded(groupInfo.title, 15)}
                            </Text>
                            <IconUsers color={isInCurrentDialog ? '#fff' : colors.chevrons.active} size={13}></IconUsers>
                            {isMuted && <IconBellOff color={isInCurrentDialog ? '#fff' : colors.chevrons.active} size={13}></IconBellOff>}
                            {isPinned && <IconPin color={isInCurrentDialog ? '#fff' : colors.chevrons.active} size={13}></IconPin>}
                        </Flex>
                        {usersTypeing.length <= 0 && <>
                            <Text component="div" c={
                                isInCurrentDialog ? '#fff' : colors.chevrons.active
                            } size={'xs'} style={{
                                maxWidth: '130px',
                                overflow: 'hidden',
                                textOverflow: 'ellipsis',
                                whiteSpace: 'nowrap',
                            }}>
                                {loading && <Skeleton height={10} mt={4} width={100}></Skeleton>}
                                {!loading && (
                                    <>
                                        <span style={{
                                            color: isInCurrentDialog ? '#fff' : theme.colors.blue[6]
                                        }}>{userInfo.title}: </span>
                                        <TextParser 
                                            __reserved_1={isInCurrentDialog} 
                                            noHydrate={true} 
                                            text={lastMessage.plain_message}
                                        ></TextParser>
                                    </>
                                )}
                            </Text>                        
                        </>}
                        {usersTypeing.length > 0 && <>
                            <Flex gap={5} align={'center'}>
                                <Text c={isInCurrentDialog ? '#fff' : theme.colors.blue[3]} fz={12}>{typingUser.title} {usersTypeing.length > 1 && 'and ' + (usersTypeing.length - 1)} typing </Text>
                                <Loader size={15} color={isInCurrentDialog ? '#fff' : theme.colors.blue[3]} type={'dots'}></Loader>
                            </Flex>
                        </>}
                    </Flex>
                    <Flex direction={'column'} align={'flex-end'} gap={8}>
                        {!loading && (
                            <Text c={сurrentDialogPublicKeyView == props.dialog_id ? '#fff' : colors.chevrons.active} fz={10}>
                                {new Date(lastMessage.timestamp).toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' })}
                            </Text>
                        )}
                        {loading && (
                            <Skeleton height={8} mt={4} width={30}></Skeleton>
                        )}
                        {lastMessage.delivered == DeliveredMessageState.DELIVERED && <>
                            {lastMessageFromMe && unreaded > 0 && 
                            <IconCheck stroke={3} color={isInCurrentDialog ? '#fff' : theme.colors.blue[3]} size={14}></IconCheck>}
                            {lastMessageFromMe && unreaded <= 0 && 
                            <IconChecks stroke={3} color={isInCurrentDialog ? '#fff' : theme.colors.blue[3]} size={14}></IconChecks>}                    
                        </>}
                        {(lastMessage.delivered == DeliveredMessageState.WAITING && (isMessageDeliveredByTime(lastMessage.timestamp, lastMessage.attachments.length))) && <>
                            <IconClock stroke={2} size={13} color={theme.colors.gray[5]}></IconClock>
                        </>}
                        {!loading && (lastMessage.delivered == DeliveredMessageState.ERROR || (!isMessageDeliveredByTime(lastMessage.timestamp, lastMessage.attachments.length) && lastMessage.delivered != DeliveredMessageState.DELIVERED)) && (
                            <IconAlertCircle stroke={3} size={15} color={colors.error}></IconAlertCircle>
                        )}
                        {unreaded > 0 && !lastMessageFromMe && !isMentioned(props.dialog_id) && <Badge 
                            color={isInCurrentDialog ? 'white' : (isMuted ? colors.chevrons.active : colors.brandColor)} 
                            c={isInCurrentDialog ? colors.brandColor : 'white'} 
                            size={'sm'} circle={unreaded < 10}>{unreaded > 99 ? '99+' : unreaded}</Badge>}
                        {isMentioned(props.dialog_id) && !lastMessageFromMe && <Badge size={'sm'} circle c={isInCurrentDialog ? colors.brandColor : 'white'} color={isInCurrentDialog ? 'white' : colors.brandColor}>@</Badge>}
                    </Flex>
                </Flex>
            </Flex>
            <Divider></Divider>
        </Box>
    )
}