import React, { useState } from 'react';
import GreyRowBox from '@/components/elements/GreyRowBox';
import { Button } from '@/components/elements/button/index';
import FloatingMenu, {
    FloatingMenuItem,
    getFloatingMenuPosition,
} from './FloatingMenu';
import type { FloatingMenuPosition } from './FloatingMenu';

const cx = (...parts: Array<string | false | null | undefined>) => parts.filter(Boolean).join(' ');

type MenuKey = 'add' | 'more' | null;

interface FileActionsBarProps {
    selectedCount: number;
    sortBy: 'name' | 'size' | 'date' | 'type';
    sortDirection: 'asc' | 'desc';
    onSortChange: (sortBy: 'name' | 'size' | 'date' | 'type') => void;
    onNewFile: () => void;
    onNewFolder: () => void;
    onUploadFiles: () => void;
    onPullUrl: () => void;
    onDownload: () => void;
    onMoveToTrash: () => void;
    onDeletePermanently: () => void;
    onCompress: () => void;
    onRename: () => void;
    onMove: () => void;
    onPermissions: () => void;
    onProperties: () => void;
    onClearSelection: () => void;
    archiveLabel?: string;
}

interface ActionButtonProps {
    label: string;
    title?: string;
    danger?: boolean;
    disabled?: boolean;
    children: React.ReactNode;
    onClick: () => void;
    onPointerActivate?: (event: React.PointerEvent<HTMLButtonElement>) => void;
}

const ActionIcon: React.FC<React.SVGProps<SVGSVGElement>> = ({ className, ...props }) => (
    <svg className={cx('h-4 w-4 shrink-0', className)} fill='none' stroke='currentColor' viewBox='0 0 24 24' {...props} />
);

const ActionButton: React.FC<ActionButtonProps> = ({ label, title, disabled, children, onClick, onPointerActivate }) => {
    return (
        <Button.Text
            type='button'
            size={Button.Sizes.Small}
            disabled={disabled}
            title={title || label}
            aria-label={label}
            onPointerDown={(e) => {
                if (!onPointerActivate || disabled) return;
                e.preventDefault();
                e.stopPropagation();
                onPointerActivate(e);
            }}
            onClick={(e) => {
                e.preventDefault();
                if (onPointerActivate) return;
                onClick();
            }}
            className={cx(
                'h-8 min-w-[2rem] shrink-0 gap-1.5 px-2.5 text-xs',
                'disabled:cursor-not-allowed disabled:opacity-50 sm:min-w-0'
            )}
        >
            {children}
            <span className='hidden md:inline'>{label}</span>
        </Button.Text>
    );
};

const Separator = () => <div className='hidden h-7 w-px shrink-0 bg-neutral-700 md:block' />;

const FileActionsBar: React.FC<FileActionsBarProps> = ({
    selectedCount,
    onNewFile,
    onNewFolder,
    onUploadFiles,
    onPullUrl,
    onDownload,
    onMoveToTrash,
    onDeletePermanently,
    onCompress,
    onRename,
    onMove,
    onPermissions,
    onProperties,
    onClearSelection,
    archiveLabel = 'Archive',
}) => {
    const [openMenu, setOpenMenu] = useState<MenuKey>(null);
    const [menuPosition, setMenuPosition] = useState<FloatingMenuPosition | null>(null);

    const closeMenu = () => {
        setOpenMenu(null);
        setMenuPosition(null);
    };

    const openFloatingMenu = (menu: Exclude<MenuKey, null>, anchor: HTMLElement | null, align: 'left' | 'right') => {
        if (openMenu === menu) {
            closeMenu();
            return;
        }

        if (!anchor || typeof window === 'undefined') return;

        setMenuPosition(getFloatingMenuPosition(anchor, align));
        setOpenMenu(menu);
    };

    const runMenuAction = (action: () => void) => {
        closeMenu();
        action();
    };

    return (
        <div className='betterfiles-scope w-full'>
            <GreyRowBox
                className='w-full !items-center !p-2 shadow-2xl'
                $hoverable={false}
            >
                <div className='flex w-full flex-col gap-2 sm:flex-row sm:items-center'>
                    <div className='flex items-center justify-between gap-2 sm:justify-start'>
                        <GreyRowBox className='!px-3 !py-2' $hoverable={false}>
                            <span className='whitespace-nowrap text-sm font-semibold text-neutral-100'>
                                {selectedCount} selected
                            </span>
                        </GreyRowBox>

                        <Button.Text
                            type='button'
                            size={Button.Sizes.Small}
                            shape={Button.Shapes.IconSquare}
                            title='Clear selection'
                            aria-label='Clear selection'
                            onClick={onClearSelection}
                            className='sm:hidden'
                        >
                            <ActionIcon>
                                <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M6 18L18 6M6 6l12 12' />
                            </ActionIcon>
                        </Button.Text>
                    </div>

                    <div className='flex min-w-0 flex-1 flex-wrap items-center gap-2 sm:justify-end'>
                        <div className='relative shrink-0'>
                            <ActionButton
                                label='Add'
                                onClick={() => undefined}
                                onPointerActivate={(e) => openFloatingMenu('add', e.currentTarget, 'left')}
                            >
                                <ActionIcon>
                                    <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M12 5v14m7-7H5' />
                                </ActionIcon>
                            </ActionButton>
                            {openMenu === 'add' && (
                                <FloatingMenu position={menuPosition!} title='Add files' onClose={closeMenu}>
                                    <FloatingMenuItem label='New File' description='Create a file' icon={
                                        <ActionIcon>
                                            <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M9 13h6m-3-3v6m5 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.5L19 8.5V19a2 2 0 01-2 2z' />
                                        </ActionIcon>
                                    } onClick={() => runMenuAction(onNewFile)} />
                                    <FloatingMenuItem label='New Folder' description='Create a folder' icon={
                                        <ActionIcon>
                                            <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M9 13h6m-3-3v6M3 7a2 2 0 012-2h5l2 2h7a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2V7z' />
                                        </ActionIcon>
                                    } onClick={() => runMenuAction(onNewFolder)} />
                                    <FloatingMenuItem label='Upload' description='Upload from device' icon={
                                        <ActionIcon>
                                            <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M7 16a4 4 0 01-.88-7.9A5 5 0 0115.9 6H16a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12' />
                                        </ActionIcon>
                                    } onClick={() => runMenuAction(onUploadFiles)} />
                                    <FloatingMenuItem label='Pull from URL' description='Download into this server' icon={
                                        <ActionIcon>
                                            <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M7 16a4 4 0 01-.88-7.9A5 5 0 0115.9 6H16a5 5 0 011 9.9M9 19l3 3m0 0l3-3m-3 3V10' />
                                        </ActionIcon>
                                    } onClick={() => runMenuAction(onPullUrl)} />
                                </FloatingMenu>
                            )}
                        </div>

                        <Separator />

                    <ActionButton label='Move' onClick={onMove}>
                        <ActionIcon>
                            <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4' />
                        </ActionIcon>
                    </ActionButton>

                    <ActionButton
                        label='Rename'
                        disabled={selectedCount !== 1}
                        title={selectedCount === 1 ? 'Rename' : 'Select one item to rename'}
                        onClick={onRename}
                    >
                        <ActionIcon>
                            <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M15.232 5.232l3.536 3.536M4 20h4.586a1 1 0 00.707-.293l9.414-9.414a2 2 0 00-2.828-2.828L6.465 16.879a1 1 0 00-.293.707V20z' />
                        </ActionIcon>
                    </ActionButton>

                    <ActionButton label='Download' onClick={onDownload}>
                        <ActionIcon>
                            <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2M7 10l5 5m0 0l5-5m-5 5V4' />
                        </ActionIcon>
                    </ActionButton>

                    <ActionButton label={archiveLabel} onClick={onCompress}>
                        <ActionIcon>
                            <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M5 19a2 2 0 01-2-2V7a2 2 0 012-2h4l2 2h8a2 2 0 012 2v8a2 2 0 01-2 2H5z' />
                        </ActionIcon>
                    </ActionButton>

                    <div className='relative shrink-0'>
                        <ActionButton
                            label='More'
                            onClick={() => undefined}
                            onPointerActivate={(e) => openFloatingMenu('more', e.currentTarget, 'right')}
                        >
                            <ActionIcon>
                                <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M5 12h.01M12 12h.01M19 12h.01' />
                            </ActionIcon>
                        </ActionButton>
                        {openMenu === 'more' && (
                            <FloatingMenu position={menuPosition!} title='More actions' onClose={closeMenu}>
                                <FloatingMenuItem label='Permissions' description='Edit chmod values' icon={
                                    <ActionIcon>
                                        <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z' />
                                    </ActionIcon>
                                } onClick={() => runMenuAction(onPermissions)} />
                                <FloatingMenuItem label='Properties' description='View file details' icon={
                                    <ActionIcon>
                                        <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M9 12h6m-6 4h6M9 8h6M7 4h10a2 2 0 012 2v12a2 2 0 01-2 2H7a2 2 0 01-2-2V6a2 2 0 012-2z' />
                                    </ActionIcon>
                                } onClick={() => runMenuAction(onProperties)} />
                            </FloatingMenu>
                        )}
                    </div>

                    <Separator />

                    <ActionButton label='Trash' title='Move to Trash' onClick={onMoveToTrash}>
                        <ActionIcon>
                            <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6M4 7h16m-5 0V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3' />
                        </ActionIcon>
                    </ActionButton>

                    <ActionButton label='Delete' title='Delete Permanently' danger onClick={onDeletePermanently}>
                        <ActionIcon>
                            <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M6 18L18 6M6 6l12 12' />
                        </ActionIcon>
                    </ActionButton>

                    <Button.Text
                        type='button'
                        size={Button.Sizes.Small}
                        shape={Button.Shapes.IconSquare}
                        title='Clear selection'
                        aria-label='Clear selection'
                        onClick={onClearSelection}
                        className='hidden shrink-0 sm:inline-flex'
                    >
                        <ActionIcon>
                            <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M6 18L18 6M6 6l12 12' />
                        </ActionIcon>
                    </Button.Text>
                </div>
            </div>
            </GreyRowBox>
        </div>
    );
};

export default FileActionsBar;
