'use client';

import type React from 'react';

import ActionPopMenu from '@/components/common/ActionPopMenu';
import { type ColumnData, MyTable } from '@/components/common/MyTable';
import StatusChangePopup from '@/components/common/StatusChangePopup';
import BaseButton from '@/components/ui-kit/BaseButton';
import BaseInput from '@/components/ui-kit/BaseInput';
import BasePagination from '@/components/ui-kit/BasePagination';
import { selectDefaultStyles } from '@/components/ui-kit/BaseReactSelect';
import { useAuthContext } from '@/context/auth-context';
import { type BoxStatus, BoxStatusList, type IBox } from '@/data/box/box.model';
import { box_requests } from '@/data/box/box.requests';
import type { Product, UpdateProductBodyType } from '@/data/item/item.mode';
import { item_requests } from '@/data/item/item.requests';
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, Circle, Delete, Download, Edit, FilterList, FilterListOff, Print, RemoveRedEye, Search } from '@mui/icons-material';
import { Box, Button, Card, CardContent, Modal, Stack, TextField, Typography } from '@mui/material';
import { useEffect, useMemo, useRef, useState } from 'react';
import { useForm } from 'react-hook-form';
import AsyncSelect from 'react-select/async';
import { useReactToPrint } from 'react-to-print';
import BoxesPrintList from '../boxes-print/BoxesPrintList';

type Props = {};

const style = {
    position: 'absolute',
    top: '50%',
    left: '50%',
    transform: 'translate(-50%, -50%)',
    width: 400,
    bgcolor: 'background.paper',
    border: '2px solid #000',
    boxShadow: 24,
    display: 'flex',
    flexDirection: 'column',
    gap: '10px',
    p: 4,
};

const DashboardBoxesPage = (props: Props) => {
    const [open, setOpen] = useState(false);
    const [openModal, setOpenModal] = useState(false);
    const handleClose = () => setOpen(false);
    const t = useMyTranslation();
    const navigation = useMyNavigation();
    const { isAdmin } = useAuthContext();
    const [page, setPage] = useState(1);
    const [pageSize] = useState(DEFAULT_PAGE_SIZE);
    const { value: keyword, onChange: handleKeyword, setValue: setKeyword } = useInput('');
    const [boxStatusFilter, setBoxStatusFilter] = useState<BoxStatus | undefined>(undefined);
    const [trackId, setTrackId] = useState<string>();
    const [partyFilter, setPartyFilter] = useState<{ label: string; value: number } | undefined>(undefined);

    const [deleteIds, setDeleteIds] = useState<number[]>([]);
    const [downloadIds, setDownloadIds] = useState<number[]>([]);
    const [changeStatusIds, setChangeStatusIds] = useState<number[]>([]);
    const [boxAmounts, setBoxAmounts] = useState<Record<number, { totalAmount: number; totalAccepted: number }>>({});

    // Print uchun state
    const [selectedBoxForPrint, setSelectedBoxForPrint] = useState<IBox | null>(null);
    const [selectedBoxDetails, setSelectedBoxDetails] = useState<any>(null);

    const printRef = useRef<HTMLDivElement>(null);

    // Available status options (simulating admin/user permissions)

    // Print functionality
    const handlePrint = useReactToPrint({
        contentRef: printRef,
        onAfterPrint: () => {
            setSelectedBoxForPrint(null);
            setSelectedBoxDetails(null);
        },
    });

    const { data: defaultPartyOptions } = useRequest(() => party_requests.getAll({}), {
        enabled: true,
        selectData(data) {
            return data.data.data.data.map(p => ({ value: p.id, label: p.name }));
        },
        placeholderData: [],
    });

    const partyOptions = (inputValue: string) => {
        return party_requests.getAll({ partyName: inputValue }).then(res => {
            return res.data.data.data.map(p => ({ label: p.name, value: p.id }));
        });
    };

    const onPrintBox = async (boxData: IBox) => {
        try {
            // Fetch detailed box data
            const response = await box_requests.find({ packetId: boxData.id });
            const boxOne = response.data.data;

            const detailedBoxData = {
                id: +boxData.id,
                box_name: boxOne.packet.name,
                net_weight: +boxOne.packet.brutto,
                box_weight: +boxOne.packet.boxWeight,
                box_type: boxOne.packet.boxType,
                box_size: boxOne.packet.volume,
                passportName: boxOne.packet.passportName,
                status: boxOne.packet.status,
                packetId: boxData.id,
                partyId: +boxOne.packet.partyId,
                partyName: boxOne.packet.partyName,
                passportId: boxOne.client?.passportId,
                client_id: boxOne.packet?.cargoId,
                clientName: boxOne.client?.passportName,
                products_list: boxOne.items.map((item: any) => ({
                    id: item.id,
                    price: item.price,
                    cargoId: item.cargoId,
                    trekId: item.trekId,
                    name: item.name,
                    nameRu: item.nameRu,
                    amount: +item.amount,
                    acceptedNumber: item.acceptedNumber,
                    weight: +item.weight,
                })),
            };

            setSelectedBoxDetails(detailedBoxData);
            setTimeout(() => {
                handlePrint();
            }, 100);
        } catch (error) {
            console.error('Failed to fetch box details:', error);
        }
    };

    const handleOpen = (data: any) => {
        setOpen(true);
    };

    const handleOpenModal = (data: any) => {
        setOpenModal(true);
        setSelectedBoxForPrint(data);
    };

    const boxStatusOptions = useMemo(() => {
        const p = ['READY_TO_INVOICE'] as BoxStatus[];
        if (isAdmin) {
            p.push('READY');
        }
        return p;
    }, [isAdmin]);

    const getBoxesQuery = useRequest(
        () =>
            box_requests.getAll({
                page: page,
                cargoId: keyword,
                partyId: partyFilter?.value,
                status: boxStatusFilter,
                direction: 'desc',
                sort: 'id',
            }),
        {
            dependencies: [page, boxStatusFilter],
            selectData(data) {
                return data.data.data;
            },
        }
    );

    const getListQuery = useRequest(
        () =>
            item_requests.getAll({
                page: page,
                trekId: trackId,
            }),
        {
            dependencies: [page, trackId],
            selectData(data) {
                return data.data.data;
            },
        }
    );

    const [values, setValues] = useState<{ [trackId: string]: number | '' }>({});

    const handleAmountChange = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>, max: number, trackId: string) => {
        const val = Number(event.target.value);
        if (val >= 1 && val <= max) {
            setValues(prev => ({ ...prev, [trackId]: val }));
        } else if (event.target.value === '') {
            setValues(prev => ({ ...prev, [trackId]: '' }));
        }
    };

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

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

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

    const onDelete = async (id: number) => {
        if (deleteIds.includes(id)) return;

        try {
            setDeleteIds(p => [...p, id]);
            await box_requests.delete({ packetId: id });
            getBoxesQuery.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 box_requests.downloadExcel({ packetId: id });
            const file = new File([response.data], 'Box-excel.xlsx', { type: response.data.type });
            file_service.download(file);
        } catch (error) {
            notifyUnknownError(error);
        } finally {
            setDownloadIds(prev => prev.filter(i => i !== id));
        }
    };

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

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

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

    useEffect(() => {
        const fetchAmounts = async () => {
            const result: Record<number, { totalAmount: number; totalAccepted: number }> = {};

            await Promise.all(
                list.map(async box => {
                    try {
                        const res = await box_requests.find({ packetId: box.id });
                        const boxData = res.data.data;

                        const total = boxData.items.reduce(
                            (acc: { totalAmount: number; totalAccepted: number }, item: any) => {
                                acc.totalAmount += +item.amount || 0;
                                acc.totalAccepted += +item.acceptedNumber || 0;
                                return acc;
                            },
                            { totalAmount: 0, totalAccepted: 0 }
                        );

                        result[box.id] = total;
                    } catch (e) {
                        console.error(`Failed to fetch box ${box.id}`, e);
                    }
                })
            );

            setBoxAmounts(result);
        };

        if (list.length > 0 && !loading) {
            fetchAmounts();
        }
    }, [list, loading]);

    const columns: ColumnData<IBox>[] = [
        {
            label: t('No'),
            width: 100,
            renderCell(data, rowIndex) {
                return (page - 1) * pageSize + rowIndex + 1;
            },
        },
        {
            dataKey: 'id',
            label: "Qo'shish",
            width: 120,
            renderCell: data => {
                return (
                    <Button onClick={() => navigation.push(pageLinks.dashboard.boxes.edit(data.id))}>
                        <Add />
                    </Button>
                );
            },
        },
        {
            dataKey: 'partyName',
            label: t('party_name'),
            width: 120,
        },
        {
            dataKey: 'name',
            label: t('name'),
            width: 120,
        },
        {
            dataKey: 'packetNetWeight',
            label: t('weight'),
            width: 120,
        },
        {
            dataKey: 'totalItems',
            label: t('count_of_items'),
            width: 120,
            renderCell: data => {
                const total = boxAmounts[data.id];
                if (!total) return <Typography>...</Typography>;
                return (
                    <Typography>
                        {total.totalAmount} | {total.totalAccepted}
                    </Typography>
                );
            },
        },
        {
            dataKey: 'totalNetWeight',
            label: t('party_weight'),
            width: 120,
        },
        {
            dataKey: 'cargoId',
            label: t('cargo_id'),
            width: 120,
        },
        {
            dataKey: 'passportName',
            label: t('client'),
            width: 120,
        },
        {
            dataKey: 'status',
            label: t('status'),
            width: 240,
            renderHeaderCell(rowIndex) {
                return (
                    <Stack direction={'row'} alignItems={'center'}>
                        <span>{t('box_status')}</span>
                        <ActionPopMenu
                            buttons={BoxStatusList.map(stat => {
                                return {
                                    icon: <Circle sx={{ path: { color: getStatusColor(stat) } }} />,
                                    label: t(stat),
                                    onClick() {
                                        setBoxStatusFilter(stat);
                                        setPage(1);
                                    },
                                };
                            })}
                            mainIcon={<FilterList />}
                            placement={{
                                anchorOrigin: {
                                    vertical: 'bottom',
                                    horizontal: 'center',
                                },
                                transformOrigin: {
                                    horizontal: 'center',
                                    vertical: 'top',
                                },
                            }}
                        />
                    </Stack>
                );
            },
            renderCell(data) {
                return (
                    <StatusChangePopup
                        anchor={{
                            status: data.status,
                            text: t(data.status),
                        }}
                        loading={changeStatusIds.includes(data.id)}
                        buttons={boxStatusOptions.map(stat => {
                            return {
                                icon: (
                                    <Circle
                                        sx={{
                                            path: {
                                                color: getStatusColor(stat),
                                            },
                                        }}
                                    />
                                ),
                                label: t(stat),
                                onClick: () => {
                                    onChangeStatus(data.id, stat);
                                },
                            };
                        })}
                    />
                );
            },
        },
        {
            dataKey: 'id',
            label: t('print'),
            width: 120,
            renderHeaderCell(rowIndex) {
                return (
                    <Stack direction={'row'} alignItems={'center'}>
                        <span>{t('print')}</span>
                    </Stack>
                );
            },
            renderCell(data) {
                const total = boxAmounts[data.id];
                return (
                    <Button onClick={() => onPrintBox(data)} disabled={total?.totalAccepted !== total?.totalAmount}>
                        <Print className='h-3 w-3 mr-1' />
                    </Button>
                );
            },
        },
        {
            label: '',
            width: 100,
            numeric: true,
            renderCell(data, rowIndex) {
                return (
                    <ActionPopMenu
                        buttons={[
                            {
                                icon: <RemoveRedEye sx={{ path: { color: '#3489E4' } }} />,
                                label: t('view_packet'),
                                onClick: () => {
                                    navigation.push(pageLinks.dashboard.boxes.detail(data.id));
                                },
                            },
                            {
                                icon: <Edit sx={{ path: { color: '#3489E4' } }} />,
                                label: t('edit'),
                                onClick: () => {
                                    navigation.push(pageLinks.dashboard.boxes.edit(data.id));
                                },
                            },
                            {
                                icon: <Delete sx={{ path: { color: '#3489E4' } }} />,
                                label: t('delete'),
                                onClick: () => {
                                    onDelete(data.id);
                                },
                                dontCloseOnClick: true,
                                loading: deleteIds.includes(data.id),
                            },
                            ...(data.status === 'READY'
                                ? [
                                      {
                                          icon: <Download sx={{ path: { color: '#3489E4' } }} />,
                                          label: t('download_excel'),
                                          onClick: () => {
                                              onDownloadExcel(data.id);
                                          },
                                          loading: downloadIds.includes(data.id),
                                          dontCloseOnClick: true,
                                      },
                                  ]
                                : []),
                        ]}
                    />
                );
            },
        },
    ];

    const [items, setItems] = useState<Product>();
    const [loaer, setLoading] = useState(false);
    const {
        register,
        control,
        handleSubmit,
        watch,
        setValue,
        formState: { errors },
    } = useForm<Product>({
        defaultValues: {
            trekId: items?.trekId,
            name: items?.name,
            nameRu: items?.nameRu,
            amount: items?.amount,
            weight: items?.weight,
            acceptedNumber: Number(values),
        },
    });

    const updateItems = async (item: Product, acceptedNumber: number) => {
        try {
            setLoading(true);

            const updateBody: UpdateProductBodyType = {
                itemId: item.id,
                acceptedNumber: item.amount,
                amount: item.amount,
                name: item.name,
                nameRu: item.nameRu,
                trekId: item.trekId,
                weight: item.weight,
            };

            await item_requests.update(updateBody);

            getListQuery.refetch();
            getBoxesQuery.refetch();

            setValues(prev => ({ ...prev, [item.trekId]: '' }));
            setTrackId('');
        } catch (error) {
            notifyUnknownError(error);
        } finally {
            setLoading(false);
        }
    };

    return (
        <Box>
            <Stack direction={'row'} mb={3} spacing={3}>
                <BaseButton colorVariant='blue' startIcon={<Add />} href={pageLinks.dashboard.boxes.create}>
                    {t('create_packet')}
                </BaseButton>
                <Button onClick={handleOpen}>{t('product_inspection')}</Button>
                <Modal open={open} onClose={handleClose} aria-labelledby='modal-modal-title' aria-describedby='modal-modal-description'>
                    <Box sx={style}>
                        <Typography id='modal-modal-title' variant='h6' component='h2'>
                            {t('product_inspection')}
                        </Typography>
                        <Typography id='modal-modal-description' sx={{ mt: 2 }}>
                            {t('enter_product')}
                        </Typography>
                        <TextField
                            id='outlined-basic'
                            label={t('track_id')}
                            variant='outlined'
                            value={trackId}
                            onChange={e => setTrackId(e.target.value)}
                        />
                        {trackId && trackId.length > 0 && (
                            <>
                                {getListQuery.loading ? (
                                    <Typography sx={{ mt: 2 }}>{t('loading')}...</Typography>
                                ) : getListQuery.data?.data && getListQuery.data?.data.length > 0 ? (
                                    getListQuery.data?.data.map(e => (
                                        <Box key={e.id} sx={{ width: '100%', display: 'flex', flexDirection: 'column' }}>
                                            <Card sx={{ minWidth: 275, mb: 2 }}>
                                                <CardContent>
                                                    <Typography sx={{ fontSize: 14 }}>
                                                        {t('track_id')}: {e.trekId}
                                                    </Typography>
                                                    <Typography sx={{ fontSize: 14 }}>Nomi: {e.name || e.nameRu}</Typography>
                                                    <Typography sx={{ fontSize: 14 }}>Mahsulot soni: {e.amount}</Typography>
                                                    <Typography sx={{ fontSize: 14 }}>Paket nomi: {e?.packetName}</Typography>
                                                </CardContent>
                                            </Card>
                                            <Button
                                                sx={{ mt: '10px' }}
                                                onClick={() => {
                                                    if (values[e.trekId] !== '') {
                                                        updateItems(e, Number(values[e.trekId]));
                                                    }
                                                }}
                                            >
                                                {t('confirmation')}
                                            </Button>
                                        </Box>
                                    ))
                                ) : (
                                    <Typography sx={{ mt: 2 }}>{t('no_products_found') || 'Mahsulot topilmadi'}</Typography>
                                )}
                            </>
                        )}
                    </Box>
                </Modal>
            </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('packet')}
                    </Typography>
                    <Stack direction={'row'} alignItems={'center'} spacing={2}>
                        <BaseInput
                            InputProps={{
                                startAdornment: <Search color='primary' />,
                            }}
                            placeholder={t('filter_packet_name')}
                            value={keyword}
                            onChange={e => {
                                setKeyword(e.target.value);
                            }}
                        />
                        <AsyncSelect
                            isClearable
                            value={partyFilter}
                            onChange={(newValue: any) => {
                                setPartyFilter(newValue);
                                setPage(1);
                            }}
                            styles={selectDefaultStyles}
                            noOptionsMessage={() => t('not_found')}
                            loadingMessage={() => t('loading')}
                            defaultOptions={defaultPartyOptions!}
                            loadOptions={partyOptions}
                            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>

            {/* Print komponenti - sahifaning oxirida yashirin */}
            {selectedBoxDetails && (
                <div style={{ display: 'none' }}>
                    <BoxesPrintList ref={printRef} boxData={selectedBoxDetails} />
                </div>
            )}
        </Box>
    );
};

export default DashboardBoxesPage;
