import React, { useEffect, useState, useCallback, useRef } from 'react'
import { connect, useDispatch } from 'react-redux'
import {
    Card,
    Table,
    Space,
    Modal,
    Col,
    Row,
    Select,
    Drawer,
    Tooltip,
} from 'antd'
import commonStyles from '../../../Utils/Common.less'
import type { ColumnsType, TableProps } from 'antd/es/table'
import {
    type PerformInvoiceProps,
    type InvoiceListDataTypeInterface,
    type DataCHAT,
    type PerformStateInterface,
} from '../../../Types/Invoicing/Invoice'
import SearchInput from '../../../Components/SearchInput'
import ToBeRaisedComponent from './DropDownList/ToBeRaised'
import PaidByBankComponent from './DropDownList/PaidByBank'
import DDComponent from './DropDownList/DD'
import NoNeedComponent from './DropDownList/NoNeed'
import PaidByCashComponent from './DropDownList/PaidByCash'
import StaffCommunication from '../../../Components/StaffChat'
import { CommentOutlined } from '@ant-design/icons'
import { GetChat } from '../../../Services/Common'
import calculatePagination from '../../../Utils/Pagination'
import { GetPerformInvoice } from '../../../Services/Invoicing/Invoice'

const PerformInvoice = (props: PerformInvoiceProps): React.ReactElement => {
    const dispatch = useDispatch()
    const {
        PerformInvoice,
        selectedCategoryId,
        selectedServiceId,
        PerformInvoiceCount,
    } = props
    const [ToBeRaised, setToBeRaised] = useState<boolean>(false)
    const [DD, setDD] = useState<boolean>(false)
    const [PaidByBank, setPaidByBank] = useState<boolean>(false)
    const [NoNeed, setNoNeed] = useState<boolean>(false)
    const [PaidByCash, setPaidByCash] = useState<boolean>(false)
    const [selectedDropdownValue, setSelectedDropdownValue] = useState<
        number | null
    >(null)
    const [dropdownClicked, setDropdownClicked] = useState<boolean>(false)
    const [selectedRecord, setSelectedRecord] = useState<any>(null)
    const [ChatDatas, setChatData] = useState<DataCHAT | null>(null)
    const [open, setOpen] = useState<boolean>(false)
    const [serviceProcessId, setprospectChat] = useState<number>(0)
    const [searchString, setSearchString] = useState('=NA=')
    const [currentPage, setCurrentPage] = useState(1)
    const [itemsPerPage, setItemsPerPage] = useState(10)
    const hasFetchedOnce = useRef(false)
    const hasFetchedOnce2 = useRef(false)
    const getTableData = useCallback(() => {
        GetPerformInvoice(
            dispatch,
            searchString,
            1,
            selectedCategoryId,
            selectedServiceId,
            currentPage,
            itemsPerPage
        )
    }, [
        searchString,
        currentPage,
        itemsPerPage,
        selectedCategoryId,
        selectedServiceId,
    ])

    useEffect(() => {
        if (!hasFetchedOnce2.current) {
            hasFetchedOnce2.current = true
            return
        }
        void GetChat(
            dispatch,
            3,
            serviceProcessId,
            0,
            (chatdatass: DataCHAT) => {
                setChatData(chatdatass)
            }
        )
    }, [serviceProcessId])

    const showDrawer = (id: number): void => {
        setprospectChat(id)
        setOpen(true)
    }

    const onClose = (): void => {
        setOpen(false)
    }

    useEffect(() => {
        if (!hasFetchedOnce.current) {
            hasFetchedOnce.current = true
            return
        }
        getTableData()
    }, [getTableData])

    const onTableChange = (): void => {
        setTimeout(() => {
            getTableData()
            handleModalClose()
        }, 3000)
    }
    const renderSelectedComponent = (): JSX.Element | null => {
        switch (selectedDropdownValue) {
            case 1:
                return (
                    <ToBeRaisedComponent
                        record={selectedRecord}
                        onTableChange={onTableChange}
                    />
                )
            case 2:
                return (
                    <DDComponent
                        record={selectedRecord}
                        onTableChange={onTableChange}
                    />
                )
            case 3:
                return (
                    <NoNeedComponent
                        record={selectedRecord}
                        onTableChange={onTableChange}
                    />
                )
            case 4:
                return (
                    <PaidByCashComponent
                        record={selectedRecord}
                        onTableChange={onTableChange}
                    />
                )
            case 5:
                return (
                    <PaidByBankComponent
                        record={selectedRecord}
                        onTableChange={onTableChange}
                    />
                )
            default:
                return null
        }
    }

    const onChangeSelect = (value: number, record: any): void => {
        setSelectedDropdownValue(value)
        setDropdownClicked(true)
        setSelectedRecord(record)
        switch (value) {
            case 1:
                setToBeRaised(true)
                break
            case 2:
                setDD(true)
                break
            case 3:
                setNoNeed(true)
                break
            case 4:
                setPaidByCash(true)
                break
            case 5:
                setPaidByBank(true)
                break
        }
        renderSelectedComponent()
    }

    const formatDate = (dateString: string): string => {
        const date = new Date(dateString)
        return date.toLocaleDateString()
    }

    const handlePageChange = (pageNo: number, pageSize: number): void => {
        window.scrollTo(0, 0)
        setCurrentPage(pageNo)
        setItemsPerPage(pageSize)
    }
    const handlePageSizeChange = (pageSize: number): void => {
        setItemsPerPage(pageSize)
        setCurrentPage(1) // Reset to first page when page size changes
    }

    const pagination = calculatePagination(
        currentPage,
        PerformInvoiceCount,
        itemsPerPage,
        handlePageSizeChange
    )
    const columns: ColumnsType<InvoiceListDataTypeInterface> = [
        {
            title: 'Number',
            dataIndex: 'clientNumber',
        },
        {
            title: 'Client',
            dataIndex: 'referenceName',
        },
        {
            title: 'Period',
            dataIndex: 'periodStartDates',
            render: (_, record) => (
                <span>
                    Period Of {formatDate(record.periodStartDate)} to{' '}
                    {formatDate(record.periodEndDate)}
                </span>
            ),
        },
        {
            title: 'Services',
            dataIndex: 'serviceName',
        },
        {
            title: '',
            dataIndex: 'accInvoiceTypeList',
            render: (_, record: any) => {
                const options = record.accInvoiceTypeList?.map((item: any) => ({
                    label: item.description,
                    value: item.invoicePaymentTypeId,
                }))

                return (
                    <Select
                        showSearch
                        allowClear
                        placeholder="Please select"
                        onChange={(value) => {
                            onChangeSelect(value, record)
                        }}
                        filterOption={(input, option) =>
                            !(option == null) &&
                            option.label
                                .toLowerCase()
                                .includes(input.toLowerCase())
                        }
                        options={[
                            { label: 'Please select', value: null },
                            ...options,
                        ]}
                        value={
                            dropdownClicked ? selectedDropdownValue : undefined
                        }
                    />
                )
            },
        },
        {
            title: 'Action',
            key: 'action',
            render: (_, record: any) => {
                return (
                    <Space size="middle">
                        <Tooltip title="Staff Communication">
                            <CommentOutlined
                                onClick={() => {
                                    showDrawer(record?.serviceProcessId)
                                }}
                                className={commonStyles.clickableIcon}
                            />
                        </Tooltip>
                    </Space>
                )
            },
        },
    ]

    const onChangeTableParams: TableProps<InvoiceListDataTypeInterface>['onChange'] =
        (pagination, filters, sorter: any, extra) => {
            handlePageChange(pagination.current ?? 1, pagination.pageSize ?? 10)
        }

    const onChangeText = (data: React.ChangeEvent<HTMLInputElement>): void => {
        onChangeFilter(data.target.value)
    }

    const onChangeFilter = (data: string): void => {
        if (data?.length !== 0) {
            setSearchString(data)
        } else {
            setSearchString('=NA=')
        }
    }

    const handleModalClose = (): void => {
        setToBeRaised(false)
        setDD(false)
        setPaidByBank(false)
        setNoNeed(false)
        setPaidByCash(false)
        setSelectedDropdownValue(null)
    }

    const [showMessage, setShowMessage] = useState(false)

    useEffect(() => {
        const timer = setTimeout(() => {
            setShowMessage(true)
        }, 5000)

        // Clear the timer if the component unmounts
        return () => {
            clearTimeout(timer)
        }
    }, [])
    return (
        <Card className={commonStyles.card}>
            <Row gutter={16} align="middle">
                <div className={commonStyles.corpList}>
                    <Col span={16}>
                        <SearchInput
                            placeHolder={'Search CompanyName by keywords'}
                            onSearch={onChangeFilter}
                            onChange={onChangeText}
                            width="478"
                        />
                    </Col>
                </div>
            </Row>
            <div className={commonStyles.table}>
                {PerformInvoice?.length > 0 ? (
                    <Table
                        columns={columns}
                        dataSource={PerformInvoice}
                        onChange={onChangeTableParams}
                        pagination={pagination}
                    />
                ) : (
                    <div>
                        {showMessage ? (
                            <h4>No matching data available</h4>
                        ) : (
                            <h4>Loading data...</h4>
                        )}
                    </div>
                )}
            </div>
            <Modal
                title="Create Invoice"
                open={ToBeRaised}
                onCancel={() => {
                    setToBeRaised(false)
                    handleModalClose()
                }}
                footer={null}
                width={'30%'}
            >
                <ToBeRaisedComponent
                    record={selectedRecord}
                    onTableChange={onTableChange}
                />
            </Modal>
            <Modal
                title="Status Update"
                open={DD}
                onCancel={() => {
                    setDD(false)
                    handleModalClose()
                }}
                footer={null}
                width={'30%'}
            >
                <DDComponent
                    record={selectedRecord}
                    onTableChange={onTableChange}
                />
            </Modal>
            <Modal
                title="Status Update"
                open={PaidByBank}
                onCancel={() => {
                    setPaidByBank(false)
                    handleModalClose()
                }}
                footer={null}
                width={'30%'}
            >
                <PaidByBankComponent
                    record={selectedRecord}
                    onTableChange={onTableChange}
                />
            </Modal>
            <Modal
                title="Status Update"
                open={NoNeed}
                onCancel={() => {
                    setNoNeed(false)
                    handleModalClose()
                }}
                footer={null}
                width={'30%'}
            >
                <NoNeedComponent
                    record={selectedRecord}
                    onTableChange={onTableChange}
                />
            </Modal>
            <Modal
                title="Status Update"
                open={PaidByCash}
                onCancel={() => {
                    setPaidByCash(false)
                    handleModalClose()
                }}
                footer={null}
                width={'30%'}
            >
                <PaidByCashComponent
                    record={selectedRecord}
                    onTableChange={onTableChange}
                />
            </Modal>

            <Drawer
                title={ChatDatas?.clientName}
                width={550}
                onClose={onClose}
                open={open}
            >
                <StaffCommunication
                    refernceId={serviceProcessId}
                    messageTypeId={3}
                    businessId={0}
                />
            </Drawer>
        </Card>
    )
}

const mapStateToProps = (state: any): PerformStateInterface => {
    return {
        PerformInvoice: state.invoice.PerformInvoice,
        PerformInvoiceCount: state.invoice.PerformInvoiceCount,
    }
}

export default connect(mapStateToProps)(PerformInvoice)
