'use client';

import ActionPopMenu from '@/components/common/ActionPopMenu';
import Loader from '@/components/common/Loader';
import { MyTable, ColumnData } from '@/components/common/MyTable';
import StatusChangePopup from '@/components/common/StatusChangePopup';
import BaseButton from '@/components/ui-kit/BaseButton';
import BaseIconButton from '@/components/ui-kit/BaseIconButton';
import BaseInput from '@/components/ui-kit/BaseInput';
import BasePagination from '@/components/ui-kit/BasePagination';
import BaseReactSelect from '@/components/ui-kit/BaseReactSelect';
import { useAuthContext } from '@/context/auth-context';
import { Party, PartyStatus, PartyStatusList, PartyStatusOptions } from '@/data/party/party.model';
import { party_requests } from '@/data/party/party.requests';
import { DEFAULT_PAGE_SIZE, pageLinks } from '@/helpers/constants';
import useInput from '@/hooks/useInput';
import { useMyNavigation } from '@/hooks/useMyNavigation';
import { useMyTranslation } from '@/hooks/useMyTranslation';
import useRequest from '@/hooks/useRequest';
import { file_service } from '@/services/file-service';
import { notifyUnknownError } from '@/services/notification';
import { getStatusColor } from '@/theme/getStatusBoxStyles';
import { Add, AddCircleOutline, Circle, Delete, Download, Edit, FilterList, FilterListOff, Search } from '@mui/icons-material';
import { Box, CircularProgress, Stack, SvgIcon, Tooltip, Typography } from '@mui/material';
import { useRouter } from 'next/navigation';
import React, { useEffect, useMemo, useState } from 'react';
import { getBoxStatusStyles } from '@/theme/getStatusBoxStyles';

type Props = {};

const DashboardPartiesPage = (props: Props) => {
    const t = useMyTranslation();
    const navigation = useMyNavigation();
    const { isAdmin, isAdminOrUzbek } = useAuthContext();
    const [page, setPage] = useState(1);
    const [pageSize] = useState(DEFAULT_PAGE_SIZE);
    const { value: keyword, onChange: handleKeyword, setValue: setKeyword } = useInput('');
    const [partyStatusFilter, setPartyStatusFilter] = useState<PartyStatus | undefined>(undefined);

    const [deleteIds, setDeleteIds] = useState<number[]>([]);
    const [downloadIds, setDownloadIds] = useState<number[]>([]);
    const [downloadItemIds, setDownloadItemIds] = useState<number[]>([]);
    const [downloadItemIdsExel, setDownloadItemIdsExel] = useState<number[]>([]);
    const [changeStatusIds, setChangeStatusIds] = useState<number[]>([]);

    const partyStatusOptions = useMemo(() => {
        const p = ['COLLECTING', 'ON_THE_WAY', 'IN_CUSTOMS', 'IN_WAREHOUSE'] as PartyStatus[];
        if (isAdmin) {
            // p.push('ARRIVED');
            p.push('DELIVERED');
        }
        return p;
    }, [isAdmin]);

    const getPartiesQuery = useRequest(
        () =>
            party_requests.getAll({
                page: page,
                partyName: keyword,
                status: partyStatusFilter,
                direction: 'desc',
                sort: 'id',
            }),
        {
            dependencies: [page, partyStatusFilter],
            selectData(data) {
                return data.data.data;
            },
        }
    );

    const {
        data: list,
        totalElements,
        totalPages,
    } = useMemo(() => {
        if (getPartiesQuery.data?.data) {
            return {
                data: getPartiesQuery.data.data,
                totalElements: getPartiesQuery.data.totalElements,
                totalPages: getPartiesQuery.data.totalPages,
            };
        } else {
            return {
                data: [],
                totalElements: 0,
                totalPages: 0,
            };
        }
    }, [getPartiesQuery]);
    const loading = getPartiesQuery.loading;

    const handleChange = (newPage: number) => {
        setPage(newPage);
    };

    const resetFilter = () => {
        setPage(1);
        setKeyword('');
        setPartyStatusFilter(undefined);
    };

    const onDelete = async (id: number, name: string) => {
        if (!window.confirm(t('are_you_sure_delete_party', { name }))) return;

        if (deleteIds.includes(id)) return;

        try {
            setDeleteIds(p => [...p, id]);
            await party_requests.delete({ partyId: id });
            getPartiesQuery.refetch();
        } catch (error) {
            notifyUnknownError(error);
        } finally {
            setDeleteIds(prev => prev.filter(i => i !== id));
        }
    };

    const onDownloadExcel = async (id: number) => {
        if (downloadIds.includes(id)) return;

        try {
            setDownloadIds(p => [...p, id]);
            const response = await party_requests.downloadExcel({ partyId: id });
            const file = new File([response.data], 'Party-excel.xlsx', { type: response.data.type });
            file_service.download(file);
        } catch (error) {
            notifyUnknownError(error);
        } finally {
            setDownloadIds(prev => prev.filter(i => i !== id));
        }
    };

    const onDownloadPartyItems = async (id: number) => {
        if (downloadItemIds.includes(id)) return;

        try {
            setDownloadItemIds(p => [...p, id]);
            const response = await party_requests.downloadPartyItemsExcel({ partyId: id });
            const file = new File([response.data], 'Party-items-excel.xlsx', { type: response.data.type });
            file_service.download(file);
        } catch (error) {
            notifyUnknownError(error);
        } finally {
            setDownloadItemIds(prev => prev.filter(i => i !== id));
        }
    };

    const onDownloadPartyItemsExel = async (id: number, name: string) => {
        if (downloadItemIds.includes(id)) return;

        try {
            setDownloadItemIdsExel(p => [...p, id]);
            const response = await party_requests.downloadPartyItemsAllExcel({ partyId: id });
            const file = new File([response.data], `${name}.xlsx`, { type: response.data.type });
            file_service.download(file);
        } catch (error) {
            notifyUnknownError(error);
        } finally {
            setDownloadItemIdsExel(prev => prev.filter(i => i !== id));
        }
    };

    const onChangeStatus = async (id: number, newStatus: PartyStatus) => {
        if (changeStatusIds.includes(id)) return;

        try {
            setChangeStatusIds(p => [...p, id]);
            await party_requests.changeStatus({ partyId: id, status: newStatus });
            getPartiesQuery.refetch();
        } catch (error) {
            notifyUnknownError(error);
        } finally {
            setChangeStatusIds(prev => prev.filter(i => i !== id));
        }
    };

    useEffect(() => {
        const timeoutId = setTimeout(() => {
            setPage(1);
            getPartiesQuery.refetch();
        }, 350);
        return () => clearTimeout(timeoutId);
    }, [keyword]);

    const columns: ColumnData<Party>[] = [
        {
            label: t('No'),
            width: 100,
            renderCell(data, rowIndex) {
                return (page - 1) * pageSize + rowIndex + 1;
            },
        },
        {
            dataKey: 'id',
            label: t('id'),
            width: 100,
        },
        {
            dataKey: 'name',
            label: t('name'),
            width: 300,
        },
        {
            dataKey: 'totalBoxes',
            label: t('count_of_boxes'),
            width: 300,
        },
        {
            dataKey: 'partyStatus',
            label: t('party_status'),
            width: 300,
            renderHeaderCell(rowIndex) {
                return (
                    <Stack direction={'row'} alignItems={'center'}>
                        <span>{t('party_status')}</span>
                        <ActionPopMenu
                            buttons={PartyStatusList.map(stat => {
                                return {
                                    icon: <Circle sx={{ path: { color: getStatusColor(stat) } }} />,
                                    label: t(stat),
                                    onClick() {
                                        setPartyStatusFilter(stat);
                                        setPage(1);
                                    },
                                };
                            })}
                            mainIcon={<FilterList />}
                            placement={{
                                anchorOrigin: {
                                    vertical: 'bottom',
                                    horizontal: 'center',
                                },
                                transformOrigin: {
                                    horizontal: 'center',
                                    vertical: 'top',
                                },
                            }}
                        />
                    </Stack>
                );
            },
            renderCell(data) {
                return isAdminOrUzbek ? (
                    <StatusChangePopup
                        anchor={{
                            status: data.partyStatus,
                            text: t(data.partyStatus),
                        }}
                        loading={changeStatusIds.includes(data.id)}
                        buttons={partyStatusOptions.map(stat => {
                            return {
                                icon: (
                                    <Circle
                                        sx={{
                                            path: {
                                                color: getStatusColor(stat),
                                            },
                                        }}
                                    />
                                ),
                                label: t(stat),
                                onClick: () => {
                                    onChangeStatus(data.id, stat);
                                },
                            };
                        })}
                    />
                ) : (
                    <BaseButton sx={{ ...getBoxStatusStyles(data.partyStatus), alignItems: 'center', whiteSpace: 'nowrap' }} fullWidth>
                        {t(data.partyStatus)}
                    </BaseButton>
                );
            },
        },
        {
            label: '',
            width: 100,
            numeric: true,
            renderCell(data, rowIndex) {
                return (
                    <ActionPopMenu
                        buttons={[
                            // {
                            //     icon: <AddCircleOutline />,
                            //     label: t('add_box'),
                            //     onClick: () => {
                            //         navigation.push(pageLinks.dashboard.boxes.create + `?party_id=${data.id}`);
                            //     },
                            // },
                            {
                                icon: <Edit sx={{ path: { color: '#3489E4' } }} />,
                                label: t('edit'),
                                onClick: () => {
                                    navigation.push(pageLinks.dashboard.parties.edit(data.id));
                                },
                            },
                            {
                                icon: <Delete sx={{ path: { color: '#3489E4' } }} />,
                                label: t('delete'),
                                onClick: () => {
                                    onDelete(data.id, data.name);
                                },
                                dontCloseOnClick: true,
                                loading: deleteIds.includes(data.id),
                            },
                            ...(isAdmin
                                ? [
                                    {
                                        icon: <Download sx={{ path: { color: '#3489E4' } }} />,
                                        label: t('download_all_items'),
                                        onClick: () => {
                                            onDownloadPartyItems(data.id);
                                        },
                                        dontCloseOnClick: true,
                                        loading: downloadItemIds.includes(data.id),
                                    },
                                ]
                                : []),
                            {
                                icon: <Download sx={{ path: { color: '#3489E4' } }} />,
                                label: t('download_all_items_exel'),
                                onClick: () => {
                                    onDownloadPartyItemsExel(data.id, data.name);
                                },
                                dontCloseOnClick: true,
                                loading: downloadItemIdsExel.includes(data.id),
                            },
                            ...(Boolean(data.partyStatus === 'ON_THE_WAY' || data.partyStatus === 'ARRIVED')
                                ? [
                                    {
                                        icon: <Download sx={{ path: { color: '#3489E4' } }} />,
                                        label: t('download_excel'),
                                        onClick: () => {
                                            onDownloadExcel(data.id);
                                        },
                                        loading: downloadIds.includes(data.id),
                                        dontCloseOnClick: true,
                                    },
                                ]
                                : []),
                        ]}
                    />
                );
            },
        },
    ];

    return (
        <Box>
            <Stack direction={'row'} mb={3}>
                <BaseButton colorVariant='blue' startIcon={<Add />} href={pageLinks.dashboard.parties.create}>
                    {t('create_party')}
                </BaseButton>
            </Stack>
            <Box
                width={1}
                mb={3}
                sx={{
                    padding: '28px',
                    borderRadius: '16px',
                    backgroundColor: '#fff',
                }}
            >
                <Stack mb={3.5} direction={'row'} justifyContent={'space-between'} alignItems={'center'}>
                    <Typography
                        sx={{
                            fontSize: '20px',
                            lineHeight: '24px',
                            fontWeight: 600,
                            textTransform: 'capitalize',
                            color: '#000',
                        }}
                    >
                        {t('parties')}
                    </Typography>
                    <Stack direction={'row'} alignItems={'center'} spacing={2}>
                        <BaseInput
                            InputProps={{
                                startAdornment: <Search color='primary' />,
                            }}
                            value={keyword}
                            onChange={handleKeyword}
                            placeholder={t('filter_party_name')}
                        />

                        <BaseButton colorVariant='gray' startIcon={<FilterListOff />} size='small' onClick={resetFilter}>
                            {t('reset_filter')}
                        </BaseButton>
                    </Stack>
                </Stack>
                <Box mb={6}>
                    <MyTable columns={columns} data={list} loading={loading} />
                </Box>
                <Stack direction={'row'} justifyContent={'center'}>
                    <BasePagination page={page} pageSize={pageSize} totalCount={totalElements} onChange={handleChange} />
                </Stack>
            </Box>
        </Box>
    );
};

export default DashboardPartiesPage;
