"use client";

import { useMemo } from "react";
import EntriesList from "@/features/entries/components/entries-list";
import EntriesPanelHeader from "@/features/entries/components/entries-panel-header";
import EntriesPanelModals from "@/features/entries/components/entries-panel-modals";
import SchedulesList from "@/features/entries/components/schedules-list";
import useEntriesPanelCrud from "@/features/entries/components/use-entries-panel-crud";
import useEntriesPanelFilters from "@/features/entries/components/use-entries-panel-filters";
import useEntries from "@/features/entries/hooks/use-entries";
import useSchedules from "@/features/entries/hooks/use-schedules";
import useGroupSettings from "@/features/groups/hooks/use-group-settings";
import useTags from "@/features/tags/hooks/use-tags";
import { useEntryMutation } from "@/hooks/entry-mutation-context";
import { useGroupsContext } from "@/hooks/groups-context";
import { useNotificationsContext } from "@/hooks/notifications-context";
import useUserSettings from "@/hooks/use-user-settings";

type ListProgressSignalProps = {
    hasMore: boolean;
    shownCount: number;
    totalCount: number;
    noun: "entries" | "schedules";
};

function ListProgressSignal({ hasMore, shownCount, totalCount, noun }: ListProgressSignalProps) {
    if (totalCount <= 0) return null;

    return (
        <div
            className={`mt-3 flex items-center justify-center gap-2 rounded-lg border px-3 py-2 text-xs ${hasMore ? "border-accent-weak bg-accent-soft text-[color:var(--color-text)]" : "border-accent-weak bg-panel text-soft"}`}
            aria-live="polite"
        >
            <span className={`inline-flex h-5 w-5 items-center justify-center rounded-full border ${hasMore ? "border-accent bg-panel text-[color:var(--color-accent)]" : "border-accent-weak text-soft"}`}>
                {hasMore ? "\u21e3" : "\u2713"}
            </span>
            <span>
                {hasMore
                    ? `Keep scrolling for more ${noun} (${shownCount} of ${totalCount})`
                    : `You have reached the end of ${noun} (${totalCount} total)`}
            </span>
        </div>
    );
}

export default function EntriesPanel() {
    const { groups, activeGroupId } = useGroupsContext();
    const { entries, loading: entriesLoading, error: entriesError, createEntry, updateEntry, deleteEntry } = useEntries(activeGroupId);
    const { schedules, loading: schedulesLoading, error: schedulesError, createSchedule, updateSchedule, deleteSchedule } = useSchedules(activeGroupId);
    const { settings: userSettings } = useUserSettings();
    const { notify } = useNotificationsContext();
    const { notifyEntryMutation } = useEntryMutation();
    const { tags: tagSuggestions } = useTags(activeGroupId);
    const { settings: groupSettings } = useGroupSettings(activeGroupId);

    const activeGroup = groups.find(group => group.id === activeGroupId) || null;
    const canManageTags = Boolean(activeGroup && (activeGroup.role !== "MEMBER" || groupSettings.allowMemberTagManage));
    const emptyTagActionLabel = canManageTags
        ? "No Tags Assigned Yet - Click To Assign Tags"
        : "No Tags Assigned Yet - Contact Your Group Admin";

    const pageSize = Math.max(1, Number(userSettings.entryPanelPageSize || 10));

    const {
        entryTab,
        setEntryTab,
        filters,
        setFilters,
        filterOpen,
        setFilterOpen,
        activeFilterCount,
        filteredEntries,
        filteredSchedules,
        visibleEntries,
        visibleSchedules,
        hasMoreEntries,
        hasMoreSchedules,
        entriesLoadSentinelRef,
        schedulesLoadSentinelRef,
        clearFilters,
        onFilterAddTag,
        onFilterToggleTag
    } = useEntriesPanelFilters({ entries, schedules, pageSize });

    const {
        newEntryOpen,
        setNewEntryOpen,
        newScheduleOpen,
        setNewScheduleOpen,
        entryDetailsOpen,
        setEntryDetailsOpen,
        scheduleDetailsOpen,
        setScheduleDetailsOpen,
        confirmDeleteOpen,
        setConfirmDeleteOpen,
        deleteTarget,
        setDeleteTarget,
        selectedEntryIndex,
        entryRemovedTags,
        setEntryRemovedTags,
        scheduleRemovedTags,
        setScheduleRemovedTags,
        entryForm,
        setEntryForm,
        entryDetailsForm,
        setEntryDetailsForm,
        entryDetailsOriginal,
        scheduleForm,
        setScheduleForm,
        scheduleDetailsForm,
        setScheduleDetailsForm,
        scheduleDetailsOriginal,
        amountInputRef,
        tagsInputRef,
        handleEmptyTagAction,
        hasEntryChanges,
        hasScheduleChanges,
        submitNewEntry,
        submitNewSchedule,
        openEntryDetails,
        openScheduleDetails,
        submitEntryUpdate,
        submitScheduleUpdate,
        confirmDelete,
        prevEntry,
        nextEntry
    } = useEntriesPanelCrud({
        filteredEntries,
        schedules,
        createEntry,
        updateEntry,
        deleteEntry,
        createSchedule,
        updateSchedule,
        deleteSchedule,
        notify,
        notifyEntryMutation,
        canManageTags
    });

    const listCounts = useMemo(() => {
        return {
            entriesShown: visibleEntries.length,
            entriesTotal: filteredEntries.length,
            schedulesShown: visibleSchedules.length,
            schedulesTotal: filteredSchedules.length
        };
    }, [filteredEntries.length, filteredSchedules.length, visibleEntries.length, visibleSchedules.length]);

    return (
        <>
            <div className="space-y-4">
                <div className="panel panel-accent p-4">
                    <EntriesPanelHeader
                        entryTab={entryTab}
                        activeGroupId={activeGroupId}
                        activeFilterCount={activeFilterCount}
                        onTabChange={setEntryTab}
                        onOpenFilters={() => setFilterOpen(true)}
                        onOpenCreate={() => {
                            if (entryTab === "ENTRIES") {
                                setNewEntryOpen(true);
                                return;
                            }
                            setNewScheduleOpen(true);
                        }}
                    />

                    {entryTab === "ENTRIES" ? (
                        <>
                            <EntriesList
                                activeGroupId={activeGroupId}
                                loading={entriesLoading}
                                entries={entries}
                                visibleEntries={visibleEntries}
                                activeFilterCount={activeFilterCount}
                                onOpenDetails={entry => openEntryDetails(entry.id)}
                                onClearFilters={clearFilters}
                            />
                            <div ref={entriesLoadSentinelRef} className="h-1" aria-hidden="true" />
                            <ListProgressSignal
                                hasMore={hasMoreEntries}
                                shownCount={listCounts.entriesShown}
                                totalCount={listCounts.entriesTotal}
                                noun="entries"
                            />
                        </>
                    ) : (
                        <>
                            <SchedulesList
                                activeGroupId={activeGroupId}
                                loading={schedulesLoading}
                                schedules={schedules}
                                visibleSchedules={visibleSchedules}
                                activeFilterCount={activeFilterCount}
                                onOpenDetails={schedule => openScheduleDetails(schedule.id)}
                                onClearFilters={clearFilters}
                            />
                            <div ref={schedulesLoadSentinelRef} className="h-1" aria-hidden="true" />
                            <ListProgressSignal
                                hasMore={hasMoreSchedules}
                                shownCount={listCounts.schedulesShown}
                                totalCount={listCounts.schedulesTotal}
                                noun="schedules"
                            />
                        </>
                    )}
                </div>
            </div>

            <EntriesPanelModals
                activeGroupId={activeGroupId}
                entriesError={entriesError}
                schedulesError={schedulesError}
                tagSuggestions={tagSuggestions}
                canManageTags={canManageTags}
                emptyTagActionLabel={emptyTagActionLabel}
                handleEmptyTagAction={handleEmptyTagAction}
                filterOpen={filterOpen}
                setFilterOpen={setFilterOpen}
                filters={filters}
                setFilters={setFilters}
                activeFilterCount={activeFilterCount}
                clearFilters={clearFilters}
                onFilterAddTag={onFilterAddTag}
                onFilterToggleTag={onFilterToggleTag}
                newEntryOpen={newEntryOpen}
                setNewEntryOpen={setNewEntryOpen}
                entryForm={entryForm}
                setEntryForm={setEntryForm}
                submitNewEntry={submitNewEntry}
                amountInputRef={amountInputRef}
                tagsInputRef={tagsInputRef}
                newScheduleOpen={newScheduleOpen}
                setNewScheduleOpen={setNewScheduleOpen}
                scheduleForm={scheduleForm}
                setScheduleForm={setScheduleForm}
                submitNewSchedule={submitNewSchedule}
                entryDetailsOpen={entryDetailsOpen}
                setEntryDetailsOpen={setEntryDetailsOpen}
                entryDetailsForm={entryDetailsForm}
                setEntryDetailsForm={setEntryDetailsForm}
                entryDetailsOriginal={entryDetailsOriginal}
                hasEntryChanges={hasEntryChanges}
                submitEntryUpdate={submitEntryUpdate}
                entryRemovedTags={entryRemovedTags}
                setEntryRemovedTags={setEntryRemovedTags}
                prevEntry={prevEntry}
                nextEntry={nextEntry}
                selectedEntryIndex={selectedEntryIndex}
                filteredEntriesCount={filteredEntries.length}
                scheduleDetailsOpen={scheduleDetailsOpen}
                setScheduleDetailsOpen={setScheduleDetailsOpen}
                scheduleDetailsForm={scheduleDetailsForm}
                setScheduleDetailsForm={setScheduleDetailsForm}
                scheduleDetailsOriginal={scheduleDetailsOriginal}
                hasScheduleChanges={hasScheduleChanges}
                submitScheduleUpdate={submitScheduleUpdate}
                scheduleRemovedTags={scheduleRemovedTags}
                setScheduleRemovedTags={setScheduleRemovedTags}
                confirmDeleteOpen={confirmDeleteOpen}
                setConfirmDeleteOpen={setConfirmDeleteOpen}
                deleteTarget={deleteTarget}
                setDeleteTarget={setDeleteTarget}
                confirmDelete={confirmDelete}
            />
        </>
    );
}