import { router } from '@inertiajs/react';
import {
    ChevronDown,
    Clock3,
    LogOut,
    MessageSquare,
    Trash2,
} from 'lucide-react';
import type { CSSProperties, ReactNode } from 'react';
import { useState, useSyncExternalStore } from 'react';

import AppearanceToggle from '@/components/appearance-toggle';
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { LoadingIndicator } from '@/components/ui/loading-indicator';
import {
    Sidebar,
    SidebarContent,
    SidebarFooter,
    SidebarGroup,
    SidebarGroupContent,
    SidebarGroupLabel,
    SidebarHeader,
    SidebarInset,
    SidebarMenu,
    SidebarMenuButton,
    SidebarMenuItem,
    SidebarProvider,
    SidebarRail,
    SidebarTrigger,
    useSidebar,
} from '@/components/ui/sidebar';
import { clearAuthSession, getStoredAuthUser } from '@/lib/auth';
import type { ChatSessionResponse } from '@/lib/rag';
import { login, mahasiswa } from '@/routes';
import { show as showMahasiswaSession } from '@/routes/mahasiswa';

const sidebarStyle = {
    '--sidebar-width': '260px',
    '--sidebar-width-icon': '64px',
} as CSSProperties;

export type DeleteSessionResult = {
    ok: boolean;
    message?: string;
};

export function getStoredStudentName(): string {
    return getStoredAuthUser()?.name ?? 'Mahasiswa';
}

function subscribeToAuthStorage(onStoreChange: () => void): () => void {
    if (typeof window === 'undefined') {
        return () => {};
    }

    window.addEventListener('storage', onStoreChange);

    return () => window.removeEventListener('storage', onStoreChange);
}

export function useStoredStudentName(): string {
    return useSyncExternalStore(
        subscribeToAuthStorage,
        getStoredStudentName,
        () => 'Mahasiswa',
    );
}

export function isAbortError(error: unknown): boolean {
    return error instanceof DOMException && error.name === 'AbortError';
}

export function formatSessionTime(value?: string): string {
    if (!value) {
        return '';
    }

    const normalized = /[Zz]|[+-]\d{2}:?\d{2}$/.test(value) ? value : value + 'Z';
    const date = new Date(normalized);

    if (Number.isNaN(date.getTime())) {
        return value;
    }

    return new Intl.DateTimeFormat('en-US', {
        day: 'numeric',
        hour: 'numeric',
        minute: '2-digit',
        month: 'short',
    }).format(date);
}

function getInitials(name: string): string {
    return name
        .split(' ')
        .filter(Boolean)
        .slice(0, 2)
        .map((part) => part[0]?.toUpperCase())
        .join('');
}

function confirmLogout(): void {
    clearAuthSession();
    router.visit(login());
}

function StudentSidebarLogo() {
    const { state, toggleSidebar } = useSidebar();

    const handleLogoClick = (): void => {
        if (state === 'collapsed') {
            toggleSidebar();
        }
    };

    return (
        <button
            aria-label="Buka sidebar"
            className="student-logo-action"
            onClick={handleLogoClick}
            type="button"
        >
            <span className="student-logo-mark">
                <MessageSquare className="size-5" />
            </span>
        </button>
    );
}

function StudentSidebar({
    activeSessionId,
    chatSessions,
    isLoading,
    onDeleteSession,
    studentName,
}: {
    activeSessionId?: string;
    chatSessions: ChatSessionResponse[];
    isLoading: boolean;
    onDeleteSession?: (
        sessionId: string,
    ) => DeleteSessionResult | Promise<DeleteSessionResult>;
    studentName: string;
}) {
    const [isHistoryOpen, setIsHistoryOpen] = useState(true);
    const [deleteDialogMessage, setDeleteDialogMessage] = useState<string>();
    const [isDeletingSession, setIsDeletingSession] = useState(false);
    const [isLogoutDialogOpen, setIsLogoutDialogOpen] = useState(false);
    const [sessionToDelete, setSessionToDelete] =
        useState<ChatSessionResponse>();
    const { state, toggleSidebar } = useSidebar();
    const isSidebarCollapsed = state === 'collapsed';

    function handleDeleteDialogOpenChange(open: boolean): void {
        if (isDeletingSession) {
            return;
        }

        if (!open) {
            setSessionToDelete(undefined);
            setDeleteDialogMessage(undefined);
        }
    }

    async function handleConfirmDeleteSession(): Promise<void> {
        if (!sessionToDelete || !onDeleteSession) {
            return;
        }

        setIsDeletingSession(true);
        setDeleteDialogMessage(undefined);

        try {
            const result = await onDeleteSession(sessionToDelete.uuid_id);

            if (result.ok) {
                setSessionToDelete(undefined);

                return;
            }

            setDeleteDialogMessage(result.message);
        } finally {
            setIsDeletingSession(false);
        }
    }

    return (
        <>
            <Sidebar className="student-sidebar" collapsible="icon">
                <SidebarHeader className="student-sidebar-top">
                    <StudentSidebarLogo />
                    <SidebarTrigger className="student-sidebar-trigger" />
                </SidebarHeader>

                <SidebarContent className="student-sidebar-content">
                    <SidebarGroup className="student-history-group">
                        {isSidebarCollapsed ? (
                            <SidebarGroupContent>
                                <SidebarMenu className="student-history-list">
                                    <SidebarMenuItem>
                                        <SidebarMenuButton
                                            className="student-history-menu-button"
                                            tooltip="Riwayat Chat"
                                            onClick={() => {
                                                toggleSidebar();
                                                setIsHistoryOpen(true);
                                            }}
                                        >
                                            <Clock3 className="student-history-menu-icon size-4" />
                                            <span className="student-history-copy">
                                                <span className="student-history-title">
                                                    Riwayat Chat
                                                </span>
                                            </span>
                                        </SidebarMenuButton>
                                    </SidebarMenuItem>
                                </SidebarMenu>
                            </SidebarGroupContent>
                        ) : (
                            <>
                                <SidebarGroupLabel asChild>
                                    <button
                                        aria-expanded={isHistoryOpen}
                                        className="student-history-label"
                                        onClick={() =>
                                            setIsHistoryOpen(
                                                (currentState) => !currentState,
                                            )
                                        }
                                        type="button"
                                    >
                                        <Clock3 className="size-4" />
                                        <span>Riwayat Chat</span>
                                        <ChevronDown className="student-history-chevron" />
                                    </button>
                                </SidebarGroupLabel>

                                {isHistoryOpen && (
                                    <SidebarGroupContent>
                                        <SidebarMenu className="student-history-list">
                                            {isLoading && (
                                                <SidebarMenuItem>
                                                    <SidebarMenuButton
                                                        className="student-history-menu-button"
                                                        disabled
                                                    >
                                                        <Clock3 className="student-history-menu-icon size-4" />
                                                        <span className="student-history-copy">
                                                            <span className="student-history-title">
                                                                <LoadingIndicator
                                                                    label="Memuat riwayat"
                                                                    spinnerClassName="size-3"
                                                                />
                                                            </span>
                                                        </span>
                                                    </SidebarMenuButton>
                                                </SidebarMenuItem>
                                            )}

                                            {chatSessions.map((session) => {
                                                const sessionTime =
                                                    formatSessionTime(
                                                        session.last_message_at ??
                                                            session.updated_at ??
                                                            session.created_at,
                                                    );

                                                return (
                                                    <SidebarMenuItem
                                                        className="student-history-menu-item"
                                                        key={session.uuid_id}
                                                    >
                                                        <SidebarMenuButton
                                                            className="student-history-menu-button"
                                                            isActive={
                                                                session.uuid_id ===
                                                                activeSessionId
                                                            }
                                                            onClick={() =>
                                                                router.visit(
                                                                    showMahasiswaSession(
                                                                        session.uuid_id,
                                                                    ),
                                                                )
                                                            }
                                                            tooltip={
                                                                session.title
                                                            }
                                                            type="button"
                                                        >
                                                            <Clock3 className="student-history-menu-icon size-4" />
                                                            <span className="student-history-copy">
                                                                <span className="student-history-title">
                                                                    {
                                                                        session.title
                                                                    }
                                                                </span>
                                                                {sessionTime && (
                                                                    <span className="student-history-meta">
                                                                        {
                                                                            sessionTime
                                                                        }
                                                                    </span>
                                                                )}
                                                            </span>
                                                        </SidebarMenuButton>

                                                        {onDeleteSession && (
                                                            <button
                                                                aria-label={`Hapus sesi ${session.title}`}
                                                                className="student-history-delete"
                                                                onClick={(
                                                                    event,
                                                                ) => {
                                                                    event.stopPropagation();
                                                                    setSessionToDelete(
                                                                        session,
                                                                    );
                                                                    setDeleteDialogMessage(
                                                                        undefined,
                                                                    );
                                                                }}
                                                                type="button"
                                                            >
                                                                <Trash2 className="size-3" />
                                                            </button>
                                                        )}
                                                    </SidebarMenuItem>
                                                );
                                            })}
                                        </SidebarMenu>
                                    </SidebarGroupContent>
                                )}
                            </>
                        )}
                    </SidebarGroup>
                </SidebarContent>

                <SidebarFooter className="student-sidebar-footer">
                    <SidebarMenu>
                        <SidebarMenuItem>
                            <SidebarMenuButton
                                className="student-user-menu-button"
                                tooltip={studentName}
                            >
                                <Avatar className="student-user-avatar">
                                    <AvatarFallback>
                                        {getInitials(studentName) || 'AK'}
                                    </AvatarFallback>
                                </Avatar>
                                <span className="student-user-copy">
                                    <span className="student-user-name">
                                        {studentName}
                                    </span>
                                    <span className="student-user-role">
                                        Mahasiswa
                                    </span>
                                </span>
                            </SidebarMenuButton>
                        </SidebarMenuItem>

                        <SidebarMenuItem>
                            <SidebarMenuButton
                                className="student-logout-button"
                                onClick={() => setIsLogoutDialogOpen(true)}
                                tooltip="Logout"
                            >
                                <LogOut className="size-4" />
                                <span>Logout</span>
                            </SidebarMenuButton>
                        </SidebarMenuItem>
                    </SidebarMenu>
                </SidebarFooter>

                <SidebarRail />
            </Sidebar>

            <Dialog
                onOpenChange={handleDeleteDialogOpenChange}
                open={Boolean(sessionToDelete)}
            >
                <DialogContent className="student-delete-dialog">
                    <DialogHeader>
                        <DialogTitle>Hapus Riwayat Chat</DialogTitle>
                        <DialogDescription>
                            Sesi chat ini akan dihapus dari riwayat.
                        </DialogDescription>
                    </DialogHeader>

                    <div className="student-delete-dialog-body">
                        <p className="student-delete-copy">
                            Hapus sesi{' '}
                            <strong>
                                {sessionToDelete?.title ?? 'chat ini'}
                            </strong>
                            ?
                        </p>

                        {deleteDialogMessage && (
                            <p className="student-delete-error" role="alert">
                                {deleteDialogMessage}
                            </p>
                        )}
                    </div>

                    <DialogFooter className="student-delete-dialog-footer">
                        <Button
                            className="student-delete-cancel"
                            disabled={isDeletingSession}
                            onClick={() => handleDeleteDialogOpenChange(false)}
                            type="button"
                            variant="outline"
                        >
                            Batal
                        </Button>
                        <Button
                            className="student-delete-confirm"
                            disabled={isDeletingSession}
                            onClick={() => {
                                void handleConfirmDeleteSession();
                            }}
                            type="button"
                        >
                            {isDeletingSession ? (
                                <LoadingIndicator
                                    label="Menghapus"
                                    showSpinner={false}
                                />
                            ) : (
                                'Hapus'
                            )}
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>

            <Dialog
                onOpenChange={setIsLogoutDialogOpen}
                open={isLogoutDialogOpen}
            >
                <DialogContent className="student-delete-dialog">
                    <DialogHeader>
                        <DialogTitle>Keluar dari akun?</DialogTitle>
                        <DialogDescription>
                            Anda perlu login kembali untuk mengakses sesi chat.
                        </DialogDescription>
                    </DialogHeader>

                    <DialogFooter className="student-delete-dialog-footer">
                        <Button
                            className="student-delete-cancel"
                            onClick={() => setIsLogoutDialogOpen(false)}
                            type="button"
                            variant="outline"
                        >
                            Batal
                        </Button>
                        <Button
                            className="student-delete-confirm"
                            onClick={confirmLogout}
                            type="button"
                        >
                            Logout
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>
        </>
    );
}

export function StudentShell({
    activeSessionId,
    chatSessions,
    children,
    isLoadingSessions,
    onDeleteSession,
    studentName,
}: {
    activeSessionId?: string;
    chatSessions: ChatSessionResponse[];
    children: ReactNode;
    isLoadingSessions: boolean;
    onDeleteSession?: (
        sessionId: string,
    ) => DeleteSessionResult | Promise<DeleteSessionResult>;
    studentName: string;
}) {
    return (
        <SidebarProvider
            className="student-dashboard-shell"
            defaultOpen
            style={sidebarStyle}
        >
            <StudentSidebar
                activeSessionId={activeSessionId}
                chatSessions={chatSessions}
                isLoading={isLoadingSessions}
                onDeleteSession={onDeleteSession}
                studentName={studentName}
            />

            <SidebarInset className="student-workspace">
                <header className="student-topbar">
                    <SidebarTrigger className="md:hidden" />
                    <h1 className="student-brand-title">RAG Hub</h1>

                    <div className="student-topbar-actions">
                        <AppearanceToggle className="student-theme-toggle" />
                        <Button
                            className="student-new-session-button"
                            onClick={() => router.visit(mahasiswa())}
                            type="button"
                        >
                            + Sesi Baru
                        </Button>
                    </div>
                </header>

                {children}
            </SidebarInset>
        </SidebarProvider>
    );
}
