'use client';

import BaseButton from '@/components/ui-kit/BaseButton';
import BaseIconButton from '@/components/ui-kit/BaseIconButton';
import { useAuthContext } from '@/context/auth-context';
import { box_requests } from '@/data/box/box.requests';
import { item_requests } from '@/data/item/item.requests';
import { party_requests } from '@/data/party/party.requests';
import { FormValues, RealCreateBoxBodyType, UpdateRealBoxBodyType } from '@/data/real-box/real-box.model';
import { real_box_requests } from '@/data/real-box/real-box.requests';
import { pageLinks } from '@/helpers/constants';
import { useMyNavigation } from '@/hooks/useMyNavigation';
import { useMyTranslation } from '@/hooks/useMyTranslation';
import { notifyUnknownError } from '@/services/notification';
import { AddCircleRounded, Close } from '@mui/icons-material';
import {
    Box,
    Checkbox,
    Chip,
    CircularProgress,
    FormControl,
    FormHelperText,
    Grid,
    InputLabel,
    ListItemText,
    MenuItem,
    Select,
    Stack,
    styled,
    Typography,
} from '@mui/material';
import { useQuery } from '@tanstack/react-query';
import get from 'lodash.get';
import { useSearchParams } from 'next/navigation';
import { useEffect, useRef, useState } from 'react';
import { Controller, useFieldArray, useForm } from 'react-hook-form';

const StyledCreateBox = styled(Box)`
    .item-row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 16px;
    }

    & > * {
        flex: 1 1 1;
    }
`;

interface Props {
    partiesData?: { value: number; label: string }[];
    initialValues?: {
        id?: number;
        boxId?: string;
        partyId?: number;
        partyName?: string;
        paketIds?: Array<any>;
    };
}

const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
    const { user } = useAuthContext();
    const editMode = !!initialValues?.id;
    const [keyword, setKeyword] = useState('');
    const t = useMyTranslation();
    const params = useSearchParams();
    const { push } = useMyNavigation();
    const [partyId, setPartyId] = useState<number | string>('');
    const [loading, setLoading] = useState(false);

    // Packetlar uchun scroll state
    const [packetsPage, setPacketsPage] = useState(1);
    const [packetsList, setPacketsList] = useState<any[]>([]);
    const [packetsHasMore, setPacketsHasMore] = useState(true);
    const packetScrollRef = useRef<HTMLDivElement>(null);

    const { isFetching: isLoadingPackets } = useQuery({
        queryKey: ['packets-list', partyId, keyword, packetsPage],
        queryFn: () => box_requests.getAll({ partyId, cargoId: keyword, page: packetsPage }),
        enabled: !!partyId,
        onSuccess: data => {
            const newPackets = data?.data?.data?.data || [];
            setPacketsList(prev => (packetsPage === 1 ? newPackets : [...prev, ...newPackets]));
            const totalPages = data?.data?.data?.totalPages || 0;
            setPacketsHasMore(packetsPage < totalPages);
        },
    });

    const handlePacketScroll = (e: React.UIEvent<HTMLDivElement>) => {
        const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
        const isNearBottom = scrollHeight - scrollTop - clientHeight < 50;

        if (isNearBottom && !isLoadingPackets && packetsHasMore) {
            setPacketsPage(prev => prev + 1);
        }
    };

    const {
        control,
        handleSubmit,
        setValue,
        reset,
        watch,
        formState: { errors },
    } = useForm<FormValues>({
        defaultValues: {
            partyName: initialValues?.partyName || '',
            packetItemDtos: initialValues?.paketIds
                ? initialValues.paketIds.map(paket => ({
                      packetId: paket.id,
                      itemDtos: paket.items ? paket.items.map((item: any) => item.id) : [],
                  }))
                : params.get('party_id')
                  ? [{ packetId: +params.get('party_id')!, itemDtos: [] }]
                  : [{ packetId: 0, itemDtos: [] }],
            id: initialValues?.id,
            boxId: initialValues?.boxId,
            partyId: initialValues?.partyId,
        },
    });

    useEffect(() => {
        if (initialValues) {
            reset({
                partyName: initialValues.partyName || '',
                packetItemDtos: initialValues.paketIds
                    ? initialValues.paketIds.map(paket => ({
                          packetId: paket.id,
                          itemDtos: paket.items ? paket.items.map((item: any) => item.id) : [],
                      }))
                    : [{ packetId: 0, itemDtos: [] }],
                id: initialValues.id,
                boxId: initialValues.boxId,
                partyId: initialValues.partyId,
            });
            if (initialValues.partyId) {
                setPartyId(initialValues.partyId);
            }
        }
    }, [initialValues, reset]);

    const { fields, append, remove } = useFieldArray({
        control,
        name: 'packetItemDtos',
        keyName: 'key',
    });

    const requiredText = t('required');

    const { data: parties = [], isLoading: isLoadingParties } = useQuery({
        queryKey: ['parties-list', 'COLLECTING'],
        queryFn: () => party_requests.getAll({ status: 'COLLECTING' }),
        select: data =>
            data.data.data.data.map((p: any) => ({
                id: p.id,
                name: p.name,
            })),
    });

    const onSubmit = handleSubmit(async values => {
        try {
            setLoading(true);

            if (editMode) {
                const updateBody: UpdateRealBoxBodyType = {
                    boxId: initialValues!.boxId!,
                    partyName: values.partyName,
                    packetItemDtos: values.packetItemDtos.map(packet => ({
                        packetId: packet.packetId,
                        itemDtos: packet.itemDtos,
                    })),
                };
                await real_box_requests.update(updateBody);
            } else {
                const createBody: RealCreateBoxBodyType = {
                    partyName: values.partyName,
                    packetItemDtos: values.packetItemDtos.map(packet => ({
                        packetId: packet.packetId,
                        itemDtos: packet.itemDtos,
                    })),
                };
                await real_box_requests.create(createBody);
            }

            push(pageLinks.dashboard.real_boxes.index);
        } catch (error) {
            notifyUnknownError(error);
        } finally {
            setLoading(false);
        }
    });

    const handlePartyChange = (event: any) => {
        const selectedParty = parties.find(p => p.id === event.target.value);
        if (selectedParty) {
            setValue('partyName', selectedParty.name);
            setPartyId(selectedParty.id);
            setKeyword('');
            setPacketsPage(1);
            setPacketsList([]);
            setPacketsHasMore(true);
            setValue('packetItemDtos', [{ packetId: 0, itemDtos: [] }]);
        }
    };

    const handlePacketChange = (index: number, value: number) => {
        setValue(`packetItemDtos.${index}.packetId`, value);
        setValue(`packetItemDtos.${index}.itemDtos`, []);
    };

    const appendPacket = () => {
        append({ packetId: 0, itemDtos: [] });
    };

    const removePacket = (index: number) => {
        remove(index);
    };

    const PacketRow = ({ index, field }: { index: number; field: any }) => {
        const packetId = watch(`packetItemDtos.${index}.packetId`);

        // Itemlar uchun scroll state
        const [itemsPage, setItemsPage] = useState(1);
        const [itemsList, setItemsList] = useState<any[]>([]);
        const [itemsHasMore, setItemsHasMore] = useState(true);
        const itemScrollRef = useRef<HTMLDivElement>(null);

        const { isLoading: isLoadingProducts } = useQuery({
            queryKey: ['product-list', packetId, itemsPage],
            queryFn: () => item_requests.list({ packetId, page: itemsPage }),
            enabled: !!packetId,
            onSuccess: data => {
                const newItems = data?.data?.data?.data || [];
                setItemsList(prev => (itemsPage === 1 ? newItems : [...prev, ...newItems]));
                // const totalPages = data?.data?.data || 0;
                // setItemsHasMore(itemsPage < totalPages);
            },
        });

        const handleItemScroll = (e: React.UIEvent<HTMLDivElement>) => {
            const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
            const isNearBottom = scrollHeight - scrollTop - clientHeight < 50;

            if (isNearBottom && !isLoadingProducts && itemsHasMore) {
                setItemsPage(prev => prev + 1);
            }
        };

        useEffect(() => {
            // Reset items list when packet changes
            setItemsPage(1);
            setItemsList([]);
            setItemsHasMore(true);
        }, [packetId]);

        const selectedProducts = watch(`packetItemDtos.${index}.itemDtos`) || [];
        const handleSelectAll = (checked: boolean) => {
            if (checked) {
                setValue(
                    `packetItemDtos.${index}.itemDtos`,
                    itemsList.map((p: any) => p.id)
                );
            } else {
                setValue(`packetItemDtos.${index}.itemDtos`, []);
            }
        };

        return (
            <Box className='item-row' mb={2} display={'flex'} flexDirection={'column'}>
                <div style={{ width: '100%' }}>
                    <Typography fontSize='18px' sx={{ textAlign: 'start' }} fontWeight={500} color='#5D5850'>
                        {t('packet')}
                    </Typography>
                </div>
                <Box
                    className='item-row-field'
                    sx={{ width: '100%' }}
                    flex={1}
                    display={'flex'}
                    gap={2}
                    justifyContent={'space-between'}
                    alignItems={'center'}
                >
                    <div style={{ width: '100%' }}>
                        <FormControl fullWidth>
                            <InputLabel id={`packet-select-label-${index}`}>{t('packet')}</InputLabel>
                            <Controller
                                name={`packetItemDtos.${index}.packetId`}
                                control={control}
                                rules={{ required: requiredText }}
                                render={({ field }) => (
                                    <Select
                                        {...field}
                                        labelId={`packet-select-label-${index}`}
                                        label={t('packet')}
                                        onChange={e => {
                                            field.onChange(e);
                                            handlePacketChange(index, e.target.value as number);
                                        }}
                                        value={field.value || ''}
                                        disabled={isLoadingPackets}
                                        MenuProps={{
                                            PaperProps: {
                                                style: { maxHeight: 280 },
                                                ref: packetScrollRef,
                                                onScroll: handlePacketScroll,
                                            },
                                        }}
                                    >
                                        {isLoadingPackets && packetsList.length === 0 ? (
                                            <MenuItem disabled>
                                                <CircularProgress size={24} />
                                            </MenuItem>
                                        ) : (
                                            packetsList.map(packet => (
                                                <MenuItem key={packet.id} value={packet.id}>
                                                    {packet.name || `Box ${packet.id}`}
                                                </MenuItem>
                                            ))
                                        )}
                                        {isLoadingPackets && packetsList.length > 0 && (
                                            <MenuItem disabled>
                                                <CircularProgress size={20} />
                                            </MenuItem>
                                        )}
                                    </Select>
                                )}
                            />
                            {!!get(errors, `packetItemDtos.${index}.packetId`) && (
                                <FormHelperText sx={{ color: 'red' }}>{requiredText}</FormHelperText>
                            )}
                        </FormControl>
                    </div>
                    <div>
                        {fields.length > 1 && (
                            <BaseIconButton
                                size='small'
                                colorVariant='icon-error'
                                sx={{ flexShrink: 0, height: 'auto', marginTop: 1 }}
                                onClick={() => removePacket(index)}
                            >
                                <Close />
                            </BaseIconButton>
                        )}
                    </div>
                </Box>

                {packetId && (
                    <Box mt={2} sx={{ width: '100%' }}>
                        <Typography fontSize='18px' sx={{ textAlign: 'start' }} fontWeight={500} color='#5D5850' mb={2}>
                            {t('products')}
                        </Typography>
                        {isLoadingProducts && itemsList.length === 0 ? (
                            <CircularProgress />
                        ) : (
                            <FormControl fullWidth>
                                <Box display='flex' alignItems='center' mb={1}>
                                    <Checkbox
                                        indeterminate={selectedProducts.length > 0 && selectedProducts.length < itemsList.length}
                                        checked={itemsList.length > 0 && selectedProducts.length === itemsList.length}
                                        onChange={e => handleSelectAll(e.target.checked)}
                                        disabled={itemsList.length === 0}
                                    />
                                    <Typography variant='body2'>{t('select_all')}</Typography>
                                </Box>
                                <Controller
                                    name={`packetItemDtos.${index}.itemDtos`}
                                    control={control}
                                    render={({ field }) => (
                                        <Select
                                            {...field}
                                            multiple
                                            MenuProps={{
                                                PaperProps: {
                                                    style: { maxHeight: 280 },
                                                    ref: itemScrollRef,
                                                    onScroll: handleItemScroll,
                                                },
                                                disableAutoFocus: true,
                                                autoFocus: false,
                                            }}
                                            renderValue={selected => (
                                                <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
                                                    {(selected as any[]).map(value => (
                                                        <Chip
                                                            key={value}
                                                            label={itemsList.find(p => p.id === value)?.name}
                                                            onDelete={e => {
                                                                e.stopPropagation();
                                                                field.onChange(field.value.filter((id: any) => id !== value));
                                                            }}
                                                        />
                                                    ))}
                                                </Box>
                                            )}
                                        >
                                            {itemsList.map(product => (
                                                <MenuItem key={product.id} value={product.id} onClick={e => e.stopPropagation()}>
                                                    <Checkbox checked={field.value.includes(product.id)} />
                                                    <ListItemText primary={product.name} />
                                                </MenuItem>
                                            ))}
                                            {isLoadingProducts && itemsHasMore && (
                                                <MenuItem disabled>
                                                    <Box display='flex' justifyContent='center' width='100%'>
                                                        <CircularProgress size={20} />
                                                    </Box>
                                                </MenuItem>
                                            )}
                                        </Select>
                                    )}
                                />
                            </FormControl>
                        )}
                    </Box>
                )}
            </Box>
        );
    };

    return (
        <StyledCreateBox
            width={1}
            mb={3}
            sx={{
                padding: '28px',
                borderRadius: '16px',
                backgroundColor: '#fff',
            }}
        >
            <Box component='form' onSubmit={onSubmit}>
                <Typography variant='h5' mb={3.5}>
                    {editMode ? t('update_box') : t('create_box')}
                </Typography>

                <Grid container columnSpacing={2.5} rowSpacing={3} mb={3.5}>
                    <Grid item xs={12}>
                        <Typography fontSize='18px' fontWeight={500} color='#5D5850' mb={2}>
                            {t('party_name')}
                        </Typography>
                        <FormControl fullWidth>
                            <InputLabel id='party-select-label'>{t('party_name')}</InputLabel>
                            <Controller
                                name='partyId'
                                control={control}
                                rules={{ required: requiredText }}
                                render={({ field }) => (
                                    <Select
                                        {...field}
                                        labelId='party-select-label'
                                        label={t('party_name')}
                                        onChange={e => {
                                            field.onChange(e);
                                            handlePartyChange(e);
                                        }}
                                        value={field.value || ''}
                                        disabled={isLoadingParties}
                                    >
                                        {isLoadingParties ? (
                                            <MenuItem disabled>
                                                <CircularProgress size={24} />
                                            </MenuItem>
                                        ) : (
                                            parties.map(party => (
                                                <MenuItem key={party.id} value={party.id}>
                                                    {party.name}
                                                </MenuItem>
                                            ))
                                        )}
                                    </Select>
                                )}
                            />
                            {!!errors.partyId && <FormHelperText sx={{ color: 'red' }}>{requiredText}</FormHelperText>}
                        </FormControl>
                    </Grid>

                    <Grid item xs={12}>
                        <Stack
                            sx={{
                                borderRadius: '8px',
                                border: '2px solid #3489E4',
                                background: '#FFF',
                                padding: '24px',
                                gap: '12px',
                                display: 'flex',
                                flexDirection: 'column',
                            }}
                        >
                            <div>
                                {fields.map((field, index) => (
                                    <PacketRow key={field.key} index={index} field={field} />
                                ))}
                                <BaseButton variant='outlined' onClick={appendPacket} startIcon={<AddCircleRounded />} sx={{ mt: 2 }}>
                                    {t('add_packet')}
                                </BaseButton>
                            </div>
                        </Stack>
                    </Grid>
                </Grid>

                <BaseButton variant='contained' type='submit' disabled={loading} fullWidth sx={{ py: 1.5 }}>
                    {loading ? <CircularProgress size={24} color='inherit' /> : editMode ? t('update_box') : t('create_box')}
                </BaseButton>
            </Box>
        </StyledCreateBox>
    );
};

export default DashboardCreateRealBoxPage;
