import Location from '../../components/Location.vue';
import {
    Avatar,
    AvatarFallback,
    AvatarImage
} from '../../components/ui/avatar';
import { Badge } from '../../components/ui/badge';
import { Button } from '../../components/ui/button';
import {
    Tooltip,
    TooltipContent,
    TooltipTrigger,
    TooltipWrapper
} from '../../components/ui/tooltip';
import {
    ArrowUpDown,
    Ban,
    BellOff,
    Check,
    ImageOff,
    Link,
    MessageCircle,
    Reply,
    Tag,
    Trash2,
    X
} from 'lucide-vue-next';
import { storeToRefs } from 'pinia';

import { checkCanInvite, formatDateFilter } from '../../shared/utils';
import { i18n } from '../../plugin';
import {
    useGameStore,
    useGroupStore,
    useLocationStore,
    useUiStore,
    useUserStore,
    useWorldStore,
    useNotificationStore
} from '../../stores';

import Emoji from '../../components/Emoji.vue';

const { t, te } = i18n.global;

const isGroupId = (id) => typeof id === 'string' && id.startsWith('grp_');

export const createColumns = ({
    getNotificationCreatedAt,
    getNotificationCreatedAtTs,
    openNotificationLink,
    showFullscreenImageDialog,
    getSmallThumbnailUrl,
    acceptFriendRequestNotification,
    showSendInviteResponseDialog,
    showSendInviteRequestResponseDialog,
    acceptRequestInvite,
    sendNotificationResponse,
    hideNotification,
    hideNotificationPrompt,
    deleteNotificationLog,
    deleteNotificationLogPrompt
}) => {
    const { showUserDialog, showSendBoopDialog } = useUserStore();
    const { showWorldDialog } = useWorldStore();
    const { showGroupDialog } = useGroupStore();
    const { shiftHeld } = storeToRefs(useUiStore());
    const { currentUser } = storeToRefs(useUserStore());
    const { lastLocation } = storeToRefs(useLocationStore());
    const { isGameRunning } = storeToRefs(useGameStore());
    const { isNotificationExpired } = useNotificationStore();

    const canInvite = () => {
        const location = lastLocation.value?.location;
        return (
            Boolean(location) && isGameRunning.value && checkCanInvite(location)
        );
    };

    const getResponseIcon = (response, notificationType) => {
        if (response?.type === 'link') {
            return Link;
        }
        switch (response?.icon) {
            case 'check':
                return Check;
            case 'cancel':
                return X;
            case 'ban':
                return Ban;
            case 'bell-slash':
                return BellOff;
            case 'reply':
                return notificationType === 'boop' ? MessageCircle : Reply;
            default:
                return Tag;
        }
    };

    return [
        {
            accessorFn: (row) => getNotificationCreatedAtTs(row),
            id: 'created_at',
            size: 120,
            meta: { label: () => t('table.notification.date') },
            header: ({ column }) => (
                <Button
                    variant="ghost"
                    onClick={() =>
                        column.toggleSorting(column.getIsSorted() === 'asc')
                    }
                >
                    {t('table.notification.date')}
                    <ArrowUpDown class="ml-1 h-4 w-4" />
                </Button>
            ),
            sortingFn: (rowA, rowB, columnId) => {
                const a = rowA.getValue(columnId) ?? 0;
                const b = rowB.getValue(columnId) ?? 0;
                if (a !== b) {
                    return a - b;
                }

                const aId =
                    typeof rowA.original?.id === 'string'
                        ? rowA.original.id
                        : '';
                const bId =
                    typeof rowB.original?.id === 'string'
                        ? rowB.original.id
                        : '';
                return aId.localeCompare(bId);
            },
            cell: ({ row }) => {
                const createdAt = getNotificationCreatedAt(row.original);
                const shortText = formatDateFilter(createdAt, 'short');
                const longText = formatDateFilter(createdAt, 'long');

                return (
                    <Tooltip>
                        <TooltipTrigger asChild>
                            <span>{shortText}</span>
                        </TooltipTrigger>
                        <TooltipContent side="right">
                            <span>{longText}</span>
                        </TooltipContent>
                    </Tooltip>
                );
            }
        },
        {
            accessorKey: 'type',
            size: 180,
            header: () => t('table.notification.type'),
            meta: { label: () => t('table.notification.type') },
            cell: ({ row }) => {
                const original = row.original;
                const typeKey = `view.notification.filters.${original.type}`;
                const label = te(typeKey) ? t(typeKey) : original.type;

                if (original.type === 'invite') {
                    return (
                        <Badge variant="outline" class="text-muted-foreground">
                            {label}
                        </Badge>
                    );
                }

                if (
                    original.type === 'group.queueReady' ||
                    original.type === 'instance.closed'
                ) {
                    return (
                        <Badge variant="outline" class="text-muted-foreground">
                            <Tooltip>
                                <TooltipTrigger asChild>
                                    <span
                                        class="cursor-pointer"
                                        onClick={() =>
                                            showWorldDialog(original.location)
                                        }
                                    >
                                        {label}
                                    </span>
                                </TooltipTrigger>
                                <TooltipContent side="top">
                                    {original.location ? (
                                        <Location
                                            location={original.location}
                                            hint={original.worldName}
                                            grouphint={original.groupName}
                                            link={true}
                                        />
                                    ) : null}
                                </TooltipContent>
                            </Tooltip>
                        </Badge>
                    );
                }

                if (original.link) {
                    return (
                        <Badge variant="outline" class="text-muted-foreground">
                            <Tooltip>
                                <TooltipTrigger asChild>
                                    <span
                                        class="cursor-pointer"
                                        onClick={() =>
                                            openNotificationLink(original.link)
                                        }
                                    >
                                        {label}
                                    </span>
                                </TooltipTrigger>
                                <TooltipContent side="top">
                                    <span>{original.linkText}</span>
                                </TooltipContent>
                            </Tooltip>
                        </Badge>
                    );
                }

                return (
                    <Badge variant="outline" class="text-muted-foreground">
                        {label}
                    </Badge>
                );
            }
        },
        {
            accessorKey: 'senderUsername',
            meta: {
                class: 'overflow-hidden',
                label: () => t('table.notification.user')
            },
            size: 150,
            header: () => t('table.notification.user'),
            cell: ({ row }) => {
                const original = row.original;
                if (
                    original.senderUserId &&
                    !isGroupId(original.senderUserId)
                ) {
                    return (
                        <span class="table-user-text block w-full min-w-0 truncate">
                            <span
                                class="cursor-pointer block w-full min-w-0 truncate"
                                onClick={() =>
                                    showUserDialog(original.senderUserId)
                                }
                            >
                                {original.senderUsername}
                            </span>
                        </span>
                    );
                }

                if (original.link?.startsWith('user:')) {
                    return (
                        <span class="table-user-text block w-full min-w-0 truncate">
                            <span
                                class="cursor-pointer block w-full min-w-0 truncate"
                                onClick={() =>
                                    openNotificationLink(original.link)
                                }
                            >
                                {original.linkText || original.senderUsername}
                            </span>
                        </span>
                    );
                }

                if (
                    original.senderUsername &&
                    !isGroupId(original.senderUserId)
                ) {
                    return (
                        <span class="table-user-text block w-full min-w-0 truncate">
                            {original.senderUsername}
                        </span>
                    );
                }

                return null;
            }
        },
        {
            accessorKey: 'groupName',
            meta: {
                class: 'overflow-hidden',
                label: () => t('table.notification.group')
            },
            size: 150,
            header: () => t('table.notification.group'),
            cell: ({ row }) => {
                const original = row.original;
                const label =
                    original.senderUsername ||
                    original.groupName ||
                    original.data?.groupName ||
                    original.details?.groupName ||
                    original.linkText;

                if (
                    original.senderUserId &&
                    (original.type === 'groupChange' ||
                        isGroupId(original.senderUserId))
                ) {
                    return (
                        <span class="table-user-text block w-full min-w-0 truncate">
                            <span
                                class="cursor-pointer block w-full min-w-0 truncate"
                                onClick={() =>
                                    showGroupDialog(original.senderUserId)
                                }
                            >
                                {label}
                            </span>
                        </span>
                    );
                }

                if (
                    original.type === 'groupChange' &&
                    original.senderUsername
                ) {
                    return (
                        <span class="table-user-text block w-full min-w-0 truncate">
                            {original.senderUsername}
                        </span>
                    );
                }

                if (original.link?.startsWith('group:')) {
                    return (
                        <span class="table-user-text block w-full min-w-0 truncate">
                            <span
                                class="cursor-pointer block w-full min-w-0 truncate"
                                onClick={() =>
                                    openNotificationLink(original.link)
                                }
                            >
                                {original.data?.groupName || label}
                            </span>
                        </span>
                    );
                }

                if (original.link?.startsWith('event:')) {
                    return (
                        <span class="table-user-text block w-full min-w-0 truncate">
                            <span
                                class="cursor-pointer block w-full min-w-0 truncate"
                                onClick={() =>
                                    openNotificationLink(original.link)
                                }
                            >
                                {original.data?.groupName ||
                                    original.groupName ||
                                    label}
                            </span>
                        </span>
                    );
                }

                if (original.data?.groupName) {
                    return (
                        <span class="table-user-text block w-full min-w-0 truncate">
                            {original.data.groupName}
                        </span>
                    );
                }

                if (original.details?.groupName) {
                    return (
                        <span class="table-user-text block w-full min-w-0 truncate">
                            {original.details.groupName}
                        </span>
                    );
                }

                if (original.groupName) {
                    return (
                        <span class="table-user-text block w-full min-w-0 truncate">
                            {original.groupName}
                        </span>
                    );
                }

                return null;
            }
        },
        {
            accessorKey: 'photo',
            size: 80,
            header: () => t('table.notification.photo'),
            meta: { label: () => t('table.notification.photo') },
            cell: ({ row }) => {
                const original = row.original;
                if (original.type === 'boop') {
                    const imageUrl =
                        original.details?.imageUrl || original.imageUrl;
                    if (!imageUrl || imageUrl.startsWith('default_')) {
                        return null;
                    }
                    return (
                        <Emoji
                            class="cursor-pointer h-7.5 w-7.5 rounded object-cover"
                            onClick={() => showFullscreenImageDialog(imageUrl)}
                            imageUrl={imageUrl}
                            size={30}
                        />
                    );
                }

                if (original.details?.imageUrl) {
                    const detailsUrl = getSmallThumbnailUrl(
                        original.details.imageUrl
                    );
                    return (
                        <Avatar
                            class="cursor-pointer size-7.5 rounded"
                            onClick={() =>
                                showFullscreenImageDialog(
                                    original.details.imageUrl
                                )
                            }
                        >
                            <AvatarImage
                                src={detailsUrl}
                                class="object-cover"
                            />
                            <AvatarFallback class="rounded">
                                <ImageOff class="size-4 text-muted-foreground" />
                            </AvatarFallback>
                        </Avatar>
                    );
                }

                if (original.imageUrl) {
                    const imgUrl = getSmallThumbnailUrl(original.imageUrl);
                    return (
                        <Avatar
                            class="cursor-pointer size-7.5 rounded"
                            onClick={() =>
                                showFullscreenImageDialog(original.imageUrl)
                            }
                        >
                            <AvatarImage src={imgUrl} class="object-cover" />
                            <AvatarFallback class="rounded">
                                <ImageOff class="size-4 text-muted-foreground" />
                            </AvatarFallback>
                        </Avatar>
                    );
                }

                return null;
            }
        },
        {
            id: 'message',
            header: () => t('table.notification.message'),
            enableSorting: false,
            meta: {
                class: 'min-w-0 overflow-hidden',
                stretch: true,
                label: () => t('table.notification.message')
            },
            minSize: 100,
            cell: ({ row }) => {
                const original = row.original;
                return (
                    <div class="w-full min-w-0">
                        {original.type === 'invite' && original.details ? (
                            <div class="w-full min-w-0">
                                <Location
                                    location={original.details.worldId}
                                    hint={original.details.worldName}
                                    grouphint={original.details.groupName}
                                    link
                                />
                            </div>
                        ) : null}
                        {original.message && original.title ? (
                            <TooltipWrapper
                                content={`${original.title}, ${original.message}`}
                                delayDuration={500}
                            >
                                <span class="block w-full min-w-0 truncate">
                                    {`${original.title}, ${original.message}`}
                                </span>
                            </TooltipWrapper>
                        ) : null}
                        {!original.message && original.title ? (
                            <TooltipWrapper
                                content={original.title}
                                delayDuration={500}
                            >
                                <span class="block w-full min-w-0 truncate">
                                    {original.title}
                                </span>
                            </TooltipWrapper>
                        ) : null}
                        {original.message &&
                        !original.title &&
                        original.message !==
                            `This is a generated invite to ${original.details?.worldName}` ? (
                            <TooltipWrapper
                                content={original.message}
                                delayDuration={500}
                            >
                                <span class="block w-full min-w-0 truncate">
                                    {original.message}
                                </span>
                            </TooltipWrapper>
                        ) : null}
                        {!original.message &&
                        original.details?.inviteMessage ? (
                            <TooltipWrapper
                                content={original.details.inviteMessage}
                                delayDuration={500}
                            >
                                <span class="block w-full min-w-0 truncate">
                                    {original.details.inviteMessage}
                                </span>
                            </TooltipWrapper>
                        ) : null}
                        {!original.message &&
                        original.details?.requestMessage ? (
                            <TooltipWrapper
                                content={original.details.requestMessage}
                                delayDuration={500}
                            >
                                <span class="block w-full min-w-0 truncate">
                                    {original.details.requestMessage}
                                </span>
                            </TooltipWrapper>
                        ) : null}
                        {!original.message &&
                        original.details?.responseMessage ? (
                            <TooltipWrapper
                                content={original.details.responseMessage}
                                delayDuration={500}
                            >
                                <span class="block w-full min-w-0 truncate">
                                    {original.details.responseMessage}
                                </span>
                            </TooltipWrapper>
                        ) : null}
                    </div>
                );
            }
        },
        {
            id: 'action',
            meta: {
                class: 'text-right',
                label: () => t('table.notification.action')
            },
            size: 120,
            minSize: 120,
            maxSize: 120,
            header: () => t('table.notification.action'),
            enableSorting: false,
            cell: ({ row }) => {
                const original = row.original;
                const hasResponses = Array.isArray(original.responses);
                const showDecline =
                    original.type !== 'requestInviteResponse' &&
                    original.type !== 'inviteResponse' &&
                    original.type !== 'message' &&
                    original.type !== 'boop' &&
                    original.type !== 'groupChange' &&
                    !original.type?.includes('group.') &&
                    !original.type?.includes('moderation.') &&
                    !original.type?.includes('instance.') &&
                    !original.link?.startsWith('economy.');
                const showDeleteLog =
                    original.type !== 'friendRequest' &&
                    original.type !== 'ignoredFriendRequest';

                return (
                    <div class="flex items-center justify-end gap-2">
                        {original.senderUserId !== currentUser.value?.id &&
                        !isNotificationExpired(original) ? (
                            <span class="inline-flex items-center gap-2">
                                {original.type === 'friendRequest' ? (
                                    <Tooltip>
                                        <TooltipTrigger asChild>
                                            <button
                                                type="button"
                                                class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
                                                onClick={() =>
                                                    acceptFriendRequestNotification(
                                                        original
                                                    )
                                                }
                                            >
                                                <Check class="h-4 w-4" />
                                            </button>
                                        </TooltipTrigger>
                                        <TooltipContent side="top">
                                            <span>
                                                {t(
                                                    'view.notification.actions.accept'
                                                )}
                                            </span>
                                        </TooltipContent>
                                    </Tooltip>
                                ) : null}

                                {original.type === 'invite' ? (
                                    <Tooltip>
                                        <TooltipTrigger asChild>
                                            <button
                                                type="button"
                                                class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
                                                onClick={() =>
                                                    showSendInviteResponseDialog(
                                                        original
                                                    )
                                                }
                                            >
                                                <MessageCircle class="h-4 w-4" />
                                            </button>
                                        </TooltipTrigger>
                                        <TooltipContent side="top">
                                            <span>
                                                {t(
                                                    'view.notification.actions.decline_with_message'
                                                )}
                                            </span>
                                        </TooltipContent>
                                    </Tooltip>
                                ) : null}

                                {original.type === 'requestInvite' ? (
                                    <span class="inline-flex items-center">
                                        {canInvite() ? (
                                            <Tooltip>
                                                <TooltipTrigger asChild>
                                                    <button
                                                        type="button"
                                                        class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
                                                        onClick={() =>
                                                            acceptRequestInvite(
                                                                original
                                                            )
                                                        }
                                                    >
                                                        <Check class="h-4 w-4" />
                                                    </button>
                                                </TooltipTrigger>
                                                <TooltipContent side="top">
                                                    <span>
                                                        {t(
                                                            'view.notification.actions.invite'
                                                        )}
                                                    </span>
                                                </TooltipContent>
                                            </Tooltip>
                                        ) : null}
                                        <Tooltip>
                                            <TooltipTrigger asChild>
                                                <button
                                                    type="button"
                                                    class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
                                                    onClick={() =>
                                                        showSendInviteRequestResponseDialog(
                                                            original
                                                        )
                                                    }
                                                >
                                                    <MessageCircle class="h-4 w-4" />
                                                </button>
                                            </TooltipTrigger>
                                            <TooltipContent side="top">
                                                <span>
                                                    {t(
                                                        'view.notification.actions.decline_with_message'
                                                    )}
                                                </span>
                                            </TooltipContent>
                                        </Tooltip>
                                    </span>
                                ) : null}

                                {hasResponses
                                    ? original.responses.map((response) => {
                                          const onClick = () => {
                                              if (response.type === 'link') {
                                                  openNotificationLink(
                                                      response.data
                                                  );
                                                  return;
                                              }
                                              if (
                                                  response.icon === 'reply' &&
                                                  original.type === 'boop'
                                              ) {
                                                  showSendBoopDialog(
                                                      original.senderUserId
                                                  );
                                                  return;
                                              }
                                              sendNotificationResponse(
                                                  original.id,
                                                  original.responses,
                                                  response.type
                                              );
                                          };

                                          const ResponseIcon = getResponseIcon(
                                              response,
                                              original.type
                                          );

                                          return (
                                              <Tooltip
                                                  key={`${response.text}:${response.type}`}
                                              >
                                                  <TooltipTrigger asChild>
                                                      <button
                                                          type="button"
                                                          class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
                                                          onClick={onClick}
                                                      >
                                                          <ResponseIcon class="h-4 w-4" />
                                                      </button>
                                                  </TooltipTrigger>
                                                  <TooltipContent side="top">
                                                      <span>
                                                          {response.text}
                                                      </span>
                                                  </TooltipContent>
                                              </Tooltip>
                                          );
                                      })
                                    : null}

                                {showDecline ? (
                                    <Tooltip>
                                        <TooltipTrigger asChild>
                                            <button
                                                type="button"
                                                class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
                                                onClick={() =>
                                                    shiftHeld.value
                                                        ? hideNotification(
                                                              original
                                                          )
                                                        : hideNotificationPrompt(
                                                              original
                                                          )
                                                }
                                            >
                                                <X
                                                    class={
                                                        shiftHeld.value
                                                            ? 'h-4 w-4 text-red-600'
                                                            : 'h-4 w-4'
                                                    }
                                                />
                                            </button>
                                        </TooltipTrigger>
                                        <TooltipContent side="top">
                                            <span>
                                                {t(
                                                    'view.notification.actions.decline'
                                                )}
                                            </span>
                                        </TooltipContent>
                                    </Tooltip>
                                ) : null}

                                {original.type === 'group.queueReady' ? (
                                    <Tooltip>
                                        <TooltipTrigger asChild>
                                            <button
                                                type="button"
                                                class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
                                                onClick={() =>
                                                    shiftHeld.value
                                                        ? deleteNotificationLog(
                                                              original
                                                          )
                                                        : deleteNotificationLogPrompt(
                                                              original
                                                          )
                                                }
                                            >
                                                {shiftHeld.value ? (
                                                    <X class="h-4 w-4 text-red-600" />
                                                ) : (
                                                    <Trash2 class="h-4 w-4" />
                                                )}
                                            </button>
                                        </TooltipTrigger>
                                        <TooltipContent side="top">
                                            <span>
                                                {t(
                                                    'view.notification.actions.delete_log'
                                                )}
                                            </span>
                                        </TooltipContent>
                                    </Tooltip>
                                ) : null}
                            </span>
                        ) : null}
                        {showDeleteLog ? (
                            <Tooltip>
                                <TooltipTrigger asChild>
                                    <button
                                        type="button"
                                        class="inline-flex h-6 ml-1 items-center justify-center text-muted-foreground hover:text-foreground"
                                        onClick={() =>
                                            shiftHeld.value
                                                ? deleteNotificationLog(
                                                      original
                                                  )
                                                : deleteNotificationLogPrompt(
                                                      original
                                                  )
                                        }
                                    >
                                        {shiftHeld.value ? (
                                            <X class="h-4 w-4 text-red-600" />
                                        ) : (
                                            <Trash2 class="h-4 w-4" />
                                        )}
                                    </button>
                                </TooltipTrigger>
                                <TooltipContent side="top">
                                    <span>
                                        {t(
                                            'view.notification.actions.delete_log'
                                        )}
                                    </span>
                                </TooltipContent>
                            </Tooltip>
                        ) : null}
                    </div>
                );
            }
        },
        {
            id: 'trailing',
            header: () => null,
            enableSorting: false,
            enableResizing: false,
            size: 5,
            cell: () => null
        }
    ];
};
