import React from 'react';

import _ from 'lodash';
import {
  ArchiveIcon,
  CopyIcon,
  EyeIcon,
  EyeOffIcon,
  MoreHorizontalIcon,
  PencilIcon,
  PlusIcon,
  SaveIcon,
  Trash2Icon,
  XIcon,
} from 'lucide-react';
import { useHotkeys } from 'react-hotkeys-hook';

import { rpcCache } from '@/api/cache';
import { rpc } from '@/api/request';
import {
  AllItemGIKTType,
  CollectionMenuAMType,
  CollectionRelationType,
  FieldDescriptionType,
  StructureType,
} from '@/api/types';
import { toast } from '@/components/ToastRoot';
import {
  Dialog,
  DialogContent,
} from '@/components/ui/dialog';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
  MobileFab,
  MobileLink,
  MobileNavbar,
  MobilePage,
  MobilePopup,
} from '@/components/ui/mobile';
import { useAppConfig } from '@/contexts/AppConfigContext';
import { Lang } from '@/lang/Lang';
import { copyTextToClipboard } from '@/utils/helpers';

import { actionDialogRef } from '../ActionDialog';
import AnyDropdownMenu from '../AnyDropdownMenu';
import CollectionFields from '../CollectionFields/CollectionFields';
import {
  ColCSS,
  RowCSS,
} from '../CollectionFields/components/GridCss';
import { confirmAlertRef } from '../ConfirmAlert';
import MenuItem from '../MenuItem';
import SvgIcon from '../SvgIcon';
import { Button } from '../ui/button';
import { ButtonGroup } from '../ui/button-group';
import {
  Grid,
  GridCol,
  GridRow,
} from '../ui/grid';
import { Kbd } from '../ui/kbd';
import { Label } from '../ui/label';
import { Skeleton } from '../ui/skeleton';
import {
  buttonAccess,
  requiredValidation,
} from './utils';

export type CollectionViewProps = {
    modalKey?: string;
    collection: string;
    _id?: string;
    clonedFrom?: string;
}

const CollectionView = ({ collection, _id, modalKey, clonedFrom }: CollectionViewProps) => {

    const { closeDialog, focusDialogKey, openDialog, setHideTips, hideTips } = useAppConfig();

    const [structure, setStructure] = React.useState<StructureType | null>(null);


    const onHotkey = (index: number) => {

        if (focusDialogKey === modalKey) {

            if (collectionMenu?.allItems?.[index]) {
                onSelectMenu(collectionMenu?.allItems?.[index]?.key ?? '');
            }
        }


    }

    useHotkeys('shift+1', () => {
        onHotkey(0);
    });

    useHotkeys('shift+2', () => {
        onHotkey(1);
    });

    useHotkeys('shift+3', () => {
        onHotkey(2);
    });


    useHotkeys('shift+4', () => {
        onHotkey(3);
    });

    useHotkeys('shift+5', () => {
        onHotkey(4);
    });


    useHotkeys('shift+6', () => {
        onHotkey(5);
    });

    useHotkeys('shift+7', () => {
        onHotkey(6);
    });

    useHotkeys('shift+8', () => {
        onHotkey(7);
    });

    useHotkeys('shift+9', () => {
        onHotkey(8);
    });

    useHotkeys('shift+0', () => {
        onHotkey(9);
    });

    const hotkeyClose = () => {
        if (focusDialogKey === modalKey) {
            closeDialog(modalKey);
        }
    }

    useHotkeys('shift+x', () => {
        hotkeyClose();
    });

    const hotkeySave = () => {
        if (focusDialogKey === modalKey && !loading && buttonsShow.showSaveButton()) {
            onSave('save');
        }
    }

    useHotkeys('shift+s', () => {
        hotkeySave();
    });

    const [collectionMenu, setCollectionMenu] = React.useState<CollectionMenuAMType | null>(null);

    const [selectMenu, setSelectMenu] = React.useState<AllItemGIKTType | null>(null);

    const [descriptions, setDescriptions] = React.useState<FieldDescriptionType | null>(null);

    const [relations, setRelations] = React.useState<CollectionRelationType[] | null>(null);

    const onSelectMenu = (key: string) => {

        let find = collectionMenu?.allItems?.find((item) => item.key === key);

        if (find?.group) {
            setSelectMenu(find);
        }


    }

    const [loading, setLoading] = React.useState(true);

    const loadData = () => {

        setLoading(true);

        if (_id) {
            rpc.data({ collection: collection, _id: _id }).then((data) => {
                valuesRef.current = data?.result?.data?.[0] ?? {};
            }).catch(() => {

                closeDialog(modalKey)


            }).finally(() => {
                setLoading(false);
            });
        } else {
            rpc.emptyData({ collection: collection, clone: clonedFrom }).then((data) => {
                valuesRef.current = data.result ?? {};
            }).catch(() => {

                closeDialog(modalKey)
            }).finally(() => {
                setLoading(false);
            });
        }
    }
    React.useEffect(() => {

        rpcCache.collection({ collection: collection }).then((json) => {
            if (json?.result?.structure) {
                setStructure(json.result.structure);
            }
            if (json?.result?.descriptions) {
                setDescriptions(json.result.descriptions);
            }

            setRelations(json?.result?.relations ?? null);


            setCollectionMenu(json?.result?.collectionMenu ?? null);


            if (!selectMenu && json?.result?.collectionMenu?.allItems) {

                setSelectMenu(json?.result?.collectionMenu?.allItems[0]);
            }

        });



        loadData();

    }, [collection]);

    const valuesRef = React.useRef<any>({});




    const onSave = (action: 'save' | 'save_and_close' | 'save_and_add_new' | 'save_and_edit') => {


        if (!structure) {
            toast.error(Lang.key('error_saving'));
            return;
        }


        let valid = requiredValidation(valuesRef.current, structure, valuesRef.current, []);

        if (valid.length > 0) {


            let field = valid[0];





            toast.error(`${field} ${Lang.key('is_required')}`);
            return;


        }

        let loading = toast.loading(Lang.key('saving'));

        rpc.update({
            collection: collection,
            _ids: _id ? [_id] : undefined,
            values: valuesRef.current
        }).then((data) => {




            toast.success(Lang.key('saved_successfully'));

            if (action === 'save_and_close') {
                closeDialog(modalKey);
            }

            if (action === 'save_and_add_new') {

                openDialog({
                    collection: collection,
                });

                closeDialog(modalKey);


                return;
                //TODO
            }
            if (action === 'save_and_edit') {

                if (!_id) {

                    openDialog({
                        collection: collection,
                        _id: data?.result?.data?.[0]?._id,
                    });

                    closeDialog(modalKey);

                }
                return;

                //TODO
            }
            if (action === 'save') {

                if (!_id) {

                    openDialog({
                        collection: collection,
                        _id: data?.result?.data?.[0]?._id,
                    });
                    closeDialog(modalKey);

                }

                return;
                //TODO
            }


        }).catch((error) => {
            toast.error(Lang.key('error_saving'));
        }).finally(() => {
            toast.dismiss(loading);
        });
    }

    const onDelete = () => {
        confirmAlertRef.current?.open({
            title: Lang.key('delete_item'),
            description: Lang.key('delete_item_description'),
            buttons: [
                { label: Lang.key('cancel'), onClick: () => { } },
                {
                    label: Lang.key('delete'), onClick: () => {

                        if (_id) {
                            rpc.deleteData({ collection: collection, _ids: [_id] }).then((data) => {
                                toast.success(Lang.key('deleted_successfully'));
                                closeDialog(modalKey);
                            });
                        }
                    }
                },
            ]
        });
    }

    const { isMobile, color } = useAppConfig();

    const buttonsShow = buttonAccess(structure, _id);


    const onDoAction = (item: StructureType) => {

        if (_id) {

            actionDialogRef.current?.open({
                collection: collection,
                action: item,
                ids: [_id],
                onSuccess: () => {
                    loadData();
                }
            });
        }
    }

    const onClone = () => {
        if (_id) {
            openDialog({
                modalKey: `collection_create_${collection}_cloned_from_${_id}`,
                collection: collection,
                clonedFrom: _id,
            });
        }
    }

    const { openTableDialog } = useAppConfig();
    const onOpenRelationTable = (item: CollectionRelationType) => {

        if (_id) {

            openTableDialog({ ...item, ids: [_id] })
        }
    }

    const [actions, setActions] = React.useState<StructureType[]>([]);

    React.useEffect(() => {
        let _actions: StructureType[] = [];
        _.map(structure?.items, (item) => {
            if (item.type == "action" && item.actionPosition == "sidebar") {
                _actions.push(item);
            }
        });
        setActions(_actions);
    }, [structure]);

    if (isMobile) {






        return <MobilePopup opened={true} onBackdropClick={() => closeDialog(modalKey)}>

            <MobilePage>
                <MobileNavbar
                    right={<MobileLink
                        onClick={() => closeDialog(modalKey)}
                    ><XIcon /></MobileLink>}
                    title={structure?.title}
                    subtitle={_id ? Lang.key('edit_item') : Lang.key('create_item')}

                    subnavbar={collectionMenu?.allItems && collectionMenu?.allItems?.length > 1 &&
                        <div className=' inline-flex gap-2 overflow-x-scroll  py-2 overflow-y-hidden'>


                            {collectionMenu?.menu?.map((item) => {
                                if (item.children) {


                                    return <>
                                        {item.children.map((item, index) => {



                                            return <MobileLink

                                                style={{
                                                    borderColor: selectMenu?.key == item.key ? color : undefined
                                                }}

                                                onClick={() => {
                                                    if (item.key) {
                                                        onSelectMenu(item.key);
                                                    }
                                                }} className="whitespace-nowrap border-1 border-gray-200 rounded-md px-2 py-1">
                                                {item.title}
                                            </MobileLink>



                                        })}

                                    </>


                                }

                                return <MobileLink
                                    style={{
                                        borderColor: selectMenu?.key == item.key ? color : undefined
                                    }}
                                    className="whitespace-nowrap"
                                    onClick={() => {
                                        if (item.key) {
                                            onSelectMenu(item.key);
                                        }
                                    }}>
                                    {item.title}
                                </MobileLink>





                            })}


                        </div>
                    }

                />
                {loading ? <RowCSS className="w-full p-4 ">
                    {[1, 2, 3, 4, 5].map(() => {
                        return <ColCSS col={12} className='px-1'>
                            <Skeleton
                                className="w-16 h-2 mt-2"
                            />
                            <Skeleton
                                className="w-full h-12 mt-1"
                            />
                        </ColCSS>
                    })}
                </RowCSS> :
                    !!selectMenu?.group && <CollectionFields
                        descriptions={descriptions}
                        groupKey={selectMenu?.group}
                        onlyShow={!!_id ? !structure?.canUpdate : !structure?.canCreate}

                        structure={structure}
                        valuesRef={valuesRef}
                    />}




                <AnyDropdownMenu
                    className="fixed left-1/2 bottom-safe-4 transform -translate-x-1/2 z-20"
                    menu={[
                        {
                            htmlIcon: <SaveIcon />,
                            disabled: loading || !buttonsShow.showSaveButton(),
                            label: Lang.key("save"),
                            click: () => {
                                onSave('save');
                            }
                        },
                        {
                            label: Lang.key("actions"),
                            disabled: loading || !buttonsShow.showActionButton() || !actions.length,

                            submenu: actions.map((item) => {
                                return {
                                    htmlIcon: <SvgIcon icon={item.assets?.icon} />,
                                    label: item.title ?? item.key,
                                    click: () => {
                                        onDoAction(item);
                                    }
                                }
                            })
                        },
                        {
                            htmlIcon: <CopyIcon />,
                            disabled: loading || !buttonsShow.showCloneButton(),
                            label: Lang.key("copy_item"),
                            click: () => {
                                onClone()
                            }
                        },
                        {
                            htmlIcon: <ArchiveIcon />,
                            label: Lang.key("copy_item_id"),
                            disabled: loading || !buttonsShow.showCopyButton(),
                            click: () => {
                                if (_id) {
                                    copyTextToClipboard(_id);
                                }
                            }
                        },
                        {
                            htmlIcon: hideTips ? <EyeIcon /> : <EyeOffIcon />,
                            label: hideTips ? Lang.key("show_tips") : Lang.key("hide_tips"),
                            click: () => {
                                setHideTips(!hideTips);
                            }
                        },

                        {
                            htmlIcon: <Trash2Icon />,
                            disabled: loading || !buttonsShow.showDeleteButton(),
                            label: Lang.key("delete"),
                            click: () => {
                                onDelete();
                            }
                        },



                    ]}
                >
                    <MobileFab

                        icon={<MoreHorizontalIcon className='size-5' />}
                    />
                </AnyDropdownMenu>


            </MobilePage>

        </MobilePopup>
    }

    return (

        <Dialog open={true}

            onOpenChange={(open) => {
                if (!open) {
                    closeDialog(modalKey);
                }
            }}
        >

            <DialogContent className="!w-[80vw] !max-w-[80vw] sm:!max-w-[80vw] h-[80vh] overflow-hidden !p-0" >
                <Grid className='h-full w-full !w-[80vw] !max-w-[80vw] sm:!max-w-[80vw] h-[80vh]'>
                    <GridCol width="300px" className=' py-2 px-1 border-r'>

                        <GridRow autoSize>

                            <ButtonGroup className='w-full'>
                                <Button

                                    onClick={() => closeDialog(modalKey)}
                                    className='w-full flex-1'
                                    variant="outline">{Lang.key('close')} <Kbd>Shift + X</Kbd></Button>
                                <DropdownMenu>
                                    <DropdownMenuTrigger asChild>
                                        <Button
                                            disabled={loading}
                                            variant="outline" size="icon" aria-label="More Options">
                                            <MoreHorizontalIcon />
                                        </Button>
                                    </DropdownMenuTrigger>
                                    <DropdownMenuContent align="end">
                                        <DropdownMenuGroup>
                                            <DropdownMenuItem
                                                disabled={loading || !buttonsShow.showCloneButton()}
                                                onClick={() => {

                                                    onClone()

                                                }}>
                                                <CopyIcon />
                                                {Lang.key("copy_item")}
                                            </DropdownMenuItem>
                                            <DropdownMenuItem
                                                disabled={loading || !buttonsShow.showCopyButton()}
                                                onClick={() => {
                                                    if (_id) {
                                                        copyTextToClipboard(_id);
                                                    }
                                                }}>
                                                <ArchiveIcon />
                                                {Lang.key("copy_item_id")}
                                            </DropdownMenuItem>
                                        </DropdownMenuGroup>
                                        <DropdownMenuSeparator />
                                        <DropdownMenuGroup>
                                            <DropdownMenuItem

                                                onClick={() => {

                                                    setHideTips(!hideTips);

                                                }}
                                            >
                                                {hideTips ? <EyeIcon /> : <EyeOffIcon />}
                                                {hideTips ? Lang.key("show_tips") : Lang.key("hide_tips")}
                                            </DropdownMenuItem>
                                        </DropdownMenuGroup>
                                        <DropdownMenuSeparator />

                                        <DropdownMenuGroup>
                                            <DropdownMenuItem
                                                disabled={loading || !buttonsShow.showDeleteButton()}
                                                onClick={() => onDelete()}
                                                variant="destructive">
                                                <Trash2Icon />
                                                {Lang.key("delete")}
                                            </DropdownMenuItem>
                                        </DropdownMenuGroup>
                                    </DropdownMenuContent>
                                </DropdownMenu>
                            </ButtonGroup>

                        </GridRow>

                        <GridRow className='px-2 py-4 flex flex-col gap-2'>


                            {collectionMenu?.menu?.map((item) => {
                                if (item.children) {


                                    return <div className='mb-4'>
                                        <Label>{item.title}</Label>
                                        {item.children.map((item, index) => {


                                            let keyIndex: number | null = index + 1;

                                            if (keyIndex == 10) {
                                                keyIndex = 0;
                                            }

                                            if (keyIndex > 10) {
                                                keyIndex = null;
                                            }

                                            return <MenuItem

                                                hotkey={keyIndex !== null ? `Shift+${keyIndex}` : undefined}
                                                active={selectMenu?.key == item.key}
                                                media={<SvgIcon
                                                    color={selectMenu?.key == item.key ? color : undefined}
                                                    icon={item.icon} />}
                                                label={<span
                                                    style={{
                                                        opacity: selectMenu?.key == item.key ? 1 : 0.8
                                                    }}
                                                >{item.title}</span>}
                                                onClick={() => {
                                                    if (item.key) {
                                                        onSelectMenu(item.key);
                                                    }
                                                }}
                                                key={item.key}>

                                            </MenuItem>
                                        })}

                                    </div>


                                }

                                return <MenuItem
                                    onClick={() => {
                                        if (item.key) {
                                            onSelectMenu(item.key);
                                        }
                                    }}

                                    media={<SvgIcon
                                        color={selectMenu?.key == item.key ? color : undefined}
                                        icon={item.icon} />}
                                    label={<span
                                        style={{
                                            opacity: selectMenu?.key == item.key ? 1 : 0.8
                                        }}
                                    >{item.title}</span>}
                                    active={selectMenu?.key == item.key}

                                    key={item.key}>

                                </MenuItem>



                            })}

                            {buttonsShow.showActionButton() && !!actions.length && <div className='mb-4'>
                                <Label>{Lang.key('actions')}</Label>
                                {actions.map((item) => {
                                    return <MenuItem
                                        media={<SvgIcon icon={item.assets?.icon} />}
                                        onClick={() => {
                                            onDoAction(item);
                                        }}

                                        key={item.key}
                                        label={item.title}>
                                    </MenuItem>
                                })}

                            </div>}

                            {buttonsShow.showRelationButton() && relations && relations.length > 0 && <div className='mb-4'>
                                <Label>{Lang.key('relations_collection')}</Label>
                                {relations.map((item) => {
                                    return <MenuItem
                                        media={<SvgIcon icon={item.icon} />}
                                        label={item.title}
                                        subtitle={item.subtitle}
                                        key={item.key}
                                        onClick={() => {
                                            onOpenRelationTable(item);
                                        }}
                                    >
                                    </MenuItem>
                                })}
                            </div>}


                        </GridRow>

                        <GridRow autoSize >

                            <ButtonGroup

                                className='w-full'>
                                <Button
                                    disabled={loading || !buttonsShow.showSaveButton()}
                                    onClick={() => onSave('save')}
                                    className='w-full flex-1'
                                    variant="outline"><SaveIcon />
                                    {Lang.key('save')} <Kbd>Shift + S</Kbd></Button>
                                <DropdownMenu>
                                    <DropdownMenuTrigger asChild>
                                        <Button
                                            disabled={loading}

                                            variant="outline" size="icon" aria-label="More Options">
                                            <MoreHorizontalIcon />
                                        </Button>
                                    </DropdownMenuTrigger>
                                    <DropdownMenuContent align="end" >
                                        <DropdownMenuGroup>
                                            <DropdownMenuItem
                                                disabled={loading || !buttonsShow.showSaveButton()}
                                                onClick={() => onSave('save_and_close')}>
                                                <SaveIcon />
                                                {Lang.key("save_and_close")}
                                            </DropdownMenuItem>
                                            <DropdownMenuItem
                                                disabled={loading || !buttonsShow.showCreateButton()}
                                                onClick={() => onSave('save_and_add_new')}>
                                                <PlusIcon />
                                                {Lang.key("save_and_add_new")}
                                            </DropdownMenuItem>
                                            <DropdownMenuItem
                                                disabled={loading || !buttonsShow.showSaveButton()}
                                                onClick={() => onSave('save_and_edit')}>
                                                <PencilIcon />
                                                {Lang.key("save_and_edit")}
                                            </DropdownMenuItem>
                                        </DropdownMenuGroup>
                                        <DropdownMenuGroup>
                                            <DropdownMenuItem
                                                disabled={loading || !buttonsShow.showDeleteButton()}
                                                onClick={() => onDelete()}
                                                variant="destructive">
                                                <Trash2Icon />{Lang.key("delete")}
                                            </DropdownMenuItem>
                                        </DropdownMenuGroup>

                                    </DropdownMenuContent>
                                </DropdownMenu>
                            </ButtonGroup>



                        </GridRow>

                    </GridCol>
                    <GridCol >


                        {loading ? <RowCSS className="w-full p-4">
                            {[1, 2, 3, 4, 5].map(() => {
                                return <ColCSS col={12} className='px-1'>
                                    <Skeleton
                                        className="w-16 h-2 mt-2"
                                    />
                                    <Skeleton
                                        className="w-full h-12 mt-1"
                                    />
                                </ColCSS>
                            })}
                        </RowCSS> :
                            !!selectMenu?.group && <CollectionFields
                                descriptions={descriptions ?? null}

                                onlyShow={!!_id ? !structure?.canUpdate : !structure?.canCreate}

                                groupKey={selectMenu?.group}
                                structure={structure}
                                valuesRef={valuesRef}
                            />}


                    </GridCol>
                </Grid>


            </DialogContent>

        </Dialog>

    )


}

export default CollectionView;