import React, { useState, useEffect } from 'react';
import { useSearchParams, useNavigate, useLocation } from 'react-router-dom';
import { Task } from '../../entities/Task';
import { Project } from '../../entities/Project';
import { Note } from '../../entities/Note';
import {
    loadInboxItemsToStore,
    loadMoreInboxItemsToStore,
    processInboxItemWithStore,
    deleteInboxItemWithStore,
    updateInboxItemWithStore,
} from '../../utils/inboxService';
import InboxItemDetail from './InboxItemDetail';
import { useToast } from '../Shared/ToastContext';
import { useTranslation } from 'react-i18next';
import { InboxIcon, InformationCircleIcon } from '@heroicons/react/24/outline';
import LoadingScreen from '../Shared/LoadingScreen';
import ProjectModal from '../Project/ProjectModal';
import NoteModal from '../Note/NoteModal';
import QuickCaptureInput from './QuickCaptureInput';
import { createTask } from '../../utils/tasksService';
import { createProject } from '../../utils/projectsService';
import { createNote } from '../../utils/notesService';
import { isUrl } from '../../utils/urlService';
import { fetchAreas } from '../../utils/areasService';
import { fetchProjects } from '../../utils/projectsService';
import { useStore } from '../../store/useStore';

const InboxItems: React.FC = () => {
    const { t } = useTranslation();
    const { showSuccessToast, showErrorToast } = useToast();
    const [searchParams, setSearchParams] = useSearchParams();
    const navigate = useNavigate();
    const location = useLocation();

    const [hasInitialized, setHasInitialized] = useState(false);

    const { inboxItems, isLoading, pagination } = useStore(
        (state) => state.inboxStore
    );
    const {
        areas,
        setAreas,
        setError: setAreasError,
    } = useStore((state) => state.areasStore);
    const {
        loadTags,
        hasLoaded: tagsHasLoaded,
        isLoading: tagsLoading,
    } = useStore((state) => state.tagsStore);

    const [projects, setProjects] = useState<Project[]>([]);

    const [isProjectModalOpen, setIsProjectModalOpen] = useState(false);
    const [isNoteModalOpen, setIsNoteModalOpen] = useState(false);
    const [isInfoExpanded, setIsInfoExpanded] = useState(false);

    const [projectToEdit, setProjectToEdit] = useState<Project | null>(null);
    const [noteToEdit, setNoteToEdit] = useState<Note | null>(null);

    const [currentConversionItemUid, setCurrentConversionItemUid] = useState<
        string | null
    >(null);

    useEffect(() => {
        const urlPageSize = searchParams.get('loaded');
        const currentLoadedCount = urlPageSize ? parseInt(urlPageSize, 10) : 20;

        loadInboxItemsToStore(true, currentLoadedCount);
        setHasInitialized(true);

        const loadInitialProjects = async () => {
            try {
                const projectData = await fetchProjects();
                setProjects(Array.isArray(projectData) ? projectData : []);
            } catch (error) {
                console.error('Failed to load initial projects:', error);
                setProjects([]);
            }
        };
        loadInitialProjects();

        const loadInitialAreas = async () => {
            try {
                const areasData = await fetchAreas();
                setAreas(areasData);
            } catch (error) {
                console.error('Failed to load initial areas:', error);
                setAreasError(true);
            }
        };
        loadInitialAreas();

        const loadInitialTags = async () => {
            if (!tagsHasLoaded && !tagsLoading) {
                try {
                    await loadTags();
                } catch (error) {
                    console.error('Failed to load initial tags:', error);
                }
            }
        };
        loadInitialTags();
        const handleForceReload = () => {
            setTimeout(() => {
                const currentInboxStore = useStore.getState().inboxStore;
                const currentCount = currentInboxStore.inboxItems.length;
                loadInboxItemsToStore(false, currentCount);
            }, 500);
        };

        const handleInboxItemsUpdated = (
            event: CustomEvent<{ count: number; firstItemContent: string }>
        ) => {
            if (event.detail.count > 0) {
                showSuccessToast(
                    t(
                        'inbox.newTelegramItem',
                        'New item from Telegram: {{content}}',
                        {
                            content: event.detail.firstItemContent,
                        }
                    )
                );

                if (event.detail.count > 1) {
                    showSuccessToast(
                        t(
                            'inbox.multipleNewItems',
                            '{{count}} more new items added',
                            {
                                count: event.detail.count - 1,
                            }
                        )
                    );
                }
            }
        };

        const pollInterval = setInterval(() => {
            const currentInboxStore = useStore.getState().inboxStore;
            const currentCount = currentInboxStore.inboxItems.length;
            loadInboxItemsToStore(false, currentCount);
        }, 15000);

        window.addEventListener('forceInboxReload', handleForceReload);
        window.addEventListener(
            'inboxItemsUpdated',
            handleInboxItemsUpdated as EventListener
        );

        return () => {
            clearInterval(pollInterval);
            window.removeEventListener('forceInboxReload', handleForceReload);
            window.removeEventListener(
                'inboxItemsUpdated',
                handleInboxItemsUpdated as EventListener
            );
        };
    }, [t, showSuccessToast]);

    useEffect(() => {
        if (!hasInitialized) return;

        const urlPageSize = searchParams.get('loaded');
        const urlLoadedCount = urlPageSize ? parseInt(urlPageSize, 10) : 0;

        if (inboxItems.length > 20 && inboxItems.length !== urlLoadedCount) {
            setSearchParams(
                { loaded: inboxItems.length.toString() },
                { replace: true }
            );
        } else if (inboxItems.length <= 20 && urlLoadedCount > 0) {
            setSearchParams({}, { replace: true });
        }
    }, [inboxItems.length, hasInitialized]);

    const handleProcessItem = async (
        uid: string,
        showToast: boolean = true
    ) => {
        try {
            await processInboxItemWithStore(uid);
            if (showToast) {
                showSuccessToast(t('inbox.itemProcessed'));
            }
        } catch (error) {
            console.error('Failed to process inbox item:', error);
            showErrorToast(t('inbox.processError'));
        }
    };

    const handleUpdateItem = async (
        uid: string,
        newContent: string
    ): Promise<void> => {
        try {
            await updateInboxItemWithStore(uid, newContent);
            showSuccessToast(t('inbox.itemUpdated'));
        } catch (error) {
            console.error('Failed to update inbox item:', error);
            showErrorToast(t('inbox.updateError'));
        }
    };

    const handleDeleteItem = async (uid: string) => {
        try {
            await deleteInboxItemWithStore(uid);
            showSuccessToast(t('inbox.itemDeleted'));
        } catch (error) {
            console.error('Failed to delete inbox item:', error);
            showErrorToast(t('inbox.deleteError'));
        }
    };

    const createTaskAndHandleConversion = async (
        taskData: Task,
        options: { inboxItemUid?: string; navigateAfterCreate?: boolean } = {}
    ) => {
        try {
            const createdTask = await createTask(taskData);
            const taskLink = (
                <span>
                    {t('task.created', 'Task')}{' '}
                    <a
                        href={`/task/${createdTask.uid}`}
                        className="text-green-200 underline hover:text-green-100"
                    >
                        {createdTask.name}
                    </a>{' '}
                    {t('task.createdSuccessfully', 'created successfully!')}
                </span>
            );
            showSuccessToast(taskLink);

            const inboxUid =
                options.inboxItemUid ?? currentConversionItemUid ?? undefined;

            if (inboxUid) {
                await handleProcessItem(inboxUid, false);
                if (!options.inboxItemUid) {
                    setCurrentConversionItemUid(null);
                }
            }

            if (options.navigateAfterCreate && createdTask.uid) {
                navigate(`/task/${createdTask.uid}`, { state: { from: location.pathname + location.search } });
            }

            return createdTask;
        } catch (error) {
            console.error('Failed to create task:', error);
            showErrorToast(t('task.createError'));
            throw error;
        } finally {
            if (options.inboxItemUid) {
                setCurrentConversionItemUid(null);
            }
        }
    };

    const handleOpenTaskModal = async (task: Task, inboxItemUid?: string) => {
        if (inboxItemUid) {
            setCurrentConversionItemUid(inboxItemUid);
        }

        try {
            await createTaskAndHandleConversion(task, {
                inboxItemUid,
                navigateAfterCreate: true,
            });
        } catch {
            // Errors are already reported via toast notifications
        }
    };

    const handleOpenProjectModal = async (
        project: Project | null,
        inboxItemUid?: string
    ) => {
        try {
            try {
                const areasData = await fetchAreas();
                setAreas(areasData);
            } catch (error) {
                console.error('Failed to load areas:', error);
                showErrorToast(t('area.loadError', 'Failed to load areas'));
                setAreas([]);
            }

            setProjectToEdit(project);

            if (inboxItemUid) {
                setCurrentConversionItemUid(inboxItemUid);
            }

            setIsProjectModalOpen(true);
        } catch (error) {
            console.error('Failed to open project modal:', error);
        }
    };

    const handleOpenNoteModal = async (
        note: Note | null,
        inboxItemUid?: string
    ) => {
        if (note && note.content && isUrl(note.content.trim())) {
            if (!note.tags) {
                note.tags = [{ name: 'bookmark' }];
            } else if (!note.tags.some((tag) => tag.name === 'bookmark')) {
                note.tags.push({ name: 'bookmark' });
            }
        }

        setNoteToEdit(note);

        if (inboxItemUid) {
            setCurrentConversionItemUid(inboxItemUid);
        }

        setIsNoteModalOpen(true);
    };

    const handleSaveTask = async (task: Task) => {
        await createTaskAndHandleConversion(task);
    };

    const handleSaveProject = async (project: Project) => {
        try {
            await createProject(project);
            showSuccessToast(t('project.createSuccess'));

            if (currentConversionItemUid !== null) {
                await handleProcessItem(currentConversionItemUid, false);
                setCurrentConversionItemUid(null);
            }
        } catch (error) {
            console.error('Failed to create project:', error);
            showErrorToast(t('project.createError'));
        }
    };

    const handleSaveNote = async (note: Note) => {
        try {
            const noteContent = note.content || '';
            const isBookmarkContent = isUrl(noteContent.trim());

            if (!note.tags) {
                note.tags = [];
            }

            if (
                isBookmarkContent &&
                !note.tags.some((tag) => tag.name === 'bookmark')
            ) {
                note.tags = [...note.tags, { name: 'bookmark' }];
            }

            await createNote(note);
            showSuccessToast(
                t('note.createSuccess', 'Note created successfully')
            );

            if (currentConversionItemUid !== null) {
                await handleProcessItem(currentConversionItemUid, false);
                setCurrentConversionItemUid(null);
            }

            setIsNoteModalOpen(false);
        } catch (error) {
            console.error('Failed to create note:', error);
            showErrorToast(t('note.createError', 'Failed to create note'));
        }
    };

    const handleCreateProject = async (name: string): Promise<Project> => {
        try {
            const project = await createProject({ name, status: 'planned' });
            showSuccessToast(t('project.createSuccess'));
            return project;
        } catch (error) {
            console.error('Failed to create project:', error);
            showErrorToast(t('project.createError'));
            throw error;
        }
    };

    const handleLoadMore = async () => {
        try {
            await loadMoreInboxItemsToStore();
        } catch (error) {
            console.error('Failed to load more inbox items:', error);
            showErrorToast(
                t('inbox.loadMoreError', 'Failed to load more items')
            );
        }
    };

    if (isLoading && inboxItems.length === 0) {
        return <LoadingScreen />;
    }

    return (
        <div className="w-full px-2 sm:px-4 lg:px-6 pt-4 pb-8">
            <div className="w-full max-w-5xl mx-auto">
                <div className="flex items-center mb-8 justify-between">
                    <div className="flex items-center">
                        <h1 className="text-2xl font-light">
                            {t('inbox.title')}
                        </h1>
                    </div>
                    <button
                        onClick={() => setIsInfoExpanded(!isInfoExpanded)}
                        className={`flex items-center hover:bg-blue-100/50 dark:hover:bg-blue-800/20 transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-inset rounded-lg${isInfoExpanded ? ' bg-blue-50/70 dark:bg-blue-900/20' : ''} p-2`}
                        aria-expanded={isInfoExpanded}
                        aria-label={
                            isInfoExpanded
                                ? 'Collapse info panel'
                                : 'Show inbox information'
                        }
                        title={isInfoExpanded ? 'Hide info' : 'About Inbox'}
                    >
                        <InformationCircleIcon className="h-5 w-5 text-blue-500" />
                        <span className="sr-only">
                            {isInfoExpanded ? 'Hide info' : 'About Inbox'}
                        </span>
                    </button>
                </div>

                <div
                    className={`transition-all duration-300 ease-in-out ${
                        isInfoExpanded
                            ? 'max-h-96 opacity-100 mb-6'
                            : 'max-h-0 opacity-0 mb-0'
                    } overflow-hidden`}
                >
                    <div className="bg-blue-50/50 dark:bg-blue-900/10 border border-blue-100 dark:border-blue-800/30 rounded-lg px-6 py-5 flex items-start gap-4">
                        <div className="flex-shrink-0">
                            <InformationCircleIcon className="h-12 w-12 text-blue-400 opacity-20" />
                        </div>
                        <div className="flex-1">
                            <p className="text-sm text-gray-600 dark:text-gray-300 leading-relaxed">
                                {t(
                                    'taskViews.inbox',
                                    "Inbox is where all uncategorized tasks are located. Tasks that have not been assigned to a project or don't have a due date will appear here. This is your 'brain dump' area where you can quickly note down tasks and organize them later."
                                )}
                            </p>
                        </div>
                    </div>
                </div>

                <QuickCaptureInput
                    onTaskCreate={handleSaveTask}
                    onNoteCreate={handleSaveNote}
                    projects={projects}
                    autoFocus={true}
                    openTaskModal={handleOpenTaskModal}
                    openProjectModal={handleOpenProjectModal}
                    openNoteModal={handleOpenNoteModal}
                    cardClassName="mb-4"
                />

                {inboxItems.length > 0 && (
                    <div className="space-y-4">
                        <div className="space-y-2">
                            {inboxItems.map((item) => (
                                <InboxItemDetail
                                    key={item.uid || item.id}
                                    item={item}
                                    onDelete={handleDeleteItem}
                                    onUpdate={handleUpdateItem}
                                    openTaskModal={handleOpenTaskModal}
                                    openProjectModal={handleOpenProjectModal}
                                    openNoteModal={handleOpenNoteModal}
                                    projects={projects}
                                />
                            ))}
                        </div>

                        {pagination.hasMore && (
                            <div className="flex justify-center pt-4">
                                <button
                                    onClick={handleLoadMore}
                                    disabled={isLoading}
                                    className="inline-flex items-center px-6 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
                                >
                                    {isLoading ? (
                                        <>
                                            <svg
                                                className="animate-spin -ml-1 mr-2 h-4 w-4 text-gray-500"
                                                xmlns="http://www.w3.org/2000/svg"
                                                fill="none"
                                                viewBox="0 0 24 24"
                                            >
                                                <circle
                                                    className="opacity-25"
                                                    cx="12"
                                                    cy="12"
                                                    r="10"
                                                    stroke="currentColor"
                                                    strokeWidth="4"
                                                ></circle>
                                                <path
                                                    className="opacity-75"
                                                    fill="currentColor"
                                                    d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
                                                ></path>
                                            </svg>
                                            {t('inbox.loading', 'Loading...')}
                                        </>
                                    ) : (
                                        <>
                                            <InboxIcon className="h-4 w-4 mr-2" />
                                            {t(
                                                'inbox.loadMore',
                                                'Load more inbox items'
                                            )}
                                        </>
                                    )}
                                </button>
                            </div>
                        )}

                        {inboxItems.length > 0 && (
                            <div className="text-center text-sm text-gray-500 dark:text-gray-400 pt-2">
                                {t(
                                    'inbox.showingItems',
                                    'Showing {{current}} of {{total}} items',
                                    {
                                        current: inboxItems.length,
                                        total: pagination.total,
                                    }
                                )}
                            </div>
                        )}
                    </div>
                )}

                {(() => {
                    return (
                        isProjectModalOpen &&
                        (() => {
                            try {
                                return (
                                    <ProjectModal
                                        isOpen={isProjectModalOpen}
                                        onClose={() => {
                                            setIsProjectModalOpen(false);
                                            setProjectToEdit(null);
                                        }}
                                        onSave={handleSaveProject}
                                        project={projectToEdit || undefined}
                                        areas={
                                            Array.isArray(areas) ? areas : []
                                        }
                                    />
                                );
                            } catch (error) {
                                console.error(
                                    'ProjectModal rendering error:',
                                    error
                                );
                                return null;
                            }
                        })()
                    );
                })()}

                {(() => {
                    try {
                        return (
                            <NoteModal
                                isOpen={isNoteModalOpen}
                                onClose={() => {
                                    setIsNoteModalOpen(false);
                                    setNoteToEdit(null);
                                }}
                                onSave={handleSaveNote}
                                note={noteToEdit}
                                projects={
                                    Array.isArray(projects) ? projects : []
                                }
                                onCreateProject={handleCreateProject}
                            />
                        );
                    } catch (error) {
                        console.error('NoteModal rendering error:', error);
                        return null;
                    }
                })()}
            </div>
        </div>
    );
};

export default InboxItems;
