import { useState, useMemo, useCallback } from "react";
import { useTranslation } from "react-i18next";
import { Button, Tooltip, useModals } from "@gouvfr-lasuite/cunningham-react";
import { DropdownMenu, Icon, IconType } from "@gouvfr-lasuite/ui-kit";
import { getMessagesEmlRetrieveUrl } from "@/features/api/gen/messages/messages";
import { getRequestUrl } from "@/features/api/utils";
import { useMailboxContext } from "@/features/providers/mailbox";
import usePrint from "@/features/message/use-print";
import useRead from "@/features/message/use-read";
import useSplitThread from "@/features/message/use-split-thread";
import useTrash from "@/features/message/use-trash";
import { FEATURE_KEYS, useFeatureFlag } from "@/hooks/use-feature";
import useAbility, { Abilities } from "@/hooks/use-ability";
import useCopyDeepLink from "@/features/message/use-copy-deep-link";
import { ThreadMessageActionsProps } from "./types";

const ThreadMessageActions = ({
    message,
    isFolded,
    isLatest,
    canSendMessages,
    hasSeveralRecipients,
    onSetReplyFormMode,
    onToggleFold,
}: ThreadMessageActionsProps) => {
    const { t } = useTranslation();
    const [isDropdownOpen, setIsDropdownOpen] = useState(false);

    // Hooks and state specific to actions
    const { unselectThread, selectedThread } = useMailboxContext();
    const copyDeepLink = useCopyDeepLink();
    const { markAsReadAt } = useRead();
    const { markAsTrashed } = useTrash();
    const { splitThread } = useSplitThread();
    const { print } = usePrint();
    const modals = useModals();
    const isThreadSplitEnabled = useFeatureFlag(FEATURE_KEYS.THREAD_SPLIT);
    // Full edit rights on the thread — required for reply/forward/delete/split.
    // Mark read/unread, print and download are either read-only
    // or personal actions and stay available to viewers.
    const canEditThread = useAbility(Abilities.CAN_EDIT_THREAD, selectedThread ?? null);
    const canReply = canSendMessages && canEditThread;

    const hasSiblingMessages = useMemo(() => {
        if (!selectedThread) return false;
        return selectedThread?.messages?.length > 1;
    }, [selectedThread]);

    const canSplitThread = useMemo(() => {
        if (!isThreadSplitEnabled || !canEditThread) return false;
        if (!selectedThread || !hasSiblingMessages) return false;
        if (message.is_draft) return false;
        // Cannot split at the first message
        if (selectedThread.messages[0] === message.id) return false;
        return true;
    }, [isThreadSplitEnabled, selectedThread, hasSiblingMessages, message.id, message.is_draft, canEditThread]);

    // Handlers specific to actions
    const toggleReadStateFrom = useCallback((is_unread: boolean) => {
        if (!selectedThread) return;
        if (is_unread) {
            // Mark as unread from here: subtract 1ms so this message becomes unread.
            // `unselectThread()` unmounts the thread view synchronously, tearing
            // down its auto-mark-as-read observer before this mutation's cache
            // patch lands — otherwise the observer would re-read the messages we
            // just flagged unread.
            const readAt = new Date(new Date(message.created_at!).getTime() - 1).toISOString();
            unselectThread();
            markAsReadAt({ threadIds: [selectedThread.id], readAt });
        } else {
            // Mark as read from here: read up to this message's created_at
            markAsReadAt({ threadIds: [selectedThread.id], readAt: message.created_at! });
        }
    }, [message.id, message.created_at, unselectThread, selectedThread, markAsReadAt]);

    const handleMarkAsTrashed = useCallback(() => {
        markAsTrashed({ messageIds: [message.id] });
    }, [markAsTrashed, message.id]);

    const handleSplitThread = useCallback(async () => {
        if (!selectedThread) return;
        const decision = await modals.confirmationModal({
            titleIcon: <Icon type={IconType.FILLED} name="call_split" />,
            title: <span className="c__modal__text--centered">{t('Split thread')}</span>,
            children: t('This will move this message and all following messages to a new thread. Continue?'),
        });
        if (decision !== 'yes') return;
        splitThread({ threadId: selectedThread.id, messageId: message.id });
    }, [selectedThread, splitThread, message.id, t, modals]);

    const handleDownloadRawEmail = useCallback(() => {
        const downloadUrl = getRequestUrl(getMessagesEmlRetrieveUrl(message.id));
        const link = document.createElement('a');
        link.href = downloadUrl;
        link.download = `message-${message.id}.eml`;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    }, [message.id]);

    const dropdownOptions = [
        ...(canReply && hasSeveralRecipients ? [{
            label: t('Reply all'),
            icon: <Icon type={IconType.FILLED} name="reply_all" />,
            callback: () => onSetReplyFormMode('reply_all')
        }] : []),
        ...(canReply ? [{
            label: t('Forward'),
            icon: <Icon type={IconType.FILLED} name="forward" />,
            callback: () => onSetReplyFormMode('forward'),
            showSeparator: true
        }] : []),
        ...(message.is_unread ? [{
            label: hasSiblingMessages ? t('Mark as read from here') : t('Mark as read'),
            icon: <Icon type={IconType.FILLED} name="drafts" />,
            callback: () => toggleReadStateFrom(false)
        }] :
        [{
            label: hasSiblingMessages ? t('Mark as unread from here') : t('Mark as unread'),
            icon: <Icon type={IconType.FILLED} name="mark_email_unread" />,
            callback: () => toggleReadStateFrom(true)
        }]),
        ...(canSplitThread ? [{
            label: t('Split thread from here'),
            icon: <Icon type={IconType.FILLED} name="call_split" />,
            callback: handleSplitThread,
        }] : []),
        {
            label: t('Copy link to message'),
            icon: <Icon type={IconType.FILLED} name="link" />,
            callback: () => copyDeepLink({ messageId: message.id }),
            showSeparator: true,
        },
        {
            label: t('Print'),
            icon: <Icon type={IconType.FILLED} name="print" />,
            callback: () => print(message)
        },
        {
            label: t('Download raw email'),
            icon: <Icon type={IconType.FILLED} name="download" />,
            callback: handleDownloadRawEmail
        },
        ...(canEditThread && !message.is_trashed ? [{
            label: t('Delete'),
            icon: <Icon type={IconType.FILLED} name="delete" />,
            callback: handleMarkAsTrashed
        }] : []),
    ];

    return (
        <div className="thread-message__header-actions">
            {!isFolded && (
                <>
                    {canReply && (
                        <Tooltip content={t('Reply')}>
                            <Button
                                color="brand"
                                variant="tertiary"
                                size="small"
                                icon={<Icon type={IconType.FILLED} name="reply" />}
                                aria-label={t('Reply')}
                                onClick={() => onSetReplyFormMode('reply')}
                            />
                        </Tooltip>
                    )}
                    <DropdownMenu
                        isOpen={isDropdownOpen}
                        onOpenChange={setIsDropdownOpen}
                        options={dropdownOptions}
                    >
                        <Tooltip content={t('More options')}>
                            <Button
                                onClick={() => setIsDropdownOpen(true)}
                                icon={<Icon type={IconType.FILLED} name="more_vert" />}
                                color="brand"
                                variant="tertiary"
                                aria-label={t('More options')}
                                size="small"
                            />
                        </Tooltip>
                    </DropdownMenu>
                </>
            )}
            {!isLatest && (
                <Tooltip content={isFolded ? t('Unfold message') : t('Fold message')}>
                    <Button
                        color="brand"
                        variant="tertiary"
                        size="small"
                        icon={<Icon type={IconType.FILLED} name={isFolded ? "unfold_more" : "unfold_less"} />}
                        aria-label={isFolded ? t('Unfold message') : t('Fold message')}
                        onClick={onToggleFold}
                    />
                </Tooltip>
            )}
        </div>
    );
};

export default ThreadMessageActions;
