import {
    useEffect,
    useRef,
    useState,
} from 'react';

import {
    ChartAreaIcon,
    Edit,
    MenuSquareIcon,
    PlusCircleIcon,
    PlusSquareIcon,
} from 'lucide-react';

import { rpc } from '@/api/request';
import {
    BiBlockType,
    ShmBiBoardType,
} from '@/api/types';
import { Lang } from '@/lang/Lang';
import {
    DndContext,
    DragEndEvent,
    PointerSensor,
    useSensor,
    useSensors,
} from '@dnd-kit/core';
import {
    arrayMove,
    rectSortingStrategy,
    SortableContext,
} from '@dnd-kit/sortable';

import AnyDropdownMenu from '../AnyDropdownMenu';
import { confirmAlertRef } from '../ConfirmAlert';
import { inputDialogRef } from '../InputDialog';
import { Button } from '../ui/button';
import { GridRow } from '../ui/grid';
import BIBlockDialog, { BIBlockDialogRef } from './components/BIBlockDialog';
import BIBlockView from './components/BIBlockView';
import { getBlockSizes } from './utils/blockSizes';

// Константы для CSS Grid
const UNIT_WIDTH = '1fr'; // 1 колонка из 24
export const UNIT_HEIGHT = 150; // Высота одной строки

const BIView = () => {
    const biBlockDialogRef = useRef<BIBlockDialogRef>(null);

    const sensors = useSensors(
        useSensor(PointerSensor, {
            activationConstraint: {
                distance: 8,
            },
        })
    );

    const [boards, setBoards] = useState<ShmBiBoardType[]>([]);

    const [selectedBoard, setSelectedBoard] = useState<ShmBiBoardType | null>(null);

    useEffect(() => {

        if (boards.length > 0) {

            if (!selectedBoard) {
                setSelectedBoard(boards[0] ?? null);
            }

            if (selectedBoard) {

                let _selectedBoard = boards.find((board) => board._id === selectedBoard?._id);
                if (_selectedBoard) {
                    setSelectedBoard(_selectedBoard);
                } else {
                    setSelectedBoard(boards[0] ?? null);
                }
            }
        }

    }, [boards])

    const loadBoards = () => {
        rpc.biBoards().then((res) => {
            setBoards(res?.result ?? []);
        });
    }

    const addBlockOnBoard = (data: BiBlockType) => {
        if (!selectedBoard) return;

        // Генерируем uuid, если его нет
        const uuid = data.uuid ?? crypto.randomUUID();

        // Устанавливаем colSpan и rowSpan на основе типа, если они не заданы
        const sizes = getBlockSizes(data.type);
        const blockWithSizes: BiBlockType = {
            ...data,
            uuid,
            colSpan: data.colSpan ?? sizes.colSpan,
            rowSpan: data.rowSpan ?? sizes.rowSpan,
        };

        rpc.updateBiBoard({
            _id: selectedBoard?._id,
            board: {
                ...selectedBoard,
                blocks: [...(selectedBoard?.blocks ?? []), blockWithSizes]
            }
        }).then((res) => {
            loadBoards();
        });
    }

    const editBlockOnBoard = (block: BiBlockType) => {
        biBlockDialogRef.current?.open({
            data: block,
            onSave: (data) => {
                if (!selectedBoard) return;
                const updatedBlocks = (selectedBoard.blocks ?? []).map(b =>
                    b.uuid === block.uuid ? { ...data, uuid: block.uuid, colSpan: b.colSpan, rowSpan: b.rowSpan } : b
                );
                const updatedBoard = { ...selectedBoard, blocks: updatedBlocks };
                rpc.updateBiBoard({ _id: selectedBoard._id, board: updatedBoard }).then(() => {
                    setSelectedBoard(updatedBoard);
                    loadBoards();
                });
            }
        });
    };

    const deleteBlockOnBoard = (uuid?: string) => {
        if (!selectedBoard) return;

        if (!uuid) return;


        confirmAlertRef.current?.open({
            title: Lang.key('delete_bi_view_block'),
            description: Lang.key('delete_bi_view_block_description'),
            buttons: [
                {
                    label: Lang.key('cancel'),
                    onClick: () => {
                        return;
                    }
                },
                {
                    label: Lang.key('delete'),
                    onClick: () => {
                        const updatedBoard = {
                            ...selectedBoard,
                            blocks: selectedBoard.blocks?.filter((block) => block.uuid !== uuid) ?? [],
                        };
                        setSelectedBoard(updatedBoard);
                        rpc.updateBiBoard({
                            _id: selectedBoard._id,
                            board: updatedBoard,
                        }).then((res) => {
                            loadBoards();
                        });
                    }
                }
            ]
        });

    }

    const handleDragEnd = (event: DragEndEvent) => {
        const { active, over } = event;

        if (!over || !selectedBoard || active.id === over.id) {
            return;
        }

        const blocks = selectedBoard.blocks ?? [];
        const oldIndex = blocks.findIndex((block) => block.uuid === active.id);
        const newIndex = blocks.findIndex((block) => block.uuid === over.id);

        if (oldIndex !== -1 && newIndex !== -1) {
            const newBlocks = arrayMove(blocks, oldIndex, newIndex);

            // Сразу обновляем локальный state
            const updatedBoard = {
                ...selectedBoard,
                blocks: newBlocks,
            };
            setSelectedBoard(updatedBoard);

            // Обновляем boards в state
            setBoards((prevBoards) =>
                prevBoards.map((board) =>
                    board._id === selectedBoard._id ? updatedBoard : board
                )
            );

            // Затем обновляем через API
            rpc.updateBiBoard({
                _id: selectedBoard._id,
                board: updatedBoard,
            }).then((res) => {
                loadBoards();
            }).catch((err) => {
                // В случае ошибки откатываем изменения
                console.error('Error updating board:', err);
                loadBoards();
            });
        }
    };

    useEffect(() => {
        loadBoards();
    }, []);


    const addBoard = () => {
        inputDialogRef.current?.open({
            title: Lang.key('add_bi_view_board'),
            value: '',
            onSave: (value) => {

                rpc.addBiBoard({
                    title: value,
                }).then((res) => {

                    setSelectedBoard(res?.result ?? null);
                    loadBoards();

                });

            }
        });
    }

    const blocks = selectedBoard?.blocks ?? [];
    const blockIds = blocks.map((block) => block.uuid ?? '').filter(Boolean);

    return (<>
        <GridRow autoSize className='flex flex-col p-4 border-b border-gray-200'>

            <div className="flex items-center  gap-2 justify-between">


                <div className='flex items-center'>



                    <div className='text-lg font-medium '>{selectedBoard ? selectedBoard.title : Lang.key('bi_view')}</div>

                    {selectedBoard && <AnyDropdownMenu menu={[
                        {
                            label: Lang.key('edit_bi_view_board'),
                            click: () => {
                                inputDialogRef.current?.open({
                                    title: Lang.key('edit_bi_view_board'),
                                    value: selectedBoard.title ?? '',
                                    onSave: (value) => {
                                        rpc.updateBiBoard({
                                            _id: selectedBoard._id,
                                            board: { ...selectedBoard, title: value },
                                        }).then((res) => {
                                            if (res?.result) setSelectedBoard(res.result);
                                            loadBoards();
                                        });
                                    }
                                });
                            }
                        },
                        {
                            label: Lang.key('delete_bi_view_board'),
                            click: () => {
                                confirmAlertRef.current?.open({
                                    title: Lang.key('delete_bi_view_board'),
                                    description: Lang.key('delete_bi_view_board_description'),
                                    buttons: [
                                        { label: Lang.key('cancel'), onClick: () => {} },
                                        {
                                            label: Lang.key('delete'),
                                            onClick: () => {
                                                rpc.deleteBiBoard({ _id: selectedBoard._id }).then(() => {
                                                    const remaining = boards.filter(b => b._id !== selectedBoard._id);
                                                    setBoards(remaining);
                                                    setSelectedBoard(remaining[0] ?? null);
                                                    loadBoards();
                                                });
                                            }
                                        }
                                    ]
                                });
                            }
                        }
                    ]} >
                        <Button variant="link" size="icon"><Edit /></Button>
                    </AnyDropdownMenu>}

                </div>


                <AnyDropdownMenu menu={[
                    ...(boards.map((board) => {
                        return {
                            htmlIcon: <ChartAreaIcon />,
                            label: board.title,
                            click: () => {
                                setSelectedBoard(board);
                            }
                        }
                    })),

                    {
                        htmlIcon: <PlusCircleIcon />,
                        label: Lang.key('add_bi_view_board'),
                        click: () => {

                            addBoard();

                        }
                    }
                ]} >
                    <Button variant="outline" size="icon"><MenuSquareIcon /></Button>
                </AnyDropdownMenu>



            </div>



        </GridRow>
        <GridRow className='flex flex-col p-4'>
            <DndContext sensors={sensors} onDragEnd={handleDragEnd}>
                <SortableContext items={blockIds} strategy={rectSortingStrategy}>
                    <div
                        style={{
                            display: 'grid',
                            gridTemplateColumns: `repeat(24, ${UNIT_WIDTH})`,
                            gridAutoRows: UNIT_HEIGHT,
                            gridAutoFlow: 'dense',
                            gap: '8px',
                        }}
                    >
                        {blocks.map((item) => {
                            const sizes = getBlockSizes(item.type);
                            const colSpan = item.colSpan ?? sizes.colSpan;
                            const rowSpan = item.rowSpan ?? sizes.rowSpan;

                            return (
                                <BIBlockView
                                    onDelete={(block) => deleteBlockOnBoard(block.uuid)}
                                    onEdit={editBlockOnBoard}
                                    key={item.uuid}
                                    item={item}
                                    colSpan={colSpan}
                                    rowSpan={rowSpan}
                                />
                            );
                        })}
                        <div
                            style={{
                                gridColumn: 'span 4',
                                gridRow: 'span 1',
                            }}
                            className='flex flex-col items-center justify-center gap-2 border border-gray-200 rounded-md p-2 opacity-80 cursor-pointer hover:opacity-100'
                            onClick={() => {
                                biBlockDialogRef.current?.open({
                                    onSave: (data) => {
                                        addBlockOnBoard(data);
                                    }
                                });
                            }}
                        >
                            <PlusSquareIcon />
                            <div className='text-sm text-gray-500'>{Lang.key('add_bi_view_block')}</div>
                        </div>
                    </div>
                </SortableContext>
            </DndContext>
        </GridRow>





        <BIBlockDialog ref={biBlockDialogRef} />

    </>

    )
}

export default BIView;