import React, {
    createRef,
    forwardRef,
    useEffect,
    useImperativeHandle,
    useState,
} from 'react';

import dayjs from 'dayjs';
import { get } from 'lodash';
import {
    ArrowDownLeft,
    ArrowUpRight,
    CircleMinus,
    CirclePlus,
    FileSpreadsheet,
    Plus,
    Wallet,
    XIcon,
} from 'lucide-react';

import { rpc } from '@/api/request';
import {
    ArgsMakeStatementExportInput,
    BalanceFPType,
    BalancePaymentType,
    TypeAIOEnum,
} from '@/api/types';
import { DateEditableField } from '@/components/CollectionFields/components/ItemData/DateEditableField';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
    Empty,
    EmptyDescription,
    EmptyHeader,
    EmptyMedia,
    EmptyTitle,
} from '@/components/ui/empty';
import { Label } from '@/components/ui/label';
import {
    MobileCard,
    MobileLink,
    MobileList,
    MobileListItem,
    MobileNavbar,
    MobilePage,
    MobilePopup,
} from '@/components/ui/mobile';
import {
    RadioGroup,
    RadioGroupItem,
} from '@/components/ui/radio-group';
import { ScrollArea } from '@/components/ui/scroll-area';
import { SystemWindowDialog } from '@/components/ui/system-window-dialog';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import {
    Tabs,
    TabsContent,
    TabsList,
    TabsTrigger,
} from '@/components/ui/tabs';
import { confirmAlertRef } from '@/componentsRoot/ConfirmAlert';
import { exportDialogRef } from '@/componentsRoot/ExportDialog';
import { paymentDialogRef } from '@/componentsRoot/PaymentDialog';
import { toast } from '@/componentsRoot/ToastRoot';
import {
    Lang,
    useLang,
} from '@/lang/Lang';
import { useLLText } from '@/lang/localizationService';
import { cn } from '@/lib/utils';
import useAppConfigStore from '@/stores/appConfig';
import { useMainPage } from '@/stores/mainPage';

type BalanceAndPaymentDialogRefType = {
    open: () => void;
    close: () => void;
}

type OperationsTab = 'all' | 'earn' | 'spend';
type ExportPeriodMode = 'all' | 'range';

const tabToApiType = (tab: OperationsTab): TypeAIOEnum => {
    if (tab === 'earn') return 'in';
    if (tab === 'spend') return 'out';
    return 'all';
};

export const balanceAndPaymentDialogRef = createRef<BalanceAndPaymentDialogRefType>();

export const BalanceAndPaymentDialog = forwardRef<BalanceAndPaymentDialogRefType, {}>((_, ref) => {
    const [open, setOpen] = useState(false);


    const { profile } = useMainPage();

    useImperativeHandle(ref, () => ({
        open: () => {




            setOpen(true);
        },
        close: () => setOpen(false),
    }));


    const [activeTab, setActiveTab] = useState<OperationsTab>('all');
    const [operationsByType, setOperationsByType] = useState<Partial<Record<TypeAIOEnum, BalancePaymentType[]>>>({});

    const [exportOpen, setExportOpen] = useState(false);
    const [exportCurrency, setExportCurrency] = useState('');
    const [exportPeriodMode, setExportPeriodMode] = useState<ExportPeriodMode>('all');
    const [exportFrom, setExportFrom] = useState<number | null>(null);
    const [exportTo, setExportTo] = useState<number | null>(null);

    const loadOperations = (apiType: TypeAIOEnum) => {
        rpc.lastBalanceOperations({ type: apiType }).then((data) => {
            setOperationsByType((prev) => ({
                ...prev,
                [apiType]: data.result ?? [],
            }));
        });
    };

    useEffect(() => {
        if (!open) return;

        setActiveTab('all');
        setOperationsByType({});
        loadOperations('all');
    }, [open]);

    const handleTabChange = (value: string) => {
        const tab = value as OperationsTab;
        setActiveTab(tab);

        const apiType = tabToApiType(tab);
        if (operationsByType[apiType] === undefined) {
            loadOperations(apiType);
        }
    };

    const getBalanceValue = (path?: string) => {
        if (!profile?.data) return 0;
        if (!path) return 0;
        return get(profile.data, path) ?? 0;
    };

    const formatOperationAmount = (amount?: number) => {
        const value = amount ?? 0;
        if (value > 0) return `+${value}`;
        return `${value}`;
    };

    const BalanceItem = ({ balance }: { balance: BalanceFPType }) => {
        const lang = useLang();
        const value = getBalanceValue(balance.path);
        const label = useLLText(balance.field?.title ?? balance.field?.currency ?? '', lang);
        const isNegative = Number(value) < 0;

        return (
            <div className="flex min-w-[280px] flex-1 flex-col gap-2 rounded-lg border bg-muted/20 px-3 py-2.5">
                <div className="flex items-center gap-3">
                    <div
                        className={cn(
                            'flex size-9 shrink-0 items-center justify-center rounded-full',
                            'bg-gradient-to-br from-primary/20 via-primary/10 to-primary/5',
                            'text-xl font-semibold leading-none text-primary',
                            'ring-1 ring-primary/20 shadow-sm'
                        )}
                    >
                        <span className="translate-y-px">
                            {balance.field?.currencySymbol
                                ?? balance.field?.currency?.slice(0, 1).toUpperCase()
                                ?? '—'}
                        </span>
                    </div>
                    <div className="min-w-0 flex-1">

                        <p className={cn('truncate text-base font-semibold tabular-nums leading-tight', isNegative && 'text-destructive')}>
                            {value.toLocaleString(undefined, { maximumFractionDigits: 2 })}
                            {balance.field?.currency && (
                                <span className="ml-1 text-xs font-normal text-muted-foreground">
                                    {balance.field.currency}
                                </span>
                            )}
                        </p>
                    </div>
                </div>
                <div className="flex flex-wrap gap-1.5">
                    <Button size="sm" variant="outline" onClick={() => onTopUpBalance(balance)}>
                        <Plus className="size-3.5" />
                        {Lang.key('top_up_balance')}
                    </Button>
                    <Button size="sm" variant="outline" onClick={() => exportReport(balance)}>
                        <FileSpreadsheet className="size-3.5" />
                        {Lang.key('export_report')}
                    </Button>
                </div>
            </div>
        );
    };

    const PaymentTable = ({ type }: { type: OperationsTab }) => {
        const data = operationsByType[tabToApiType(type)] ?? [];

        if (data.length === 0) {
            return (
                <Empty className="border-0 py-12">
                    <EmptyHeader>
                        <EmptyMedia variant="icon">
                            <Wallet />
                        </EmptyMedia>
                        <EmptyTitle>{Lang.key('not_found_payment')}</EmptyTitle>
                        <EmptyDescription>
                            {Lang.key('payment_history_description_one')}
                        </EmptyDescription>
                    </EmptyHeader>
                </Empty>
            );
        }

        return (
            <Table className="w-full">
                <TableHeader className="sticky top-0 z-10 bg-background/95 backdrop-blur-sm">
                    <TableRow>
                        <TableHead className="w-[170px]">{Lang.key('date')}</TableHead>
                        <TableHead className="w-[140px]">{Lang.key('payment_type')}</TableHead>
                        <TableHead className="w-full">{Lang.key('payment_description')}</TableHead>
                        <TableHead className="w-[100px] text-right">{Lang.key('payment_amount')}</TableHead>
                        <TableHead className="w-[90px] text-right">{Lang.key('payment_currency')}</TableHead>
                    </TableRow>
                </TableHeader>
                <TableBody>
                    {data.map((invoice) => {
                        const isEarn = (invoice.amount ?? 0) > 0;

                        return (
                            <TableRow key={invoice._id} className="hover:bg-muted/30">
                                <TableCell className="text-muted-foreground whitespace-nowrap">
                                    {!!invoice.created_at && dayjs.unix(invoice.created_at).format('DD.MM.YYYY HH:mm')}
                                </TableCell>
                                <TableCell>
                                    <Badge
                                        variant="outline"
                                        className={cn(
                                            'gap-1 font-normal',
                                            isEarn
                                                ? 'border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-400'
                                                : 'border-orange-500/30 bg-orange-500/10 text-orange-700 dark:text-orange-400'
                                        )}
                                    >
                                        {isEarn ? (
                                            <ArrowUpRight className="size-3" />
                                        ) : (
                                            <ArrowDownLeft className="size-3" />
                                        )}
                                        {isEarn ? Lang.key('payment_earn') : Lang.key('payment_spend')}
                                    </Badge>
                                </TableCell>
                                <TableCell>
                                    <p className="text-sm leading-snug break-words whitespace-normal">
                                        {invoice.description || '—'}
                                    </p>
                                </TableCell>
                                <TableCell
                                    className={cn(
                                        'w-[100px] text-right font-medium tabular-nums whitespace-nowrap',
                                        isEarn ? 'text-emerald-600 dark:text-emerald-400' : 'text-foreground'
                                    )}
                                >
                                    {formatOperationAmount(invoice.amount)}
                                </TableCell>
                                <TableCell className="text-right text-muted-foreground">
                                    {invoice.currency}
                                </TableCell>
                            </TableRow>
                        );
                    })}
                </TableBody>
            </Table>
        );
    };

    const exportReport = (balance: BalanceFPType) => {
        if (!balance.field?.currency) return;

        setExportCurrency(balance.field.currency);
        setExportPeriodMode('all');
        setExportFrom(null);
        setExportTo(null);
        setExportOpen(true);
    };

    const canSubmitExport = exportPeriodMode === 'all'
        || (exportFrom != null && exportTo != null && exportFrom <= exportTo);

    const submitExport = () => {
        if (!exportCurrency || !canSubmitExport) return;

        const params: ArgsMakeStatementExportInput = {
            currency: exportCurrency,
        };

        if (exportPeriodMode === 'range' && exportFrom != null && exportTo != null) {
            params.range = {
                from: dayjs.unix(exportFrom).startOf('day').unix(),
                to: dayjs.unix(exportTo).endOf('day').unix(),
            };
        }

        setExportOpen(false);

        const loading = toast.loading(Lang.key('exporting_report'));
        rpc.makeStatementExport(params).then(() => {
            toast.success(Lang.key('report_exported_successfully'));
            exportDialogRef.current?.open();
        }).catch(() => {
            exportDialogRef.current?.open();
        }).finally(() => {
            toast.dismiss(loading);
        });
    };

    const onTopUpBalance = (balance: BalanceFPType) => {

        if (!balance.field?.gateways?.length) {

            confirmAlertRef.current?.open({
                title: Lang.key('no_gateways_available'),
                description: Lang.key('no_gateways_available_description'),
                buttons: [
                    { label: Lang.key('close'), onClick: () => { } },
                ]
            });

        } else {
            paymentDialogRef.current?.open({
                gateways: balance.field?.gateways ?? [],
            });
        }

    }

    const { isMobile } = useAppConfigStore();

    if (isMobile) {
        return <MobilePopup
            opened={open}
            onBackdropClick={() => setOpen(false)}
        >
            <MobilePage className="flex flex-col">
                <MobileNavbar

                    title={Lang.key('payment_and_balance')}
                    right={<MobileLink onClick={() => setOpen(false)}><XIcon /></MobileLink>}
                />




                <div>

                    <div>
                        {profile?.balances?.map((e) => {
                            return <MobileCard outline


                            >

                                <div className='flex items-center justify-between'>

                                    <div className='flex items-center gap-2 w-full'>
                                        <div
                                            className='w-10 h-10 rounded-full bg-gray-300 flex items-center justify-center'
                                        >
                                            <div className='text-2xl font-bold text-gray-500'>{e.field?.currencySymbol}</div>
                                        </div>

                                        <div className='text-lg font-medium'>{getBalanceValue(e?.path)}</div>
                                    </div>

                                    <Button onClick={() => {
                                        onTopUpBalance(e);
                                    }}>
                                        <Plus />
                                    </Button>

                                </div>


                            </MobileCard>
                        })}
                    </div>


                    <div className='px-4'>

                        <div className='text-lg font-medium mt-4'>{Lang.key('payment_history')}</div>
                        <div className='text-xs text-gray-500'>{Lang.key('payment_history_description_one')}</div>
                        <div className='text-xs text-gray-500'>{Lang.key('payment_history_description_two')}</div>
                        <div className='text-xs text-gray-500'>{Lang.key('payment_history_last_100_hint')}</div>

                    </div>
                    <MobileList outline>
                        {(operationsByType.all ?? []).map((e) => {
                            return <MobileListItem key={e._id}
                                dividers
                                media={!!e.amount ? e.amount > 0 ? <CirclePlus /> : <CircleMinus /> : undefined}
                                header={e.description}
                                title={e.amount}
                                after={e.currency}
                                footer={e.created_at ? dayjs.unix(e.created_at).format('DD.MM.YYYY HH:mm') : ''}

                            >

                            </MobileListItem>
                        })}


                    </MobileList>


                </div>




            </MobilePage>
        </MobilePopup>
    }

    return (
        <>
            <SystemWindowDialog
                open={open}
                onOpenChange={setOpen}
                title={Lang.key('payment_and_balance')}

                width="80vw"
                height="80vh"
                allowFullscreen
                bodyClassName="p-0 overflow-hidden flex flex-col"
            >
                <div className="flex min-h-0 flex-1 flex-col overflow-hidden px-4 pb-4">
                    <div className="flex shrink-0 flex-wrap gap-3 border-b px-5 py-3">
                        {profile?.balances?.map((balance) => (
                            <BalanceItem key={balance.path ?? balance.field?.key} balance={balance} />
                        ))}
                    </div>

                    <div className="flex min-w-0 flex-1 flex-col overflow-hidden">
                        <div className="flex shrink-0 items-center justify-between gap-4 border-b px-5 py-2.5">
                            <div>
                                <h3 className="text-sm font-medium">{Lang.key('payment_history')}</h3>
                                <p className="text-xs text-muted-foreground">
                                    {Lang.key('payment_history_description_two')}
                                </p>
                                <p className="text-xs text-muted-foreground">
                                    {Lang.key('payment_history_last_100_hint')}
                                </p>
                            </div>
                        </div>

                        <Tabs value={activeTab} onValueChange={handleTabChange} className="flex min-h-0 flex-1 flex-col gap-0">
                            <TabsList className="mx-5 mt-3 mb-0 h-auto w-fit shrink-0 flex-wrap gap-1 bg-muted/60 p-1">
                                <TabsTrigger value="all" className="gap-0 px-3">
                                    {Lang.key('all_operations')}
                                </TabsTrigger>
                                <TabsTrigger value="earn" className="gap-0 px-3">
                                    {Lang.key('earn_balance')}
                                </TabsTrigger>
                                <TabsTrigger value="spend" className="gap-0 px-3">
                                    {Lang.key('spend_balance')}
                                </TabsTrigger>
                            </TabsList>

                            <div className="min-h-0 flex-1 overflow-hidden px-5 py-3">
                                {(['all', 'earn', 'spend'] as const).map((tab) => (
                                    <TabsContent
                                        key={tab}
                                        value={tab}
                                        className="m-0 flex h-full min-h-0 flex-col overflow-hidden rounded-lg border"
                                    >
                                        <ScrollArea className="h-full">
                                            <PaymentTable type={tab} />
                                        </ScrollArea>
                                    </TabsContent>
                                ))}
                            </div>
                        </Tabs>
                    </div>
                </div>
            </SystemWindowDialog>

            <SystemWindowDialog
                open={exportOpen}
                onOpenChange={setExportOpen}
                title={Lang.key('export_report_period_title')}
                width={448}
                footer={
                    <>
                        <Button variant="outline" onClick={() => setExportOpen(false)}>
                            {Lang.key('cancel')}
                        </Button>
                        <Button disabled={!canSubmitExport} onClick={submitExport}>
                            {Lang.key('export_report')}
                        </Button>
                    </>
                }
            >
                <div className="flex flex-col gap-4">
                    <RadioGroup
                        className="gap-2"
                        value={exportPeriodMode}
                        onValueChange={(value) => setExportPeriodMode(value as ExportPeriodMode)}
                    >
                        <label
                            htmlFor="export-period-all"
                            className={cn(
                                'flex cursor-pointer items-center gap-3 rounded-lg border p-3 transition-colors',
                                exportPeriodMode === 'all'
                                    ? 'border-primary bg-primary/5 ring-1 ring-primary/20'
                                    : 'border-border hover:bg-accent/40'
                            )}
                        >
                            <div className="min-w-0 flex-1">
                                <p className="font-medium leading-none">{Lang.key('export_all_time')}</p>
                            </div>
                            <RadioGroupItem value="all" id="export-period-all" className="shrink-0" />
                        </label>
                        <label
                            htmlFor="export-period-range"
                            className={cn(
                                'flex cursor-pointer items-center gap-3 rounded-lg border p-3 transition-colors',
                                exportPeriodMode === 'range'
                                    ? 'border-primary bg-primary/5 ring-1 ring-primary/20'
                                    : 'border-border hover:bg-accent/40'
                            )}
                        >
                            <div className="min-w-0 flex-1">
                                <p className="font-medium leading-none">{Lang.key('export_for_period')}</p>
                            </div>
                            <RadioGroupItem value="range" id="export-period-range" className="shrink-0" />
                        </label>
                    </RadioGroup>

                    {exportPeriodMode === 'range' && (
                        <div className="grid grid-cols-2 gap-3">
                            <div className="space-y-2">
                                <Label>{Lang.key('from')}</Label>
                                <DateEditableField
                                    withTime={false}
                                    value={exportFrom}
                                    onChange={setExportFrom}
                                    placeholder="DD.MM.YYYY"
                                />
                            </div>
                            <div className="space-y-2">
                                <Label>{Lang.key('to')}</Label>
                                <DateEditableField
                                    withTime={false}
                                    value={exportTo}
                                    onChange={setExportTo}
                                    placeholder="DD.MM.YYYY"
                                />
                            </div>
                        </div>
                    )}
                </div>
            </SystemWindowDialog>
        </>
    );

});