import { type FC, useState } from 'react'
import { useFormik } from 'formik'
import * as Yup from 'yup'
import { toast } from 'react-toastify'
import Table from '@/components/Table'
import Filters from '@/components/Filters'
import CategoryForm from './components/CategoryForm'
import CategoryTableColumns from './components/CategoryTableColumns'
import type { Category, CreateCategoryType } from './types/Types'
import type { ErrorType } from '@/helpers/types'
import {
    useGetCategories,
    useCreateCategory,
    useUpdateCategory,
    useDeleteCategory
} from './hooks/useProductData'
import { useSingleUpload } from '../uploader/hooks/useUploaderData'
import { extractErrorMessage } from '@/config/func'

function findCategoryById(cats: Category[], id: string | null): Category | undefined {
    if (!id) return undefined
    for (const c of cats) {
        if (c.id === id) return c
        const found = findCategoryById(c.children || [], id)
        if (found) return found
    }
    return undefined
}

function flattenCategories(cats: Category[]): Category[] {
    const result: Category[] = []
    for (const c of cats) {
        result.push(c)
        if (c.children?.length) {
            result.push(...flattenCategories(c.children))
        }
    }
    return result
}

type CategoryFormValues = {
    title: string
    icon: File[]
    order: number,
    parentId?: string,
}

const CategoryProduct: FC = () => {
    const [isActive, setIsActive] = useState<boolean>(true)
    const [iconFiles, setIconFiles] = useState<File[]>([])
    const [selectedIconUrl, setSelectedIconUrl] = useState<string>('')
    const [editingCategory, setEditingCategory] = useState<Category | null>(null)
    const [filters, setFilters] = useState<{ search?: string | null }>({})

    const { data: categoriesData, isLoading } = useGetCategories()
    const { mutate: createCategory, isPending: isCreating } = useCreateCategory()
    const { mutate: updateCategory, isPending: isUpdating } = useUpdateCategory()
    const { mutate: deleteCategory, isPending: isDeleting } = useDeleteCategory()
    const { mutate: singleUpload, isPending: isUploading } = useSingleUpload()

    const categories = categoriesData?.data || []

    const flattenedCategories = flattenCategories(categories)
    const filteredCategories = flattenedCategories.filter((category) => {
        if (filters.search) {
            return category.title.toLowerCase().includes(filters.search.toLowerCase())
        }
        return true
    })

    const formik = useFormik<CategoryFormValues>({
        initialValues: {
            title: '',
            icon: [],
            order: 0,
            parentId: undefined,
        },
        validationSchema: Yup.object().shape({
            title: Yup.string().required('عنوان دسته‌بندی الزامی است')
        }),
        onSubmit: (values) => {
            const submitCategory = (avatarUrl?: string) => {
                const categoryData: CreateCategoryType = {
                    title: values.title,
                    isActive,
                    avatarUrl: avatarUrl || selectedIconUrl || editingCategory?.avatarUrl || '',
                    order: values.order,
                    parentId: values.parentId || undefined,
                }

                if (editingCategory) {
                    updateCategory(
                        { id: editingCategory.id, params: categoryData },
                        {
                            onSuccess: () => {
                                toast.success('دسته‌بندی با موفقیت به‌روزرسانی شد')
                                resetForm()
                            },
                            onError: (error: ErrorType) => {
                                toast.error(extractErrorMessage(error))
                            }
                        }
                    )
                } else {
                    createCategory(categoryData, {
                        onSuccess: () => {
                            toast.success('دسته‌بندی با موفقیت ایجاد شد')
                            resetForm()
                        },
                        onError: (error: ErrorType) => {
                            toast.error(extractErrorMessage(error))
                        }
                    })
                }
            }

            if (selectedIconUrl) {
                submitCategory(selectedIconUrl)
            } else if (iconFiles.length > 0) {
                singleUpload(iconFiles[0], {
                    onSuccess: (response) => {
                        const avatarUrl = response?.data?.url || ''
                        submitCategory(avatarUrl)
                    },
                    onError: (error: ErrorType) => {
                        toast.error(extractErrorMessage(error, 'خطا در آپلود تصویر'))
                    }
                })
            } else {
                submitCategory()
            }
        }
    })

    const resetForm = () => {
        formik.resetForm()
        setIsActive(true)
        setIconFiles([])
        setSelectedIconUrl('')
        setEditingCategory(null)
    }

    const handleEdit = (category: Category) => {
        formik.setValues({
            title: category.title,
            icon: [],
            order: category.order || 0,
            parentId: category.parent || undefined
        })
        setIsActive(category.isActive)
        setIconFiles([])
        setSelectedIconUrl(category.avatarUrl || '')
        setEditingCategory(category)
    }

    const handleIconUrlChange = (url: string) => {
        setSelectedIconUrl(url)
        setIconFiles([])
        formik.setFieldValue('icon', [])
    }

    const handleIconFileChange = (files: File[]) => {
        setIconFiles(files)
        setSelectedIconUrl('')
    }

    const handleDelete = (id: string) => {
        deleteCategory(id, {
            onSuccess: () => {
                toast.success('دسته‌بندی با موفقیت حذف شد')
            },
            onError: (error: ErrorType) => {
                toast.error(extractErrorMessage(error))
            }
        })
    }

    const handleStatusChange = (id: string, value: boolean) => {
        const category = findCategoryById(categories, id)
        if (category) {
            const categoryData: CreateCategoryType = {
                title: category.title,
                isActive: value,
                avatarUrl: category.avatarUrl,
                order: category.order || 0
            }
            updateCategory(
                { id, params: categoryData },
                {
                    onSuccess: () => {
                        toast.success('وضعیت دسته‌بندی با موفقیت تغییر کرد')
                    },
                    onError: (error: ErrorType) => {
                        toast.error(extractErrorMessage(error))
                    }
                }
            )
        }
    }

    const columns = CategoryTableColumns({
        categories,
        onStatusChange: handleStatusChange,
        onEdit: handleEdit,
        onDelete: handleDelete,
        isDeleting
    })

    return (
        <div className="flex flex-col lg:flex-row gap-4 lg:gap-6 p-4 lg:p-6">
            <div className="flex-1 w-full lg:w-auto">
                <div className="flex items-center justify-between mb-4 lg:mb-6">
                    <h1 className="text-base lg:text-lg font-light">دسته بندی کالا</h1>
                </div>
                <div className="mb-4 lg:mb-0">
                    <Filters
                        fields={[
                            {
                                type: 'input',
                                name: 'search',
                                placeholder: 'جستجو'
                            }
                        ]}
                        onChange={(filters) => setFilters(filters)}
                    />
                </div>

                <div className="overflow-x-auto">
                    <Table
                        columns={columns}
                        data={filteredCategories}
                        isloading={isLoading}
                        selectable
                    />
                </div>
            </div>

            <CategoryForm
                formik={formik}
                isActive={isActive}
                onActiveChange={setIsActive}
                onIconChange={handleIconFileChange}
                iconFiles={iconFiles}
                isSubmitting={isCreating || isUpdating || isUploading}
                isEditing={!!editingCategory}
                onIconUrlChange={handleIconUrlChange}
                selectedIconUrl={selectedIconUrl}
            />
        </div>
    )
}

export default CategoryProduct
