'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,
    Button,
    Checkbox,
    Chip,
    CircularProgress,
    FormControl,
    FormHelperText,
    Grid,
    InputLabel,
    ListItemText,
    MenuItem,
    OutlinedInput,
    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, useMemo, 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 t = useMyTranslation();
    const params = useSearchParams();
    const { push } = useMyNavigation();
    const [partyId, setPartyId] = useState<number | string>(initialValues?.partyId || '');
    const [loading, setLoading] = useState(false);

    const selectMenuProps = useMemo(
        () => ({
            PaperProps: { style: { maxHeight: 280 } },
            autoFocus: false,
            disableAutoFocus: true,
            disableEnforceFocus: true,
            disableRestoreFocus: true,
            disableScrollLock: true,
        }),
        []
    );

    // Barcha box/packetlarni barcha sahifadan yuklash uchun state
    const [allPackets, setAllPackets] = useState<any[]>([]);
    // Barcha mahsulotlarni barcha sahifadan yuklash uchun map
    const [allItemsMap, setAllItemsMap] = useState<{ [packetId: number]: any[] }>({});

    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,
        },
    });

    // Paketlar va mahsulotlarni yuklash
    const [isLoadingPackets, setIsLoadingPackets] = useState(false);
    useEffect(() => {
        const fetchAllPackets = async () => {
            if (!partyId) {
                setAllPackets([]);
                return;
            }
            setIsLoadingPackets(true);
            let packets: any[] = [];
            let totalPages = 1;
            try {
                const firstRes = await box_requests.getAll({ partyId, page: 1 });
                const firstData = firstRes?.data?.data;
                packets = firstData?.data || [];
                totalPages = firstData?.totalPages || 1;

                if (totalPages > 1) {
                    const promises = [];
                    for (let page = 2; page <= totalPages; page++) {
                        promises.push(box_requests.getAll({ partyId, page }));
                    }
                    const results = await Promise.all(promises);
                    results.forEach(res => {
                        const data = res?.data?.data;
                        packets = [...packets, ...(data?.data || [])];
                    });
                }
            } catch (e) {}
            setAllPackets(packets);
            setIsLoadingPackets(false);
        };
        fetchAllPackets();
    }, [partyId]);

    const fetchAllItemsForPacket = async (packetId: number) => {
        let items: any[] = [];
        let totalPages = 1;
        try {
            const firstRes = await item_requests.getAll({ packetId, page: 1 });
            const firstData = firstRes?.data?.data;
            items = firstData?.data || [];
            totalPages = firstData?.totalPages || 1;
            if (totalPages > 1) {
                const promises = [];
                for (let page = 2; page <= totalPages; page++) {
                    promises.push(item_requests.getAll({ packetId, page }));
                }
                const results = await Promise.all(promises);
                results.forEach(res => {
                    const data = res?.data?.data;
                    items = [...items, ...(data?.data || [])];
                });
            }
        } catch (e) {}
        setAllItemsMap(prev => ({ ...prev, [packetId]: items }));
        return items;
    };

    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);
            }
            if (initialValues.paketIds) {
                initialValues.paketIds.forEach((paket: any) => {
                    fetchAllItemsForPacket(paket.id);
                });
            }
        }
    }, [initialValues, reset]);

    // useFieldArray keyName="key" orqali unique key
    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 appendPacket = () => {
        append({ packetId: 0, itemDtos: [] });
        setTimeout(() => {
            document.activeElement instanceof HTMLElement && document.activeElement.blur();
        }, 0);
    };

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

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

    const PacketRow = ({ index, field }: { index: number; field: any }) => {
        const packetId = watch(`packetItemDtos.${index}.packetId`);
        const [keyword, setKeyword] = useState<string>('');
        const [selectedProductNames, setSelectedProductNames] = useState<{ [productId: number]: string }>({});
        const packetsList = keyword ? allPackets.filter(p => (p.name || '').toLowerCase().includes(keyword.toLowerCase())) : allPackets;
        const itemsList = allItemsMap[packetId] || [];
        const loadingItems = !allItemsMap[packetId] && !!packetId;

        useEffect(() => {
            if (packetId && !allItemsMap[packetId]) {
                fetchAllItemsForPacket(packetId);
            }
        }, [packetId]);

        useEffect(() => {
            if (packetId && field?.itemDtos?.length && itemsList.length) {
                const names: { [productId: number]: string } = {};
                field.itemDtos.forEach((id: number) => {
                    const prod = itemsList.find(p => p.id === id);
                    names[id] = prod?.name || prod?.nameRu || String(id);
                });
                setSelectedProductNames(names);
            }
        }, [field?.itemDtos, itemsList, packetId]);

        const handleProductChange = (product: any, checked: boolean) => {
            setSelectedProductNames(prev => {
                if (checked) {
                    return { ...prev, [product.id]: product.name || product.nameRu || String(product.id) };
                } else {
                    const newNames = { ...prev };
                    delete newNames[product.id];
                    return newNames;
                }
            });
        };

        useEffect(() => {
            const element = document.getElementById(`packet-select-${index}`);
            if (element) {
                element.scrollIntoView({ behavior: 'smooth', block: 'center' });
            }
        }, [fields.length]);

        const handleSelectAllProducts = async () => {
            if (!packetId) return;
            let allProducts = allItemsMap[packetId] || [];
            if (!allProducts.length) {
                allProducts = await fetchAllItemsForPacket(packetId);
            }
            if (allProducts.length > 0) {
                setValue(
                    `packetItemDtos.${index}.itemDtos`,
                    allProducts.map((p: any) => p.id)
                );
                setSelectedProductNames(
                    allProducts.reduce(
                        (acc, p) => ({
                            ...acc,
                            [p.id]: p.name || p.nameRu || String(p.id),
                        }),
                        {}
                    )
                );
            }
        };

        const handleClearAll = () => {
            setValue(`packetItemDtos.${index}.itemDtos`, []);
            setSelectedProductNames({});
        };

        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'}
                >
                    <OutlinedInput onChange={e => setKeyword(e.target.value)} autoFocus={false} />
                    <div style={{ width: '100%' }}>
                        <FormControl fullWidth>
                            <InputLabel id={`packet-select-label-${index}`}>{t('packet')}</InputLabel>
                            <Controller
                                name={`packetItemDtos.${index}.packetId`}
                                control={control}
                                render={({ field: selectField }) => (
                                    <Select
                                        {...selectField}
                                        autoFocus={false}
                                        labelId={`packet-select-label-${index}`}
                                        id={`packet-select-${index}`}
                                        label={t('packet')}
                                        MenuProps={selectMenuProps}
                                        onChange={e => {
                                            e.stopPropagation();
                                            selectField.onChange(e);
                                        }}
                                        value={selectField.value || ''}
                                        renderValue={selected => {
                                            const selectedPacket = packetsList.find(p => p.id === selected);
                                            return selectedPacket ? selectedPacket.name : t('loading');
                                        }}
                                    >
                                        {isLoadingPackets ? (
                                            <MenuItem disabled>
                                                <CircularProgress size={24} />
                                            </MenuItem>
                                        ) : packetsList.length === 0 ? (
                                            <MenuItem disabled>{t('not_found') || 'Paketlar topilmadi'}</MenuItem>
                                        ) : (
                                            packetsList.map(packet => (
                                                <MenuItem key={packet.id} value={packet.id}>
                                                    {packet.name}
                                                </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%' }}>
                        <Box display='flex' justifyContent='space-between' alignItems='center' mb={2}>
                            <Typography fontSize='18px' sx={{ textAlign: 'start' }} fontWeight={500} color='#5D5850'>
                                {t('products')}
                            </Typography>
                            <Box>
                                <Button size='small' color='primary' variant='outlined' sx={{ mr: 1 }} onClick={handleSelectAllProducts}>
                                    {t('select_all') || 'Barcha mahsulotni tanlash'}
                                </Button>
                                <Button size='small' color='error' variant='outlined' onClick={handleClearAll}>
                                    {t('cancel') || 'Hammasini bekor qilish'}
                                </Button>
                            </Box>
                        </Box>
                        {loadingItems ? (
                            <CircularProgress />
                        ) : (
                            <FormControl fullWidth>
                                <Controller
                                    name={`packetItemDtos.${index}.itemDtos`}
                                    control={control}
                                    render={({ field }) => (
                                        <Select
                                            {...field}
                                            multiple
                                            MenuProps={selectMenuProps}
                                            renderValue={selected => (
                                                <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
                                                    {(selected as any[]).map((id: number) => (
                                                        <Chip
                                                            key={id}
                                                            label={
                                                                selectedProductNames[id] ||
                                                                itemsList.find(p => p.id === id)?.name ||
                                                                itemsList.find(p => p.id === id)?.nameRu ||
                                                                id
                                                            }
                                                            onDelete={e => {
                                                                e.stopPropagation();
                                                                field.onChange(field.value.filter((x: any) => x !== id));
                                                                handleProductChange({ id }, false);
                                                            }}
                                                        />
                                                    ))}
                                                </Box>
                                            )}
                                        >
                                            {itemsList.map(product => (
                                                <MenuItem
                                                    key={product.id}
                                                    value={product.id}
                                                    onClick={e => {
                                                        e.stopPropagation();
                                                        const checked = !field.value.includes(product.id);
                                                        let newValue;
                                                        if (checked) {
                                                            newValue = [...field.value, product.id];
                                                        } else {
                                                            newValue = field.value.filter((x: any) => x !== product.id);
                                                        }
                                                        field.onChange(newValue);
                                                        handleProductChange(product, checked);
                                                    }}
                                                >
                                                    <Checkbox checked={field.value.includes(product.id)} />
                                                    <ListItemText primary={product.name || product.nameRu || product.id} />
                                                </MenuItem>
                                            ))}
                                        </Select>
                                    )}
                                />
                            </FormControl>
                        )}
                    </Box>
                )}
            </Box>
        );
    };

    return (
        <StyledCreateBox
            width={1}
            mb={3}
            sx={{
                padding: '28px',
                borderRadius: '16px',
                backgroundColor: '#fff',
            }}
        >
            <Box component='form' onSubmit={onSubmit} sx={{ overflowAnchor: 'none' }}>
                <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')}
                                        MenuProps={selectMenuProps}
                                        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_more')}
                                </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;
