import { GetServerSideProps, NextPage } from 'next';
import { Trans, useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import Layout from '@/components/layouts';
import { AxiosErrorResponse, BasePageProps } from '@/types';
import { authentication } from '@/utils/authentication';
import localeLinkGenerator from '@/utils/localeLinkGenerator';
import { Book } from '@/types/book';
import FilterDrawer from '@/components/book/modals/filter';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import usePagination from '@/hooks/usePagination';
import { Button, Form, Table } from 'antd';
import { toast } from 'react-toastify';
import { errorMessageFormatter } from '@/utils';
import { getBookListByPagination, updateBookRequestStatus } from '@/services/book';
import ConfirmationModal from '@/components/modals/ConfirmationModal';
import React from 'react';
import AddBookOrderModal from '@/components/book-order/modals/AddBookOrderModal';
import ImageDrawer from '@/components/book/modals/ImageDrawer';
import { ColumnsType } from 'antd/es/table';
import HtmlParser from '@/components/HtmlParser';

const BookPage: NextPage<BasePageProps> = ({ member }) => {
    const { t } = useTranslation(['book', 'layout', 'common', 'messages']);
    const [pagination, setPagination, paginationOnChange] = usePagination<Book>();
    const [filterBookForm] = Form.useForm<Book>();
    const [isOrderBookModalOpen, setIsOrderBookModalOpen] = React.useState(false);
    const [book, setBook] = React.useState<Book | null>(null);
    const queryClient = useQueryClient();
    const [isImageDrawerOpen, setIsImageDrawerOpen] = React.useState(false);
    const [bookData, setBookData] = React.useState<Book>();

    // Query
    const bookQuery = useQuery({
        queryKey: ['book', 'pagination', pagination],
        queryFn: async () => {
            // Get the form values
            let searchedValue = filterBookForm.getFieldsValue();

            const query = {
                ...searchedValue,
                page: pagination.page,
                pageSize: pagination.pageSize,
                sortField: pagination.sortField,
                sortOrder: pagination.sortOrder,
            };

            const res = await getBookListByPagination(query);

            setPagination((prevValue) => {
                return {
                    ...prevValue,
                    page: res.data.page,
                    total: res.data.total,
                };
            });

            return res.data.rows;
        },
        onError: (error: AxiosErrorResponse & Error) => {
            toast.error(t(errorMessageFormatter(error)));
        },
    });

    //Mutations
    const updateBookRequestStatusMutation = useMutation({
        mutationFn: async (bookId: string) => {
            const res = await updateBookRequestStatus(bookId);
            return res.data;
        },
        onSuccess: () => {
            bookQuery.refetch();
            queryClient.invalidateQueries(['member']);
        },
    });

    // Functions
    const onResetHandler = () => {
        filterBookForm.resetFields();
        bookQuery.refetch();
    };

    const onBookRequestStatusHandler = async (bookId: string) => {
        toast.promise(updateBookRequestStatusMutation.mutateAsync(bookId), {
            pending: t('messages:requesting-book'),
            success: t('messages:book-requested'),
            error: {
                render({ data }: any) {
                    return t(errorMessageFormatter(data));
                },
            },
        });
    };

    // Data
    const breadCrumbItems = [
        {
            label: t('book-study-group-request'),
            path: '/',
        },
    ];

    const seoConfig = {
        title: t('book-study-group-request'),
    };

    const columns: ColumnsType<Book> = [
        // Name
        {
            dataIndex: 'name',
            title: t('book-name'),
        },
        {
            title: t('description'),
            dataIndex: 'description',
            key: 'description',
            render: (description: string) => <HtmlParser html={description ?? '-'} />,
        },
        {
            title: t('actions'),
            dataIndex: 'id',
            width: 100,
            render(_: unknown, book: Book) {
                return (
                    <div className="flex flex-row gap-2">
                        <ConfirmationModal
                            title={t('book-application')}
                            message={
                                <Trans
                                    i18nKey={'messages:are-you-sure-you-want-to-request-for-this-book?'}
                                    components={{
                                        strong: <strong />,
                                    }}
                                    values={{
                                        name: member.fullName,
                                    }}
                                />
                            }
                            okText={t('request')}
                            onOk={() => {
                                onBookRequestStatusHandler(book.id);
                            }}
                            reason={false}
                            width={400}
                        >
                            <Button type="primary" loading={updateBookRequestStatusMutation.isLoading}>
                                {t('request-to-join-study-group')}
                            </Button>
                        </ConfirmationModal>
                    </div>
                );
            },
        },
    ];

    return (
        <Layout member={member} breadCrumbItems={breadCrumbItems} activeMenu={['book-study-group-request']} seoConfig={seoConfig} withBackground>
            <div className="flex justify-between mb-4">
                {/* Header */}
                <div className="flex">
                    {/* Filter Drawer */}
                    <div className="w-1/2">
                        <FilterDrawer
                            filterBookForm={filterBookForm}
                            onReset={onResetHandler}
                            onSearch={() => {
                                bookQuery.refetch();
                            }}
                            loading={false}
                        />
                    </div>
                    {/* Reset Filter Button */}
                    <div className="w-1/3">
                        <Button type="link" className="list-none" onClick={onResetHandler}>
                            {t('common:reset-filter')}
                        </Button>
                    </div>
                </div>
            </div>
            <div className="table_container">
                {/* Table */}
                <Table
                    columns={columns}
                    dataSource={bookQuery.data}
                    loading={bookQuery.isLoading}
                    rowKey={(record) => record.id}
                    scroll={{ x: 1000 }}
                    onChange={paginationOnChange}
                    pagination={{
                        current: pagination.page,
                        pageSize: pagination.pageSize,
                        defaultPageSize: 1,
                        showSizeChanger: true,
                        pageSizeOptions: [10, 25, 50, 100],
                        showTotal: (total, range) =>
                            t('common:pagination', {
                                range0: range[0],
                                range1: range[1],
                                total: total,
                            }),
                        total: pagination.total,
                    }}
                />
            </div>
            <AddBookOrderModal book={book as Book} open={isOrderBookModalOpen} setOpen={setIsOrderBookModalOpen} />
            <ImageDrawer open={isImageDrawerOpen} setOpen={setIsImageDrawerOpen} bookData={bookData!} />
        </Layout>
    );
};

export const getServerSideProps: GetServerSideProps = async ({ locale, req, resolvedUrl }) => {
    try {
        const authResponse = await authentication(req);

        return {
            props: {
                member: authResponse,
                ...(await serverSideTranslations(locale as string, [
                    'book',
                    'book-request',
                    'layout',
                    'common',
                    'messages',
                    'api-messages',
                    'my-profile',
                    'book-order',
                ])),
            },
        };
    } catch (error: any) {
        if (error.response?.data?.unauthorized) {
            return {
                redirect: {
                    destination: localeLinkGenerator(locale, `/unauthorized`),
                    permanent: false,
                },
            };
        }

        return {
            redirect: {
                destination: localeLinkGenerator(locale, `/?redirect=/${resolvedUrl}`),
                permanent: false,
            },
        };
    }
};

export default BookPage;
