import { useMemo } from 'react';
import { mockEmails, mockTasks } from '@/data/static';
import axios from 'axios';
import { toast } from 'sonner';
import EmailAddOnSidebar from '../addOns/addon-sidebars/emails/emails-sidebar';
import { EventAddOnSidebar } from '../addOns/addon-sidebars/events/events-sidebar';
import NoteAddOnSidebar from '../addOns/addon-sidebars/notes/notes-sidebar';
import ReminderSidebar from '../addOns/addon-sidebars/reminders/reminders-sidebar';
import { TaskAddOnSidebar } from '../addOns/addon-sidebars/tasks/tasks-sidebar';
import { TimelineGroup, TimelineItem } from './types';

export const ItemType = {
    TASK: 'task',
    NOTE: 'note',
    EMAIL: 'email',
    REMINDER: 'reminder',
    EVENT: 'event',
    MEETING: 'meeting',
    CALL: 'call',
} as const;

export type ItemTypeKey = typeof ItemType[keyof typeof ItemType];

interface TimelineHandlersProps {
    timelineData: TimelineGroup[];
    setTimelineData: React.Dispatch<React.SetStateAction<TimelineGroup[]>>;
    addOnOpen: (sidebar: { id: string; content: React.ReactNode }) => void;
    addOnClose: () => void;
    refetchData?: () => void;
}

export const useTimelineHandlers = ({ timelineData, setTimelineData, addOnOpen, addOnClose, refetchData }: TimelineHandlersProps) => {
    // Memoized helper to find items efficiently
    const findItem = (id: number): TimelineItem | undefined => {
        return timelineData.flatMap((group) => group.items).find((item) => item.id === id);
    };

    const findItemByType = (id: number, expectedType: ItemTypeKey): TimelineItem | undefined => {
        const item = findItem(id);
        if (item && item.type === expectedType) return item;
        return undefined;
    };

    const getDueDateFromMetadata = (item: TimelineItem): string => {
        return (item.metadata?.find((m: any) => m.label === 'Due Date')?.value as string) || '';
    };

    const getCreatorFromMetadata = (item: TimelineItem) => {
        return item.metadata?.[0]
            ? {
                  id: 1,
                  name: String(item.metadata[0].value),
                  avatar: null,
              }
            : undefined;
    };

    const getBaseTaskData = (item: TimelineItem) => ({
        id: item.id,
        title: item.title,
        description: item.description || '',
        priority: 'high',
        status: 'in-progress',
        due_date: getDueDateFromMetadata(item),
    });

    const getBaseNoteData = (item: TimelineItem) => ({
        id: item.id,
        uid: `note-${item.id}`,
        title: item.title,
        content: item.description || '',
        tag: 'Work',
        is_pinned: item.isPinned || false,
        is_favorite: false,
        created_by: 1,
        creator: getCreatorFromMetadata(item),
        followers: [],
        people: [],
        status: 1,
        status_name: 'ACTIVE',
        relation_type: null,
        relation_id: null,
        created_at: item.timestamp,
        updated_at: item.timestamp,
        favorites: false,
        deleted: false,
    });

    const openSidebar = (id: string, content: React.ReactNode) => {
        addOnOpen({ id, content });
    };

    const createSidebarContent = (mode: 'edit' | 'details', type: ItemTypeKey, initialData: any) => {
        const commonProps = { onClose: addOnClose };

        switch (type) {
            case ItemType.TASK:
                return (
                    <TaskAddOnSidebar
                        mode={mode}
                        initialTask={initialData}
                        refetchTasks={refetchData}
                        {...commonProps}
                    />
                );
            case ItemType.NOTE:
                return (
                    <NoteAddOnSidebar
                        mode={mode}
                        initialNote={initialData}
                        refetchNotes={refetchData}
                        {...commonProps}
                    />
                );
            case ItemType.REMINDER:
                return (
                    <ReminderSidebar
                        mode={mode}
                        initialReminder={initialData}
                        refetchReminders={refetchData}
                        {...commonProps}
                    />
                );
            case ItemType.EMAIL:
                return (
                    <EmailAddOnSidebar
                        mode={mode === 'edit' ? 'compose' : 'details'}
                        initialEmail={mockEmails[0]}
                        {...commonProps}
                    />
                );
            case ItemType.EVENT:
            case ItemType.MEETING:
                return <EventAddOnSidebar mode={mode} {...commonProps} />;
            default:
                toast.error('Unknown item type');
                return null;
        }
    };

    const onTaskDelete = (id: number, destroyRoute: string) => {
        const activityItem = findItem(id);

        if (!activityItem) {
            toast.error('Activity not found');
            return;
        }

        if (!confirm('Are you sure you want to delete this activity? This action cannot be undone.')) {
            return;
        }

        const routeName = destroyRoute + '.destroy';
        const routeUrl = route(routeName, id);

        axios
            .delete(routeUrl)
            .then((response) => {
                if (response.data.success) {
                    setTimelineData((prevData) =>
                        prevData.map((group) => ({
                            ...group,
                            items: group.items.filter((item: TimelineItem) => item.id !== id),
                        }))
                    );
                    toast.success(response.data.message || 'Deleted successfully');
                } else {
                    toast.error(response.data.message || 'Failed to delete');
                }
            })
            .catch((error) => {
                toast.error('Failed to delete activity: ' + (error.response?.data?.message || error.message));
            });
    };

    const onItemEdit = (id: number, type: ItemTypeKey) => {
        const item = findItemByType(id, type);

        if (!item) {
            toast.error(`${type.charAt(0).toUpperCase() + type.slice(1)} not found`);
            return;
        }

        let initialData: any;
        let sidebarType: ItemTypeKey;

        switch (type) {
            case ItemType.TASK:
                initialData = getBaseTaskData(item);
                sidebarType = ItemType.TASK;
                break;
            case ItemType.NOTE:
                initialData = getBaseNoteData(item);
                sidebarType = ItemType.NOTE;
                break;
            case ItemType.REMINDER:
                axios
                    .get(route('reminder.show', id))
                    .then((response) => {
                        openSidebar(type, createSidebarContent('edit', type, response.data));
                    })
                    .catch(() => {
                        toast.error('Failed to load reminder');
                    });
                return;
            case ItemType.EMAIL:
                initialData = mockEmails[0];
                sidebarType = ItemType.EMAIL;
                break;
            case ItemType.EVENT:
            case ItemType.MEETING:
                initialData = null;
                sidebarType = ItemType.EVENT;
                break;
            default:
                toast.error('Unknown item type');
                return;
        }

        openSidebar(sidebarType, createSidebarContent('edit', sidebarType, initialData));
    };

    const onItemView = (id: number, type: ItemTypeKey) => {
        const item = findItemByType(id, type);

        if (!item) {
            toast.error(`${type.charAt(0).toUpperCase() + type.slice(1)} not found`);
            return;
        }

        let initialData: any;

        switch (type) {
            case ItemType.TASK:
                initialData = mockTasks[0];
                break;
            case ItemType.NOTE:
                initialData = getBaseNoteData(item);
                break;
            case ItemType.REMINDER:
            case ItemType.EMAIL:
                initialData = mockEmails[0];
                break;
            case ItemType.EVENT:
            case ItemType.MEETING:
                initialData = null;
                break;
            default:
                toast.error('Unknown item type');
                return;
        }

        openSidebar(type, createSidebarContent('details', type, initialData));
    };

    const onTaskPin = (id: number) => {
        const activityItem = findItem(id);

        if (!activityItem) {
            toast.error('Activity not found');
            return;
        }

        const isCurrentlyPinned = activityItem.isPinned || false;
        const action = isCurrentlyPinned ? 'unpin' : 'pin';

        const routeMap: Record<string, string> = {
            [ItemType.NOTE]: `note.${action}`,
            [ItemType.TASK]: `task.${action}`,
            [ItemType.REMINDER]: `reminder.${action}`,
            [ItemType.EMAIL]: `email.${action}`,
            [ItemType.CALL]: `call.${action}`,
            [ItemType.MEETING]: `meeting.${action}`,
        };

        const routeName = routeMap[activityItem.type] || `activity-log.${action}`;

        axios
            .post(route(routeName, activityItem.id))
            .then((response) => {
                if (response.data.success) {
                    setTimelineData((prevData) =>
                        prevData.map((group) => ({
                            ...group,
                            items: group.items.map((item: TimelineItem) =>
                                item.id === id ? { ...item, isPinned: !isCurrentlyPinned } : item
                            ),
                        }))
                    );
                    toast.success(response.data.message);
                } else {
                    toast.error(response.data.message);
                }
            })
            .catch(() => {
                toast.error(`Failed to ${action} ${activityItem.type}`);
            });
    };

    return useMemo(
        () => ({
            onTaskDelete,
            onTaskEdit: (id: number) => onItemEdit(id, ItemType.TASK),
            onNoteEdit: (id: number) => onItemEdit(id, ItemType.NOTE),
            onEmailEdit: (id: number) => onItemEdit(id, ItemType.EMAIL),
            onReminderEdit: (id: number) => onItemEdit(id, ItemType.REMINDER),
            onEventEdit: (id: number) => onItemEdit(id, ItemType.EVENT),
            onTaskView: (id: number) => onItemView(id, ItemType.TASK),
            onNoteView: (id: number) => onItemView(id, ItemType.NOTE),
            onEmailView: (id: number) => onItemView(id, ItemType.EMAIL),
            onReminderView: (id: number) => onItemView(id, ItemType.REMINDER),
            onEventView: (id: number) => onItemView(id, ItemType.EVENT),
            handleEditByType: onItemEdit,
            handleViewByType: onItemView,
            onTaskPin,
        }),
        [timelineData, setTimelineData, addOnOpen, addOnClose, refetchData]
    );
};

// Keep backward compatibility
export const createTimelineHandlers = useTimelineHandlers;
