import { type FC, useState, useMemo, useEffect } from 'react'
import { useFormik } from 'formik'
import * as Yup from 'yup'
import { useParams } from 'react-router-dom'
import Input from '@/components/Input'
import Select from '@/components/Select'
import type { ItemsSelectType } from '@/components/Select'
import Textarea from '@/components/Textarea'
import UploadBox from '@/components/UploadBox'
import Button from '@/components/Button'
import { TickCircle } from 'iconsax-react'
import { useGetInvoiceDetail } from '@/pages/invoice/hooks/useInvoiceData'
import { usePayInvoice } from './hooks/usePaymentData'
import { useMultiUpload } from '@/pages/uploader/hooks/useUploader'
import { NumberFormat } from '@/config/func'
import { toast } from '@/shared/toast'
import type { ErrorType } from '@/helpers/types'
import type { PayInvoiceParamsType } from './types/Types'
import { PaymentGatewayEnum, PaymentMethodEnum } from './enum/Enum'
import { useGetMe } from '../user/hooks/useUserData'

const getMethodItems = (userCredit: number): ItemsSelectType[] => [
    { value: PaymentMethodEnum.Online, label: 'آنلاین' },
    { value: PaymentMethodEnum.Cash, label: 'نقد' },
    {
        value: PaymentMethodEnum.Credit,
        label: 'اعتباری',
        disabled: userCredit <= 0,
    },
]

const gatewayItems: ItemsSelectType[] = [
    { value: PaymentGatewayEnum.ZarinPal, label: 'زرین‌پال' },
]

const formatPrice = (num: number) => `${NumberFormat(num)} تومان`

const PayInvoice: FC = () => {

    const { data: user } = useGetMe()
    const { id } = useParams()
    const { data, isPending } = useGetInvoiceDetail(id ?? '')
    const { mutate: payInvoice, isPending: isPaying } = usePayInvoice()
    const multiUpload = useMultiUpload()
    const [attachmentFiles, setAttachmentFiles] = useState<File[]>([])

    const userCredit = user?.maxCredit ?? 0
    const methodItems = useMemo(() => getMethodItems(userCredit), [userCredit])

    const invoice = data?.data

    useEffect(() => {
        if (userCredit <= 0 && formik.values.method === PaymentMethodEnum.Credit) {
            formik.setFieldValue('method', PaymentMethodEnum.Online)
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps -- only run when userCredit is known
    }, [userCredit])

    const formik = useFormik<PayInvoiceParamsType>({
        initialValues: {
            amount: invoice?.balance ?? 0,
            method: PaymentMethodEnum.Online,
            gateway: PaymentGatewayEnum.ZarinPal,
            description: '',
            attachments: [],
        },
        validationSchema: Yup.object({
            amount: Yup.number()
                .required('مبلغ اجباری است')
                .min(1, 'مبلغ باید بیشتر از صفر باشد'),
            method: Yup.string().required('روش پرداخت اجباری است'),
            gateway: Yup.string().when('method', {
                is: PaymentMethodEnum.Online,
                then: (schema) => schema.required('درگاه پرداخت اجباری است'),
            }),
            description: Yup.string(),
            attachments: Yup.array().of(Yup.string()),
        }),
        enableReinitialize: true,
        onSubmit: async (values) => {
            if (!id) return

            let attachments: string[] = values.attachments ?? []

            if (attachmentFiles.length > 0) {
                try {
                    const uploadResult = await multiUpload.mutateAsync(attachmentFiles)
                    attachments = (uploadResult?.data ?? []).map(
                        (item: { url?: string }) => item?.url ?? ''
                    ).filter(Boolean)
                } catch (error) {
                    toast((error as ErrorType)?.response?.data?.error?.message?.[0] ?? 'خطا در آپلود فایل‌ها', 'error')
                    return
                }
            }

            payInvoice(
                {
                    invoiceId: id,
                    params: {
                        ...values,
                        attachments,
                    },
                },
                {
                    onSuccess: (res) => {
                        const paymentUrl = res?.data?.paymentUrl
                        if (paymentUrl) {
                            toast('در حال انتقال به درگاه پرداخت', 'success')
                            window.location.href = paymentUrl
                            return
                        }
                        toast('پرداخت با موفقیت ثبت شد', 'success')
                    },
                    onError: (error: ErrorType) => {
                        toast(
                            error?.response?.data?.error?.message?.[0] ?? 'خطا در ثبت پرداخت',
                            'error'
                        )
                    },
                }
            )
        },
    })

    if (isPending && !invoice) {
        return (
            <div className="mt-4 text-sm flex items-center justify-center min-h-[200px]">
                <span className="text-[#8C90A3]">در حال بارگذاری...</span>
            </div>
        )
    }

    if (!id || !invoice) {
        return (
            <div className="mt-4 text-sm flex items-center justify-center min-h-[200px]">
                <span className="text-[#8C90A3]">صورت حساب یافت نشد</span>
            </div>
        )
    }

    return (
        <div className="mt-4 text-sm">
            <div className="text-sm mb-6">پرداخت صورت حساب</div>

            {/* خلاصه صورت حساب */}
            <div className="bg-white rounded-2xl p-8 mb-6">
                <div className="text-sm mb-4">اطلاعات صورت حساب</div>
                <div className="flex flex-wrap gap-x-12 gap-y-3 text-xs">
                    <div className="flex gap-1.5">
                        <span className="text-[#8C90A3]">شماره صورت حساب:</span>
                        <span className="text-black">{invoice.invoiceNumber}</span>
                    </div>
                    <div className="flex gap-1.5">
                        <span className="text-[#8C90A3]">مبلغ کل:</span>
                        <span className="text-black">{formatPrice(invoice.total)}</span>
                    </div>
                    <div className="flex gap-1.5">
                        <span className="text-[#8C90A3]">پرداخت شده:</span>
                        <span className="text-black">{formatPrice(invoice.paidAmount)}</span>
                    </div>
                    <div className="flex gap-1.5">
                        <span className="text-[#8C90A3]">مانده:</span>
                        <span className="text-black font-medium">{formatPrice(invoice.balance)}</span>
                    </div>
                    <div className="flex gap-1.5">
                        <span className="text-[#8C90A3]">اعتبار:</span>
                        <span className="text-black">{formatPrice(userCredit)}</span>
                    </div>
                </div>
            </div>

            {/* فرم پرداخت */}
            <div className="bg-white rounded-2xl p-8">
                <div className="text-sm mb-6">ثبت پرداخت</div>

                <form onSubmit={formik.handleSubmit} className="flex flex-col gap-6">
                    <Input
                        label="مبلغ (تومان)"
                        placeholder="مبلغ را وارد کنید"
                        name="amount"
                        value={formik.values.amount ?? ''}
                        onChange={(e) =>
                            formik.setFieldValue(
                                'amount',
                                Number((e.target.value ?? '').replace(/,/g, '')) || 0
                            )
                        }
                        onBlur={formik.handleBlur}
                        seprator
                        error_text={
                            formik.touched.amount && formik.errors.amount
                                ? formik.errors.amount
                                : ''
                        }
                    />

                    <Select
                        label="روش پرداخت"
                        placeholder="انتخاب کنید"
                        items={methodItems}
                        name="method"
                        value={formik.values.method}
                        onChange={formik.handleChange}
                        onBlur={formik.handleBlur}
                        error_text={
                            formik.touched.method && formik.errors.method
                                ? formik.errors.method
                                : ''
                        }
                    />

                    {formik.values.method === PaymentMethodEnum.Online && (
                        <Select
                            label="درگاه پرداخت"
                            placeholder="انتخاب کنید"
                            items={gatewayItems}
                            name="gateway"
                            value={formik.values.gateway}
                            onChange={formik.handleChange}
                            onBlur={formik.handleBlur}
                            error_text={
                                formik.touched.gateway && formik.errors.gateway
                                    ? formik.errors.gateway
                                    : ''
                            }
                        />
                    )}

                    {formik.values.method !== PaymentMethodEnum.Online && (
                        <>
                            <Textarea
                                label="توضیحات (اختیاری)"
                                placeholder="توضیحات پرداخت"
                                {...formik.getFieldProps('description')}
                                error_text={
                                    formik.touched.description && formik.errors.description
                                        ? formik.errors.description
                                        : ''
                                }
                            />

                            <UploadBox
                                label="پیوست‌ها (اختیاری)"
                                isMultiple
                                onChange={setAttachmentFiles}
                            />
                        </>
                    )}

                    <div className="flex justify-end pt-2">
                        <Button
                            type="submit"
                            isLoading={isPaying || multiUpload.isPending}
                        >
                            <div className="flex items-center gap-2">
                                <TickCircle size={20} color="black" />
                                <span>ثبت پرداخت</span>
                            </div>
                        </Button>
                    </div>
                </form>
            </div>
        </div>
    )
}

export default PayInvoice
