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 { BookStatus, StudyBookRequest } from '@/types/book';
import FilterDrawer from '@/components/book-request/modals/filter';
import { useMutation, useQuery } from '@tanstack/react-query';
import usePagination from '@/hooks/usePagination';
import { Button, Form, Table, Tag, Tooltip } from 'antd';
import { toast } from 'react-toastify';
import { errorMessageFormatter } from '@/utils';
import ConfirmationModal from '@/components/modals/ConfirmationModal';
import React from 'react';
import { getBookRequestListByPagination } from '@/services/data';
import { cancelBookRequest } from '@/services/book';
import HtmlParser from '@/components/HtmlParser';
import { dateTimeTransformer } from '@/utils/timeTransformer';
import { AiOutlineExclamationCircle } from 'react-icons/ai';

const BookPage: NextPage<BasePageProps> = ({ member }) => {
    const { t } = useTranslation(['book-request', 'layout', 'common', 'messages']);
    const [pagination, setPagination, paginationOnChange] = usePagination<StudyBookRequest>();
    const [filterBookRequestForm] = Form.useForm<StudyBookRequest>();

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

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

            const res = await getBookRequestListByPagination(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 cancelBookRequestMutation = useMutation({
        mutationFn: async ({ bookId, requestId }: { bookId: string; requestId: string }) => {
            const res = await cancelBookRequest(bookId, requestId);
            return res.data;
        },
        onSuccess: () => {
            bookRequestQuery.refetch();
        },
    });

    // Functions
    const onResetHandler = () => {
        filterBookRequestForm.resetFields();
        bookRequestQuery.refetch();
    };

    const onCancelRequestHandler = (bookId: string, studyBookRequestId: string) => {
        toast.promise(cancelBookRequestMutation.mutateAsync({ bookId, requestId: studyBookRequestId }), {
            pending: t('messages:cancelling-request'),
            success: t('messages:cancel-request-success'),
            error: t('messages:cancel-request-failed'),
        });
    };

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

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

    const columns = [
        // Name
        {
            dataIndex: 'name',
            title: t('book-name'),
            width: 200,
            render: (_: unknown, studyBookRequest: StudyBookRequest) => {
                return studyBookRequest.book.name;
            },
        },
        // Description
        {
            dataIndex: 'description',
            title: t('description'),
            width: 500,
            render: (_: unknown, studyBookRequest: StudyBookRequest) => {
                return <HtmlParser html={studyBookRequest.book.description} />;
            },
        },
        // Status
        {
            title: t('status'),
            dataIndex: 'status',
            key: 'status',
            width: 130,
            render: (_: unknown, studyBookRequest: StudyBookRequest) => {
                let tagColor, tagText;

                switch (studyBookRequest?.status) {
                    case 'PENDING':
                        tagColor = 'yellow';
                        tagText = t('pending');
                        break;
                    case 'JOINED':
                        tagColor = 'green';
                        tagText = t('joined');
                        break;
                    case 'CANCELLED':
                        tagColor = 'red';
                        tagText = t('cancelled');
                        break;
                    default:
                        tagColor = 'red';
                        tagText = t('rejected');
                }

                return (
                    <div className="flex items-center">
                        <Tag color={tagColor}>{tagText}</Tag>
                        {studyBookRequest?.status === 'REJECTED' && (
                            <Tooltip
                                title={
                                    <div className="flex flex-col gap-1 p-2">
                                        <span className="font-bold">{t('reason-for-rejection')}</span>
                                        <span>{studyBookRequest?.reason}</span>
                                    </div>
                                }
                            >
                                <AiOutlineExclamationCircle className="text-sm md:text-md" />
                            </Tooltip>
                        )}
                    </div>
                );
            },
        },
        // Created At
        {
            title: t('common:created-at'),
            dataIndex: 'createdAt',
            width: 150,
            sorter: true,
            render: (createdAt: string) => {
                return createdAt !== null ? dateTimeTransformer(createdAt) : '';
            },
        },
        // Action
        {
            title: t('actions'),
            dataIndex: 'id',
            width: 100,
            render(_: unknown, studyBookRequest: StudyBookRequest) {
                return studyBookRequest.status !== BookStatus.PENDING ? (
                    '-'
                ) : (
                    <ConfirmationModal
                        title={t('book-application')}
                        message={
                            <Trans
                                i18nKey={'messages:are-you-sure-you-want-to-cancel-request-of-this-book?'}
                                components={{
                                    strong: <strong />,
                                }}
                                values={{
                                    name: member.fullName,
                                }}
                            />
                        }
                        okText={t('cancel-request')}
                        cancelText={t('not-to-cancel')}
                        okButtonProps={{ danger: true }}
                        onOk={() => {
                            onCancelRequestHandler(studyBookRequest.bookId, studyBookRequest.id);
                        }}
                        reason={false}
                        width={400}
                    >
                        <Button type="default" danger loading={cancelBookRequestMutation.isLoading}>
                            {t('cancel-request')}
                        </Button>
                    </ConfirmationModal>
                );
            },
        },
    ];

    return (
        <Layout member={member} breadCrumbItems={breadCrumbItems} activeMenu={['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
                            filterBookRequestForm={filterBookRequestForm}
                            onReset={onResetHandler}
                            onSearch={() => {
                                bookRequestQuery.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={bookRequestQuery.data}
                    loading={bookRequestQuery.isLoading}
                    rowKey={(record) => record.bookId}
                    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>
        </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-request', 'layout', 'common', 'messages', 'api-messages', 'my-profile'])),
            },
        };
    } 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;
