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

import _ from 'lodash';
import {
    Check,
    CreditCard,
    Loader2,
    XIcon,
} from 'lucide-react';

import { rpc } from '@/api/request';
import { GatewayCDKTType } from '@/api/types';
import { Lang } from '@/lang/Lang';

import { toast } from './ToastRoot';
import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    MobileFab,
    MobileLink,
    MobileNavbar,
    MobilePage,
    MobilePopup,
} from '@/components/ui/mobile';
import {
    RadioGroup,
    RadioGroupItem,
} from '@/components/ui/radio-group';
import { cn } from '@/lib/utils';
import useAppConfigStore from '@/stores/appConfig';

type ActionOpenParams = {
    gateways: GatewayCDKTType[];
}

type PaymentDialogRefProps = {
    open: (params: ActionOpenParams) => void;
}

export const paymentDialogRef = React.createRef<PaymentDialogRefProps>();

const PaymentDialog = forwardRef<PaymentDialogRefProps, {}>((propd, ref) => {


    const { isMobile } = useAppConfigStore();



    const [open, setOpen] = useState<boolean>(false);


    const [loading, setLoading] = useState<boolean>(false);

    const [selectedGateway, setSelectedGateway] = useState<GatewayCDKTType | null>(null);
    const [amount, setAmount] = useState<number>(0);
    const [gateways, setGateways] = useState<GatewayCDKTType[]>([]);

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

            setGateways(params.gateways);
            setSelectedGateway(null);
            setAmount(0);
            setOpen(true);
        }
    }));

    const onPayNow = () => {
        if (!selectedGateway?.key) {

            toast.error(Lang.key('select_payment_method'));

            return;
        }
        if (!!selectedGateway.minAmount && amount < (selectedGateway.minAmount ?? 0)) {
            toast.error(Lang.key('amount_is_less_than_minimum'));
            return;
        }
        if (!!selectedGateway.maxAmount && amount > (selectedGateway.maxAmount ?? 0)) {
            toast.error(Lang.key('amount_is_greater_than_maximum'));
            return;
        }



        setLoading(true);
        rpc.generatePaymentLink({
            currency: selectedGateway?.currency ?? '',
            gateway: selectedGateway.key,
            amount: amount,
        }).then((data) => {
            if (data?.result) {
                window.open(data.result, '_blank');
            }

            setOpen(false);

        }).finally(() => {
            setLoading(false);
        })

    }



    const getLimitsString = (gateway: GatewayCDKTType) => {


        let result = [];
        if (!!gateway?.minAmount) {
            result.push(Lang.key("min_amount") + " " + gateway?.minAmount);
        }
        if (!!gateway?.maxAmount) {
            result.push(Lang.key("max_amount") + " " + gateway?.maxAmount);
        }
        return result.join(", ");
    }

    const currencyLabel = selectedGateway?.currency ?? gateways[0]?.currency;

    const handleAmountChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const value = e.target.value;
        if (value !== '' && isNaN(Number(value))) {
            return;
        }
        setAmount(value === '' ? 0 : _.toNumber(value));
    };

    const renderGatewayIcon = (gateway: GatewayCDKTType) => {
        if (gateway.icon) {
            return (
                <img
                    src={gateway.icon}
                    alt={gateway.title ?? ''}
                    className="size-5 object-contain"
                />
            );
        }

        return <CreditCard className="size-5 text-muted-foreground" />;
    };

    const renderAmountField = (large = false) => (
        <div className="space-y-2">
            <Label>{Lang.key('amount')}</Label>
            <div className="relative">
                {!!currencyLabel && (
                    <span className="absolute left-3 top-1/2 -translate-y-1/2 text-sm text-muted-foreground">
                        {currencyLabel}
                    </span>
                )}
                <Input
                    className={cn(
                        'font-semibold',
                        large ? 'h-14 text-2xl' : 'h-12 text-lg',
                        large && !currencyLabel && 'text-center',
                        currencyLabel && 'pl-14'
                    )}
                    value={amount || ''}
                    placeholder="0"
                    onChange={handleAmountChange}
                    type="number"
                    inputMode="decimal"
                />
            </div>
            {!!selectedGateway && (
                <p className={cn('text-muted-foreground', large ? 'text-center text-xs' : 'text-xs')}>
                    {getLimitsString(selectedGateway)}
                </p>
            )}
        </div>
    );

    const renderGateways = () => (
        <RadioGroup
            className="gap-2"
            value={selectedGateway?.key ?? ''}
            onValueChange={(value) => setSelectedGateway(gateways.find((gateway) => gateway.key === value) ?? null)}
        >
            {gateways.map((gateway) => {
                const isSelected = selectedGateway?.key === gateway.key;
                const limits = getLimitsString(gateway);

                return (
                    <label
                        key={gateway.key}
                        htmlFor={gateway.key ?? ''}
                        className={cn(
                            'flex cursor-pointer items-center gap-3 rounded-lg border p-3 transition-colors',
                            isSelected
                                ? 'border-primary bg-primary/5 ring-1 ring-primary/20'
                                : 'border-border hover:bg-accent/40'
                        )}
                    >
                        <div className="flex size-10 shrink-0 items-center justify-center rounded-full bg-muted">
                            {renderGatewayIcon(gateway)}
                        </div>
                        <div className="min-w-0 flex-1">
                            <p className="font-medium leading-none">{gateway.title ?? ''}</p>
                            {!!gateway.description && (
                                <p className="mt-1 text-xs text-muted-foreground">{gateway.description}</p>
                            )}
                            {!!limits && (
                                <p className="mt-1 text-xs text-muted-foreground">{limits}</p>
                            )}
                        </div>
                        <RadioGroupItem value={gateway.key ?? ''} id={gateway.key ?? ''} className="shrink-0" />
                    </label>
                );
            })}
        </RadioGroup>
    );


    if (isMobile) {



        return <MobilePopup opened={open} onBackdropClick={() => setOpen(false)}>
            <MobilePage>
                <MobileNavbar title={Lang.key('select_payment_method')}

                    right={<MobileLink onClick={() => setOpen(false)}><XIcon /></MobileLink>}
                />


                <div className='m-4 space-y-4'>
                    {renderAmountField()}
                    <div className='space-y-2'>
                        <Label className="text-muted-foreground">{Lang.key('select_payment_method')}</Label>
                        {renderGateways()}
                    </div>
                </div>
                <MobileFab
                    onClick={onPayNow}
                    className="fixed left-1/2 bottom-safe-4 transform -translate-x-1/2 z-20"
                    icon={<Check />}
                    text={Lang.key('pay_now')}
                    textPosition="after"
                />

            </MobilePage>
        </MobilePopup>
    }


    return (
        <Dialog
            open={open}
            onOpenChange={setOpen}
        >
            <DialogContent className="gap-0 overflow-hidden p-0 sm:max-w-md">
                <DialogHeader className="gap-3 border-b px-6 py-5">
                    <div className="flex items-start gap-3">
                        <div className="flex size-10 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary">
                            <CreditCard className="size-5" />
                        </div>
                        <div className="space-y-1 text-left">
                            <DialogTitle>{Lang.key('select_payment_method')}</DialogTitle>
                            <DialogDescription>
                                {Lang.key('select_payment_method_description')}
                            </DialogDescription>
                        </div>
                    </div>
                </DialogHeader>

                <div className="space-y-6 px-6 py-5">
                    <div className="rounded-lg border bg-muted/30 p-4">
                        {renderAmountField(true)}
                    </div>

                    <div className="space-y-3">
                        <Label className="text-xs font-medium tracking-wide text-muted-foreground uppercase">
                            {Lang.key('select_payment_method')}
                        </Label>
                        {renderGateways()}
                    </div>
                </div>

                <DialogFooter className="gap-2 border-t bg-muted/20 px-6 py-4 sm:justify-between">
                    <Button onClick={() => setOpen(false)} variant="outline">
                        {Lang.key('close')}
                    </Button>
                    <Button
                        disabled={!selectedGateway || !amount || loading}
                        onClick={onPayNow}
                    >
                        {loading && <Loader2 className="size-4 animate-spin" />}
                        {Lang.key('pay_now')}
                    </Button>
                </DialogFooter>
            </DialogContent>
        </Dialog>
    );
});

export default PaymentDialog;
