/* eslint-disable @typescript-eslint/strict-boolean-expressions */
import React, { useEffect, useRef, useState } from 'react'
import {
    Col,
    Row,
    Form,
    Button,
    Card,
    Tooltip,
    Space,
    DatePicker,
    type DatePickerProps,
    Select,
    Table,
} from 'antd'
import { connect, useDispatch } from 'react-redux'
import { CloudDownloadOutlined, EyeOutlined } from '@ant-design/icons'
import commonStyles from '../../../../Utils/Common.less'

import 'jspdf-autotable'
import dayjs from 'dayjs'
import {
    type TimesheetReportsData,
    type TimesheetReportInterface,
} from '../../../../Types/Hr/Reports'
import { GetUserList } from '../../../../Services/User'
import hederimage from '../../../../Assest/Svg/pattern-2.svg'
import { GetTimesheetStatusReportData } from '../../../../Services/HR/LeavePermission'
import jsPDF from 'jspdf'
import { type ColumnsType } from 'antd/es/table'
import { ConvertTime, formatdate } from '../../../../Utils/dateFormat'
const TimesheetReport = (
    props: TimesheetReportInterface
): React.ReactElement => {
    const { userList } = props
    const dispatch = useDispatch()
    const [form] = Form.useForm()
    const [selectedConsiderId, setSelectedLabelManager] = useState(0)
    const [selectedInvoiceDate3, setSelectedInvoiceDate3] = useState<string>('')
    const [selectedDueDate3, setSelectedDueDate3] = useState<string>('')
    const [previewData, setPreviewData] = useState<any[]>([])
    const [showTable, setShowTable] = useState<boolean>(false)
    const hasFetchedOnce = useRef(false)
    const [showMessage, setShowMessage] = useState(false)
    const getGroupedData = (data: any[]): any[] => {
        const grouped: Record<string, { totalHours: number; items: any[] }> = {}

        data.forEach((row) => {
            if (!grouped[row.date]) {
                grouped[row.date] = { totalHours: 0, items: [] }
            }
            grouped[row.date].totalHours += row.workedHours
            grouped[row.date].items.push(row)
        })

        return Object.keys(grouped).flatMap((date, index) => {
            const rows = grouped[date].items
            return rows.map((row, idx) => ({
                ...row,
                totalHours: idx === 0 ? grouped[date].totalHours : null, // Total hours only in the first row
                dateRowSpan: idx === 0 ? rows.length : 0, // Merge rows for the date
            }))
        })
    }

    const processedData = getGroupedData(previewData)
    const columns: ColumnsType<any> = [
        {
            title: 'Date',
            dataIndex: 'date',
            key: 'date',
            width: 100,
            render: (value: string, row: any) => ({
                children: value,
                props: { rowSpan: row.dateRowSpan }, // Set rowSpan for merged cells
            }),
        },
        {
            title: 'Name',
            dataIndex: 'employeeName',
            key: 'employeeName',
        },
        {
            title: 'Description',
            dataIndex: 'description',
            key: 'description',
        },
        { title: 'Status', dataIndex: 'status', key: 'status' },
        {
            title: 'Worked Hours',

            key: 'workedHours',
            render: (record) => {
                return <div>{ConvertTime(record.workedHours)}</div>
            },
        },
        {
            // title: 'Total Hours',
            // key: 'totalHours',
            width: 70,
            title: 'Total Hours',
            dataIndex: 'totalHours',
            render: (value: number, row: any) => ({
                children: ConvertTime(value) ?? null,
                props: {
                    colSpan: value !== null ? 2 : 0,
                    rowSpan: row.dateRowSpan,
                }, // Merge columns for total hours
            }),
            align: 'center',
            // render: (record) => {
            //     return <div>{ConvertTime(record.totalHours)}</div>
            // },
        },
    ]
    const customizeRequiredMark = (
        label: React.ReactNode,
        { required }: { required: boolean }
    ): React.ReactElement => (
        <>
            {label}
            &nbsp;
            {required && <span className={commonStyles.requireIcon}>*</span>}
        </>
    )
    useEffect(() => {
        if (!hasFetchedOnce.current) {
            hasFetchedOnce.current = true
            return
        }
        GetUserList(dispatch)
    }, [])

    // const onChangeInvoiceDate2 = (date: DatePickerProps['value']): void => {
    //     if (date) {
    //         form.setFieldsValue({ fromDate: date })
    //         setSelectedInvoiceDate3(date.format('DD-MM-YYYY'))
    //     }
    // }

    const onChangeInvoiceDate2 = (
        date: DatePickerProps['value'],
        dateString: string | string[]
    ): void => {
        if (date !== null && date !== undefined) {
            const isoDate = date.toISOString()
            setSelectedInvoiceDate3(isoDate)
        } else {
            setSelectedInvoiceDate3('')
        }
    }
    const onChangeDue2 = (
        date: DatePickerProps['value'],
        dateString: string | string[]
    ): void => {
        if (date !== null && date !== undefined) {
            const isoDate = date.toISOString()
            setSelectedDueDate3(isoDate)
        } else {
            setSelectedDueDate3('')
        }
    }

    useEffect(() => {
        form.setFieldValue('toDate', selectedDueDate3)
        form.setFieldValue('fromDate', selectedInvoiceDate3)
    }, [selectedDueDate3, selectedInvoiceDate3])

    const disabledToDate = (current: dayjs.Dayjs): boolean => {
        const fromDate = form.getFieldValue('fromDate')
        return fromDate
            ? current && current.isBefore(dayjs(fromDate), 'day')
            : false
    }
    const handleSelectChangeuser = (value: number): void => {
        setSelectedLabelManager(value)
    }
    const getData = async (): Promise<void> => {
        try {
            await form.validateFields()
            const formattedFromDate = selectedInvoiceDate3
                ? dayjs(selectedInvoiceDate3).format('DD-MM-YYYY')
                : ''
            const formattedToDate = selectedDueDate3
                ? dayjs(selectedDueDate3).format('DD-MM-YYYY')
                : ''

            if (selectedConsiderId !== undefined) {
                const reportData: TimesheetReportsData =
                    await GetTimesheetStatusReportData(
                        dispatch,
                        selectedConsiderId,
                        3,
                        formattedFromDate || '',
                        formattedToDate || ''
                    )
                if (
                    reportData?.employeeWorkedHour !== null &&
                    reportData?.employeeWorkedHour !== undefined &&
                    reportData?.employeeWorkedHour.length > 0
                ) {
                    generatePDF(reportData)
                }
            }
        } catch (error) {
            console.error(error)
        }
    }
    const getCompanyGroupLabel = (id: number): string => {
        if (id === 0) return 'All'
        const group = userList.find((item) => item.value === id)
        return group != null ? group.label : id.toString()
    }
    const generatePDF = (data: any): void => {
        // eslint-disable-next-line new-cap
        const doc = new jsPDF()

        const headerColor: [number, number, number] = [0, 51, 153]
        doc.setTextColor(headerColor[0], headerColor[1], headerColor[2])
        const headerFontSize = 18
        const subHeaderFontSize = 20
        const addressFontSize = 10
        const img = new Image()
        img.src = hederimage

        img.onload = function () {
            const canvas = document.createElement('canvas')
            canvas.width = img.width
            canvas.height = img.height
            const ctx = canvas.getContext('2d')
            ctx?.drawImage(img, 0, 0, img.width, img.height)
            const dataUrl = canvas.toDataURL('image/png')
            const logo = data?.businessDocumentTemplate?.companyLogo
            const marginTop = 5
            const marginLeftRight = 10
            const imageWidth =
                doc.internal.pageSize.getWidth() - 2 * marginLeftRight

            doc.addImage(
                dataUrl,
                'PNG',
                marginLeftRight,
                marginTop,
                imageWidth,
                5
            )

            const logoWidth = 50
            const logoHeight = 10
            const logoXPosition =
                doc.internal.pageSize.getWidth() - logoWidth - 10
            const logoYPosition = marginTop + 10

            if (logo) {
                doc.addImage(
                    logo,
                    'PNG',
                    logoXPosition,
                    logoYPosition,
                    logoWidth,
                    logoHeight
                )
            }

            const textXPosition = 14
            const textYPosition = logoYPosition + marginTop

            doc.setFontSize(headerFontSize)
            doc.setTextColor(0, 51, 153)
            doc.text('IYKONS LIMITED', textXPosition, textYPosition)

            const addressYPosition = textYPosition + 5
            doc.setFontSize(addressFontSize)
            doc.setTextColor(160, 160, 160)
            doc.text(
                '14 Elm Road, Chessington, KT9 1AW, UNITED KINGDOM',
                textXPosition,
                addressYPosition
            )

            const subHeaderYPosition = addressYPosition + 10
            doc.setFontSize(subHeaderFontSize)
            doc.setTextColor(0, 51, 153)
            doc.text('Timesheet Report', textXPosition, subHeaderYPosition)

            const lineStartX =
                textXPosition + doc.getTextWidth('Timesheet Report') + 5
            const lineEndX = lineStartX + 80
            const lineY = subHeaderYPosition
            doc.setDrawColor(0, 51, 153)
            doc.setLineWidth(1)
            doc.line(lineStartX, lineY, lineEndX, lineY)

            const missingCompanyCategoryLabel =
                getCompanyGroupLabel(selectedConsiderId)
            doc.setFontSize(addressFontSize)
            doc.setTextColor(0, 0, 0)
            const dateRangeYPosition = lineY + 10
            const dateRangeText = `Name: ${missingCompanyCategoryLabel} `
            doc.text(dateRangeText, textXPosition, dateRangeYPosition)

            const headers = [
                [
                    'SNo',
                    'Date',
                    'Description',
                    'Status',
                    'Worked Hours',
                    'Total Hours',
                ],
            ]

            const tableData = data?.employeeWorkedHour?.map(
                (item: any, index: number) => [
                    (index + 1).toString(),
                    formatdate(item.date),
                    item.description,
                    item.approveStatus,
                    ConvertTime(item.workedHours),
                    ConvertTime(item.totalHours),
                ]
            )
            const columnWidths = [10, 20, 90, 20, 20, 20]
            doc.autoTable({
                head: headers,
                body: tableData,
                startY: textYPosition + 30,
                theme: 'grid',
                styles: {
                    align: 'justify',
                    fontSize: 8,
                },
                headStyles: {
                    fillColor: [255, 255, 255],
                    textColor: [0, 0, 0],
                    lineColor: [160, 160, 160],
                    lineWidth: 0.05,
                },
                tableWidth: 'auto',
                columnStyles: {
                    0: { cellWidth: columnWidths[0] },
                    1: { cellWidth: columnWidths[1] },
                    2: { cellWidth: columnWidths[2] },
                    3: { cellWidth: columnWidths[3] },
                    4: { cellWidth: columnWidths[4], fontStyle: 'bold' },
                    5: { cellWidth: columnWidths[5], fontStyle: 'bold' },
                },
            })

            // Footer
            const today = new Date()
            const formattedDate = `${
                today.getMonth() + 1
            }/${today.getDate()}/${today.getFullYear()}`
            const totalPages = doc.getNumberOfPages()

            for (let i = 1; i <= totalPages; i++) {
                doc.setPage(i)
                doc.setFontSize(10)

                const footerText = `Printed on: ${formattedDate} ${i}/${totalPages} Total Count: ${tableData?.length}`
                const textWidth = doc.getTextWidth(footerText)
                const pageWidth = doc.internal.pageSize.getWidth()
                const xPosition = (pageWidth - textWidth) / 2
                const yPosition = doc.internal.pageSize.getHeight() - 10

                doc.text(footerText, xPosition, yPosition)
            }

            doc.save('Timesheet_report.pdf')
        }

        img.onerror = function () {
            console.error('Image loading failed')
        }
    }
    const [datafetch, setDataFetch] = useState(false)
    useEffect(() => {
        const handlePreviewData = async (): Promise<void> => {
            try {
                if (datafetch && selectedConsiderId !== undefined) {
                    await form.validateFields()
                    const formattedFromDate = selectedInvoiceDate3
                        ? dayjs(selectedInvoiceDate3).format('DD-MM-YYYY')
                        : ''
                    const formattedToDate = selectedDueDate3
                        ? dayjs(selectedDueDate3).format('DD-MM-YYYY')
                        : ''

                    const reportData = await GetTimesheetStatusReportData(
                        dispatch,
                        selectedConsiderId,
                        3,
                        formattedFromDate || '',
                        formattedToDate || ''
                    )

                    if (reportData?.employeeWorkedHour) {
                        setPreviewData(
                            reportData.employeeWorkedHour.map(
                                (item: any, index: number) => ({
                                    key: index.toString(),
                                    sno: (index + 1).toString(),
                                    date: dayjs(item.date).format('DD-MM-YYYY'),
                                    description: item.description,
                                    status: item.approveStatus,
                                    workedHours: item.workedHours,
                                    totalHours: item.totalHours,
                                    employeeName: item.employeeName,
                                })
                            )
                        )
                    }
                }
            } catch (error) {
                console.error(error)
            }
        }
        void handlePreviewData()
        setShowMessage(false)
        const timer = setTimeout(() => {
            setShowMessage(true)
        }, 3000)
        // Clear the timer if the component unmounts
        return () => {
            clearTimeout(timer)
        }
    }, [selectedConsiderId, datafetch])

    const handlePreview = (): void => {
        setDataFetch(true)
        setShowTable(true)
    }
    useEffect(() => {
        if (
            selectedConsiderId === 0 ||
            selectedConsiderId === undefined ||
            selectedDueDate3 === undefined ||
            selectedDueDate3 === '' ||
            selectedInvoiceDate3 === ''
        ) {
            setShowTable(false)
            setPreviewData([])
        }
    }, [selectedConsiderId, selectedDueDate3, selectedInvoiceDate3])

    return (
        <>
            <Card title="Reports" style={{ marginTop: '20px' }}>
                <div className={commonStyles.formWrapper}>
                    <Form
                        name="complex-form"
                        labelCol={{ span: 24 }}
                        wrapperCol={{ span: 24 }}
                        initialValues={{ remember: true }}
                        layout={'vertical'}
                        autoComplete="off"
                        form={form}
                        requiredMark={customizeRequiredMark}
                    >
                        <Row gutter={24}>
                            <Col span={8}>
                                <Form.Item
                                    label="From Date"
                                    name="fromDate"
                                    rules={[
                                        {
                                            required: true,
                                            message: 'Please Input From Date!',
                                        },
                                    ]}
                                >
                                    <Space direction="vertical" size={12}>
                                        <DatePicker
                                            className={commonStyles.dateWidth}
                                            value={
                                                selectedInvoiceDate3?.length > 0
                                                    ? dayjs(
                                                          selectedInvoiceDate3
                                                      )
                                                    : null
                                            }
                                            onChange={(date, dateString) => {
                                                onChangeInvoiceDate2(
                                                    date,
                                                    dateString
                                                )
                                            }}
                                            disabledDate={(current) => {
                                                const currentDate = dayjs()
                                                return (
                                                    current &&
                                                    current.isAfter(
                                                        currentDate,
                                                        'day'
                                                    )
                                                ) // Disable past dates
                                            }}
                                        />
                                    </Space>
                                </Form.Item>
                            </Col>
                            <Col span={8}>
                                <Form.Item
                                    label="To Date"
                                    name="toDate"
                                    rules={[
                                        {
                                            required: true,
                                            message: 'Please Input To Date!',
                                        },
                                    ]}
                                >
                                    <Space direction="vertical" size={12}>
                                        <DatePicker
                                            value={
                                                selectedDueDate3?.length > 0
                                                    ? dayjs(selectedDueDate3)
                                                    : null
                                            }
                                            onChange={(date, dateString) => {
                                                onChangeDue2(date, dateString)
                                            }}
                                            className={commonStyles.dateWidth}
                                            disabledDate={disabledToDate}
                                            disabled={
                                                !form.getFieldValue('fromDate')
                                            }
                                        />
                                    </Space>
                                </Form.Item>
                            </Col>
                            <Col span={8}>
                                <Form.Item label="User" name="User">
                                    <Select
                                        allowClear
                                        showSearch
                                        placeholder="Please select"
                                        onChange={handleSelectChangeuser}
                                        optionFilterProp="children"
                                        filterOption={(input, option) =>
                                            (option?.label ?? '')
                                                .toLowerCase()
                                                .includes(input.toLowerCase())
                                        }
                                        options={userList}
                                    />
                                </Form.Item>
                            </Col>
                        </Row>
                        <Row gutter={16}>
                            <Col offset={20} span={4}>
                                <Tooltip title="Download Report">
                                    <Button
                                        type="primary"
                                        style={{ marginRight: 8 }}
                                        // eslint-disable-next-line @typescript-eslint/no-misused-promises
                                        onClick={getData}
                                    >
                                        <CloudDownloadOutlined />
                                    </Button>
                                </Tooltip>
                                <Tooltip title="Preview Report">
                                    <Button
                                        type="primary"
                                        onClick={handlePreview}
                                    >
                                        <EyeOutlined />
                                    </Button>
                                </Tooltip>
                            </Col>
                        </Row>
                    </Form>
                </div>
                {showTable &&
                    (previewData?.length > 0 ? (
                        <div style={{ marginTop: '20px' }}>
                            <Table
                                columns={columns}
                                dataSource={processedData}
                                pagination={false}
                                bordered
                                size="small"
                                locale={{ emptyText: 'No record found' }}
                            />
                        </div>
                    ) : (
                        <div style={{ marginTop: '20px', textAlign: 'left' }}>
                            {showMessage ? (
                                <span
                                    style={{
                                        color: '#808080',
                                        fontSize: '18px',
                                        fontWeight: 'bold',
                                    }}
                                >
                                    {' '}
                                    No records found
                                </span>
                            ) : (
                                <h4>Loading data...</h4>
                            )}
                        </div>
                    ))}
            </Card>
        </>
    )
}

const mapStateToProps = (state: any): TimesheetReportInterface => {
    return {
        userList: state.user.userList,
        timesheetreportDetailsList: state.hr.timesheetreportDetailsList,
    }
}

export default connect(mapStateToProps)(TimesheetReport)
