import { usePublicKey } from "@/app/providers/AccountProvider/usePublicKey";
import { useUserInformation } from "@/app/providers/InformationProvider/useUserInformation";
import { getInitialsColor, isMessageDeliveredByTime } from "@/app/utils/utils";
import { Avatar, Box, Flex, MantineColor, Text, useComputedColorScheme, useMantineTheme } from "@mantine/core";
import { IconCheck, IconChecks, IconCircleCheck, IconCircleCheckFilled, IconCircleX, IconClock, IconTextCaption } from "@tabler/icons-react";
import { MessageError } from "../MessageError/MessageError";
import { DeliveredMessageState } from "@/app/providers/DialogProvider/DialogProvider";
import { Attachment, AttachmentType } from "@/app/providers/ProtocolProvider/protocol/packets/packet.message";
import { MessageAttachments } from "../MessageAttachments/MessageAttachments";
import { useAvatars } from "@/app/providers/AvatarProvider/useAvatars";
import { useContextMenu } from "@/app/providers/ContextMenuProvider/useContextMenu";
import { useNavigate } from "react-router-dom";
import { MessageReply, useReplyMessages } from "@/app/providers/DialogProvider/useReplyMessages";
import { useSetting } from "@/app/providers/SettingsProvider/useSetting";
import { useRosettaBreakpoints } from "@/app/hooks/useRosettaBreakpoints";
import { TextParser } from "../TextParser/TextParser";
import { useRosettaColors } from "@/app/hooks/useRosettaColors";
import { ATTACHMENTS_NOT_ALLOWED_TO_REPLY, ENTITY_LIMITS_TO_PARSE_IN_MESSAGE } from "@/app/constants";
import { useDialog } from "@/app/providers/DialogProvider/useDialog";
import { VerifiedBadge } from "../VerifiedBadge/VerifiedBadge";
import { useGroupMembers } from "@/app/providers/InformationProvider/useGroupMembers";


export enum MessageStyle {
    BUBBLES = 'bubbles',
    ROWS = 'rows'
}

export interface MessageProps {
    message: string;
    from_me?: boolean;
    readed?: boolean;
    avatar_no_render?: boolean;
    delivered: DeliveredMessageState;
    from: string;
    timestamp: number;
    message_id: string;
    attachments: Attachment[];
    replyed?: boolean;
    is_last_message_in_stack?: boolean;
    chacha_key_plain: string;
    parent?: MessageProps;
}

interface MessageSystemProps {
    message: string;
    c?: MantineColor;
}

export function MessageSystem(props: MessageSystemProps) {
    const [wallpaper] = useSetting<string>
            ('wallpaper', '');
    return (<>
        <Flex w={'100%'} mt={'xs'} mb={'xs'} justify={'center'} align={'center'}>
            <Box p={'sm'} style={{
                cursor: 'pointer',
                backgroundColor: wallpaper != '' ? (useComputedColorScheme() == 'light' ? 'white' : '#2C2E33') : 'transparent',
                maxWidth: 200,
                borderRadius: 10,
                padding: 0
            }}>
                <Flex h={8} align={'center'} justify={'center'}>
                    <Text fz={12} c={props.c || 'gray'} fw={600}>
                        {props.message}
                    </Text>
                </Flex>
            </Box>
        </Flex>
    </>);
}

export function Message(props: MessageProps) {
    const computedTheme = useComputedColorScheme();
    const theme = useMantineTheme();
    const publicKey = usePublicKey();
    const openContextMenu = useContextMenu();
    const colors = useRosettaColors();
    const navigate = useNavigate();
    const { isSelectionStarted,
        selectMessage,
        deselectMessage,
        isMessageSelected,
        translateMessagesToDialogInput
    } = useReplyMessages();
    const { dialog } = useDialog();
    const { md } = useRosettaBreakpoints();
    const { members } = useGroupMembers(dialog);

    const [showTimeInReplyMessages] = useSetting<boolean>
        ('showTimeInReplyMessages', false);
    const [wallpaper] = useSetting<string>
        ('wallpaper', '');

    const [userInfo] = useUserInformation(publicKey);
    const [opponent] = useUserInformation(props.from);
    const user = props.from_me ? userInfo : {
        ...opponent,
        avatar: ""
    };

    const messageReply: MessageReply = {
        timestamp: props.timestamp,
        publicKey: user.publicKey,
        message: props.message,
        attachments: props.attachments.filter(a => a.type != AttachmentType.MESSAGES),
        message_id: props.message_id
    };

    const avatars = useAvatars(user.publicKey);

    const [messageStyle] = useSetting<MessageStyle>
        ('messageStyle', MessageStyle.ROWS);

    const computedMessageStyle = props.replyed ? MessageStyle.ROWS : messageStyle;
    

    const navigateToUserProfile = () => {
        if (isSelectionStarted()) {
            return;
        }
        navigate(`/main/profile/${user.publicKey}`);
    }

    const canReply = () => {
        if (props.replyed) {
            return false;
        }
        if (messageReply.attachments.find((v) => ATTACHMENTS_NOT_ALLOWED_TO_REPLY.includes(v.type))) {
            return false;
        }
        if (messageReply.message.trim().length == 0 && messageReply.attachments.length == 0) {
            return false;
        }
        if (props.delivered != DeliveredMessageState.DELIVERED) {
            return false;
        }
        return true;
    }

    const onMessageSelectClick = () => {
        if (props.replyed || !canReply()) {
            return;
        }
        if (isMessageSelected(messageReply)) {
            deselectMessage(messageReply);
        } else {
            selectMessage(messageReply);
        }
    }

    const onDobuleClick = () => {
        if (!canReply()) {
            return;
        }
        if (isSelectionStarted()) {
            return;
        }
        selectMessage(messageReply);
        translateMessagesToDialogInput(dialog);
    }

    return (<>
        <Box onDoubleClick={onDobuleClick} onClick={isSelectionStarted() ? onMessageSelectClick : undefined} onContextMenu={() => !props.replyed && openContextMenu([
            {
                label: 'Copy Message',
                action: () => {
                    navigator.clipboard.writeText(props.message);
                },
                icon: <IconTextCaption size={14}></IconTextCaption>,
                cond: async () => {
                    return props.message.trim().length > 0;
                }
            },
            {
                label: !isMessageSelected(messageReply) ? 'Select' : 'Deselect',
                action: onMessageSelectClick,
                icon: !isMessageSelected(messageReply) ? <IconCircleCheck size={14}></IconCircleCheck> : <IconCircleX color={theme.colors.red[5]} size={14}></IconCircleX>,
                cond: () => {
                    return canReply();
                },
            }
        ])} p={'sm'} pt={props.avatar_no_render ? 0 : 'sm'} style={{
            cursor: 'pointer',
            userSelect: 'auto'
        }}>
            {computedMessageStyle == MessageStyle.ROWS && (
                <Flex direction={'row'} justify={'space-between'} gap={'sm'}>
                    <Flex direction={'row'} gap={'sm'}>
                        {(!props.avatar_no_render && (md || !props.replyed)) && <Avatar bg={avatars.length > 0 ? '#fff' : undefined} onClick={navigateToUserProfile} src={avatars.length > 0 ? avatars[0].avatar : undefined} name={user.title} variant={props.parent ? 'filled' : 'light'} color="initials"></Avatar>}
                        <Flex direction={'column'}>
                            <Flex direction={'row'} gap={3} align={'center'}>
                                {!props.avatar_no_render && (
                                    /** Только если не установлен флаг который 
                                     * запрещает рендеринг аватарки и имени*/
                                    <>
                                        <Text style={{
                                            userSelect: 'none'
                                        }} size={'sm'} onClick={navigateToUserProfile} c={getInitialsColor(user.title)} fw={500}>{user.title}</Text>
                                        {(members.length > 0 && members[0] == props.from) && (
                                            <VerifiedBadge size={18} color={'gold'} verified={3}></VerifiedBadge>
                                        )}
                                    </>
                                )}
                            </Flex>
                            {props.attachments.length > 0 &&
                                <Box ml={props.avatar_no_render ? 50 : undefined}>
                                    <MessageAttachments parent={props} chacha_key_plain={props.chacha_key_plain} text={props.message.trim()} key={props.message_id} timestamp={props.timestamp} delivered={props.delivered} attachments={props.attachments}></MessageAttachments>
                                </Box>
                            }
                            <Box style={{
                                whiteSpace: 'pre-wrap',
                                wordBreak: 'break-word',
                                userSelect: 'text',
                                fontSize: '13px',
                                color: messageStyle == MessageStyle.BUBBLES ? (computedTheme == 'light' ? (props.parent?.from_me ? 'white' : 'black') : 'white') : (computedTheme == 'light' ? 'black' : 'white')
                            }} ml={props.avatar_no_render ? 50 : undefined} onDoubleClick={(e) => e.stopPropagation()}>
                                <TextParser performanceEntityLimit={ENTITY_LIMITS_TO_PARSE_IN_MESSAGE} oversizeIfTextSmallerThan={1} text={props.message.trim()}></TextParser>
                            </Box>
                        </Flex>
                    </Flex>
                    <Flex gap={5} justify={'end'} align={'flex-start'} style={{ flexShrink: 0, minWidth: props.replyed ? 0 : 50 }}>
                        <Flex gap={5} justify={'end'} align={'center'}>
                            {!isSelectionStarted() && <>
                                {props.delivered == DeliveredMessageState.DELIVERED && <>
                                    {props.from_me && !props.readed && (
                                        <IconCheck color={theme.colors.gray[5]} stroke={3} size={16}></IconCheck>
                                    )}
                                    {props.from_me && props.readed && (
                                        <IconChecks stroke={3} size={16} color={theme.colors.blue[5]}></IconChecks>
                                    )}
                                </>}
                                {(props.delivered == DeliveredMessageState.WAITING && (isMessageDeliveredByTime(props.timestamp, props.attachments.length))) && <>
                                    <IconClock stroke={2} size={14} color={theme.colors.gray[5]}></IconClock>
                                </>}
                                {(props.delivered == DeliveredMessageState.ERROR || ((!isMessageDeliveredByTime(props.timestamp, props.attachments.length)) && props.delivered != DeliveredMessageState.DELIVERED)) && (
                                    <MessageError messageId={props.message_id} text={props.message}></MessageError>
                                )}
                            </>}
                            {(isSelectionStarted() && !props.replyed && canReply()) && <>
                                {isMessageSelected(messageReply) ?
                                    <IconCircleCheckFilled size={16} color={theme.colors.green[5]}></IconCircleCheckFilled>
                                    :
                                    <IconCircleCheck size={16} color={theme.colors.gray[5]}></IconCircleCheck>
                                }
                            </>}
                            {(isSelectionStarted() && !canReply() && !props.replyed) && <IconCircleX size={16} color={theme.colors.red[5]}></IconCircleX>}
                            {(showTimeInReplyMessages || !props.replyed) && <Text style={{
                                userSelect: 'none'
                            }} fz={12} c={colors.chevrons.active} w={30}>{
                                    new Date(props.timestamp).toLocaleTimeString('en-GB', {
                                        hour: '2-digit',
                                        minute: '2-digit'
                                    })
                                }</Text>}
                        </Flex>
                    </Flex>
                </Flex>
            )}
            {computedMessageStyle == MessageStyle.BUBBLES && (() => {
                const hasOnlyAttachments = props.attachments.length > 0 && props.message.trim().length === 0;
                
                return (
                    <Flex direction={props.from_me ? 'row-reverse' : 'row'} gap={'sm'} align={'flex-end'}>
                        {(md && props.is_last_message_in_stack) && (
                            <Avatar bg={avatars.length > 0 ? '#fff' : undefined} onClick={navigateToUserProfile} src={avatars.length > 0 ? avatars[0].avatar : undefined} name={user.title} color="initials" variant={wallpaper != '' ? 'filled' : 'light'} style={{ flexShrink: 0 }}></Avatar>
                        )}
                        {(md && !props.is_last_message_in_stack) && (
                            <Box style={{ width: 40, height: 40, flexShrink: 0 }}></Box>
                        )}
                        <Flex direction={'column'} align={props.from_me ? 'flex-end' : 'flex-start'} gap={4}>
                            {(!props.avatar_no_render && dialog.includes("#group") && wallpaper == '') && (
                                <Flex direction={'row'} ml={2} gap={3} align={'center'}>
                                    <Text style={{
                                        userSelect: 'none'
                                    }} size={'sm'} onClick={navigateToUserProfile} c={getInitialsColor(user.title)} fw={500}>{user.title}</Text>
                                    {(members.length > 0 && members[0] == props.from) && (
                                        <VerifiedBadge size={18} color={'gold'} verified={3}></VerifiedBadge>
                                    )}
                                </Flex>
                            )}
                            <Box style={{
                                backgroundColor: hasOnlyAttachments ? 'transparent' : (props.from_me 
                                    ? (computedTheme == 'light' ? theme.colors.blue[6] : theme.colors.blue[9])
                                    : (computedTheme == 'light' ? (wallpaper != '' ? 'white' : theme.colors.gray[3]) : theme.colors.dark[6])),
                                borderRadius: props.avatar_no_render ? '8px' : '12px',
                                //borderTopLeftRadius: (!props.from_me && props.avatar_no_render) ? '2px' : undefined,
                                //borderTopRightRadius: (props.from_me && props.avatar_no_render) ? '2px' : undefined,
                                padding: hasOnlyAttachments ? 0 : '8px 12px',
                                maxWidth: md ? '500px' : '280px',
                                position: 'relative',
                                marginLeft: !props.from_me && props.is_last_message_in_stack ? 2 : 0
                            }}>
                                {props.attachments.length > 0 &&
                                    <Box mb={props.message.trim().length > 0 ? 4 : 0}>
                                        <MessageAttachments parent={props} chacha_key_plain={props.chacha_key_plain} text={props.message.trim()} key={props.message_id} timestamp={props.timestamp} delivered={props.delivered} attachments={props.attachments}></MessageAttachments>
                                    </Box>
                                }
                                {props.message.trim().length > 0 && (
                                    <Box style={{
                                        whiteSpace: 'pre-wrap',
                                        wordBreak: 'break-word',
                                        userSelect: 'text',
                                        fontSize: '14px',
                                        color: props.from_me ? 'white' : (computedTheme == 'light' ? 'black' : 'white')
                                    }} onDoubleClick={(e) => e.stopPropagation()}>
                                        <TextParser __reserved_2 performanceEntityLimit={ENTITY_LIMITS_TO_PARSE_IN_MESSAGE} oversizeIfTextSmallerThan={1} text={props.message.trim()}></TextParser>
                                    </Box>
                                )}
                                <Flex gap={5} justify={'flex-end'} align={'center'} mt={hasOnlyAttachments ? 0 : 4} style={{
                                    ...(hasOnlyAttachments && props.attachments.find(a => a.type != AttachmentType.MESSAGES) ? {
                                        position: 'absolute',
                                        bottom: 8,
                                        right: 8,
                                        backgroundColor: 'rgba(0, 0, 0, 0.3)',
                                        padding: '3px 8px',
                                        borderRadius: '10px',
                                        backdropFilter: 'blur(4px)'
                                    } : {})
                                }}>
                                    {wallpaper != '' && dialog.includes("#group") && (
                                        <Text style={{
                                            userSelect: 'none',
                                            color: hasOnlyAttachments ? 'white' : (props.from_me ? (computedTheme == 'light' ? theme.colors.blue[2] : theme.colors.blue[4]) : (computedTheme == 'light' ? theme.colors.gray[6] : theme.colors.gray[4]))
                                        }} fz={11} mr={4}>
                                            {user.title}
                                        </Text>
                                    )}
                                    {!isSelectionStarted() && <>
                                        {props.delivered == DeliveredMessageState.DELIVERED && <>
                                            {props.from_me && !props.readed && (
                                                <IconCheck color={hasOnlyAttachments ? 'white' : theme.colors.gray[5]} stroke={3} size={14}></IconCheck>
                                            )}
                                            {props.from_me && props.readed && (
                                                <IconChecks stroke={3} size={14} color={hasOnlyAttachments ? 'white' : theme.colors.blue[2]}></IconChecks>
                                            )}
                                        </>}
                                        {(props.delivered == DeliveredMessageState.WAITING && (isMessageDeliveredByTime(props.timestamp, props.attachments.length))) && <>
                                            <IconClock stroke={2} size={12} color={hasOnlyAttachments ? 'white' : theme.colors.gray[5]}></IconClock>
                                        </>}
                                        {(props.delivered == DeliveredMessageState.ERROR || ((!isMessageDeliveredByTime(props.timestamp, props.attachments.length)) && props.delivered != DeliveredMessageState.DELIVERED)) && (
                                            <MessageError messageId={props.message_id} text={props.message}></MessageError>
                                        )}
                                    </>}
                                    {(isSelectionStarted() && !props.replyed && canReply()) && <>
                                        {isMessageSelected(messageReply) ?
                                            <IconCircleCheckFilled size={14} color={hasOnlyAttachments ? 'white' : theme.colors.green[5]}></IconCircleCheckFilled>
                                            :
                                            <IconCircleCheck size={14} color={hasOnlyAttachments ? 'white' : theme.colors.gray[5]}></IconCircleCheck>
                                        }
                                    </>}
                                    {(isSelectionStarted() && !canReply() && !props.replyed) && <IconCircleX size={14} color={hasOnlyAttachments ? 'white' : theme.colors.red[5]}></IconCircleX>}
                                    {(showTimeInReplyMessages || !props.replyed) && <Text style={{
                                        userSelect: 'none',
                                        color: hasOnlyAttachments ? 'white' : (props.from_me ? (computedTheme == 'light' ? theme.colors.blue[2] : theme.colors.blue[4]) : (computedTheme == 'light' ? theme.colors.gray[6] : theme.colors.gray[4]))
                                    }} fz={11}>
                                        {new Date(props.timestamp).toLocaleTimeString('en-GB', {
                                            hour: '2-digit',
                                            minute: '2-digit'
                                        })}
                                    </Text>}
                                </Flex>
                            </Box>
                        </Flex>
                    </Flex>
                );
            })()}
        </Box>
    </>);
}