import React, { useEffect, useRef, useState } from 'react'
import {
    Col,
    Row,
    Input,
    Form,
    Button,
    Card,
    Table,
    Select,
    Space,
    DatePicker,
    type DatePickerProps,
    type SelectProps,
    type TableProps,
} from 'antd'
import commonStyles from '../../../Utils/Common.less'
import { SaveOutlined } from '@ant-design/icons'
import {
    type InvoiceDetailsListInterface,
    type createInvoicePageProp,
    type OptionList,
    type InvoiceBody,
    type InvoiceDetailView,
    type InvoiceDetail,
} from '../../../Types/Invoice/Invoicing'
import {
    GetClientAddressData,
    GetPaymentMode,
    GetPaymentOption,
    SaveInvoiceDetails,
} from '../../../Services/Invoice'
import { connect, useDispatch } from 'react-redux'
import { GetUserList } from '../../../Services/User'
import dayjs from 'dayjs'
import invoive from './Invoice.less'
import axios from '../../../Config/AxiosConfig'
import EditabeRowTable from './edittableTdTh'
import { ErrorMessage } from '../../../Utils/Notification'
import { type TogilleAddress } from '../../../Types/Client/RegisteredClients/Corporate'
import ActivePremission from '../../../Utils/premissins'
import { PermissionType } from '../../../Types/Enum/PermissionType'
import moment from 'moment'
import { useNavigate } from 'react-router-dom'
interface DataType {
    key: string
    displayname: any
    amount: any
}
const CreateInvoice = (props: createInvoicePageProp): React.ReactElement => {
    const {
        userList,
        paymentOptionList,
        paymentModeList,
        serviceDropDownList,
    } = props
    const dispatch = useDispatch()
    const [form] = Form.useForm()
    const [searchValue, setSearchValue] = useState<string>('')
    const [selectedpaymentOption, setSelectedpaymentOption] = useState('')
    const [isLoading, setLoading] = useState<boolean>(false)
    const [paymentoptions, setPymentOptions] = useState<OptionList[]>(
        [] as OptionList[]
    )
    const [selectedDueDate, setSelectedDueDate] = useState<string>('')
    const [selectedInvoiceDate, setSelectedInvoiceDate] = useState<string>('')
    const [data, setData] = useState<SelectProps['options']>([])
    const [subTotal, setSubTotal] = useState(0)
    const [discount, setDiscount] = useState(0)
    const [netTotal, setNetTotal] = useState(0)
    const [tax, setTaxTotal] = useState(0)
    const [tabledata, setTabledata] = useState<InvoiceBody[]>([])
    const [clientNumber, setClientNumber] = useState('')
    const navigate = useNavigate()
    const hasFetchedOnce = useRef(false)
    useEffect(() => {
        if (!hasFetchedOnce.current) {
            hasFetchedOnce.current = true
            return
        }
        GetUserList(dispatch)
        GetPaymentMode(dispatch)
        GetPaymentOption(dispatch)
    }, [])

    useEffect(() => {
        form.setFieldValue('duedate', selectedDueDate)
        form.setFieldValue('invoicedate', selectedInvoiceDate)
    }, [selectedDueDate, selectedInvoiceDate])

    const onChangeDue = (
        date: DatePickerProps['value'],
        dateString: string | string[]
    ): void => {
        if (date !== null && date !== undefined) {
            const isoDate = date.toISOString()

            setSelectedDueDate(isoDate)
        }
    }

    const onChangeInvoiceDate = (
        date: DatePickerProps['value'],
        dateString: string | string[]
    ): void => {
        if (date !== null && date !== undefined) {
            const isoDate = date.toISOString()
            setSelectedInvoiceDate(isoDate)
        }
    }
    const dataSource: DataType[] = [
        {
            key: '1',
            displayname: <b>Sub Total</b>,
            amount: subTotal.toFixed(2),
        },
        {
            key: '2',
            displayname: <b>Discount</b>,
            amount: discount.toFixed(2),
        },
        {
            key: '3',
            displayname: <b>Net Total</b>,
            amount: netTotal.toFixed(2),
        },
        {
            key: '4',
            displayname: <b>Tax</b>,
            amount: tax.toFixed(2),
        },
        {
            key: '5',
            displayname: <b>Invoice Amount ( £ )</b>,
            amount: <b>{(tax + netTotal).toFixed(2)}</b>,
        },
    ]

    const columns: TableProps<DataType>['columns'] = [
        { title: '', dataIndex: 'displayname', key: 'name' },
        { title: '', dataIndex: 'amount', key: 'amount', align: 'right' },
    ]

    const handleClientChange = (value: string): void => {
        setClientNumber(value)
    }

    const handlePaymentOptionChange = (value: string): void => {
        setSelectedpaymentOption(value)
    }

    const GetStandardListingTwo = async (search: string): Promise<void> => {
        setLoading(true)
        await axios
            .get(`api/GetStandardListingTwo/1/${search}`)
            .then((response: any) => {
                if (response.status === 200) {
                    const clients = response?.data?.data

                    const newData = clients?.map((client: any) => {
                        return {
                            label: client.displayName,
                            value: client.id,
                            desc: (
                                <div>
                                    <div
                                        className={client.clintDropdownListDiv}
                                    >
                                        <span>{client.displayName}</span>
                                    </div>
                                    <div>
                                        <span>
                                            {client.additionalDataTwo}-
                                            {client.additionalDataOne}
                                        </span>
                                    </div>
                                    <div>
                                        <span
                                            className={
                                                client.clientDropdownListSpan
                                            }
                                        >
                                            Name-{client.additionalDataThree}
                                        </span>
                                        <span
                                            className={
                                                client.clientDropdownListSpan2
                                            }
                                        ></span>
                                        <span
                                            className={
                                                client.clientDropdownListSpan
                                            }
                                        >
                                            ContactNo-
                                            {client.additionalDataFour}
                                        </span>
                                    </div>
                                    <div>
                                        <span>
                                            Email-{client.additionalDataFive}
                                        </span>
                                    </div>
                                </div>
                            ),
                        }
                    })
                    setData(newData)
                    setLoading(false)
                } else {
                    setLoading(false)
                    ErrorMessage(response.data.error.message)
                }
            })
            .catch(() => {
                setLoading(false)
            })
    }

    useEffect(() => {
        if (
            searchValue !== null &&
            searchValue !== undefined &&
            searchValue !== '' &&
            searchValue?.length > 2
        ) {
            void GetStandardListingTwo(searchValue)
        }
    }, [searchValue])

    useEffect(() => {
        if (paymentOptionList !== undefined) {
            setPymentOptions(
                paymentOptionList?.map((client) => {
                    return {
                        label: client.displayName,
                        value: client.id,
                        id: client.additionalDataFour,
                        desc: (
                            <div>
                                <div className={invoive.clintDropdownListDiv}>
                                    {/* <img
                                        className={invoive.clintDropdownListImg}
                                        src={client.displayImageURL}
                                        alt="User"
                                    /> */}
                                    <span>{client.displayName}</span>
                                </div>
                                <div>
                                    <span>
                                        {client.additionalDataTwo}-
                                        {client.additionalDataOne}
                                    </span>
                                </div>
                                <div>
                                    <span
                                        className={
                                            invoive.clientDropdownListSpan
                                        }
                                    >
                                        Name-{client.additionalDataThree}
                                    </span>
                                    <span
                                        className={
                                            invoive.clientDropdownListSpan2
                                        }
                                    ></span>
                                    <span
                                        className={
                                            invoive.clientDropdownListSpan
                                        }
                                    >
                                        ContactNo-{client.additionalDataFour}
                                    </span>
                                </div>
                                <div>
                                    <span>
                                        Email-{client.additionalDataFive}
                                    </span>
                                </div>
                            </div>
                        ),
                    }
                })
            )
        }
    }, [paymentOptionList])

    useEffect(() => {
        if (clientNumber?.length > 0) {
            const clientNumberData = clientNumber.split('-')
            const businessId = clientNumberData[0]
            const referenceId = clientNumberData[1]
            const addressid = businessId === '1' ? 3 : 2
            void GetClientAddressData(
                dispatch,
                businessId,
                referenceId,
                addressid,
                (addressData: TogilleAddress) => {
                    form.setFieldValue(
                        'invoiceto',
                        `${addressData?.addressLineOne}\n${addressData?.addressLineTwo}\n${addressData?.town}\n${addressData?.postCode}\n${addressData?.country}`
                    )
                    form.setFieldValue(
                        'paidBy',
                        `${addressData?.addressLineOne}\n${addressData?.addressLineTwo}\n${addressData?.town}\n${addressData?.postCode}\n${addressData?.country}`
                    )
                }
            )
        }
    }, [clientNumber])

    const onSave = (): void => {
        void onSaveEmail()
    }
    const onSaveEmail = async (): Promise<void> => {
        try {
            await form.validateFields()

            const formData = form.getFieldsValue()
            const setSelectedClient = data?.find(
                (client) => client.value === clientNumber
            )

            const nameParts = clientNumber.split('-')
            const payementOptionName = paymentoptions.find(
                (payment) => payment.value === formData.paymentOptionId
            )
            if (tabledata?.length !== 0 && tabledata !== undefined) {
                const InvoiceDetailList: InvoiceDetail[] = tabledata.map(
                    (data) => ({
                        invoiceId: data?.invoiceId ?? 0,
                        lineDescription: data?.lineDescription ?? '',
                        quantity: 0,
                        unitPrice: data?.grossTotal ?? 0,
                        grossTotal: data?.grossTotal ?? 0,
                        discountType: data?.discountType ?? 1,
                        discountValue: data?.discountValue ?? 0,
                        discount: 0,
                        totalAfterDiscount:
                            data?.totalAfterDiscount ??
                            data?.grossTotal - data?.discountValue,
                        serviceId:
                            serviceDropDownList?.find(
                                (service) => service.label === data?.serviceName
                            )?.value ?? 0,
                        taxApplied: 0,
                        tax: data?.tax ?? 0,
                        netAmount: data?.netAmount ?? 0,
                    })
                )

                const InvoiceDetailViewList: InvoiceDetailView[] =
                    tabledata.map((data) => ({
                        invoiceId: data?.invoiceId ?? 0,
                        lineDescription: data?.lineDescription ?? '',
                        quantity: 0,
                        unitPrice: data?.grossTotal ?? 0,
                        grossTotal: data?.grossTotal ?? 0,
                        discountType: data?.discountType ?? 1,
                        discountValue: data?.discountValue ?? 0,
                        discount: 0,
                        totalAfterDiscount:
                            data?.totalAfterDiscount ??
                            data?.grossTotal - data?.discountValue,
                        serviceId:
                            serviceDropDownList?.find(
                                (service) => service.label === data?.serviceName
                            )?.value ?? 0,
                        taxApplied: 0,
                        tax: data?.tax ?? 0,
                        netAmount: data?.netAmount ?? 0,
                        invoiceDetailId: data?.invoiceDetailId ?? 0,
                        serviceName: data?.serviceName ?? '',
                        description: data?.description ?? '',
                    }))

                const dataTosave = {
                    invoiceId: 0,
                    invoiceNo: '',
                    invoiceCategory: 0,
                    businessType: Number(nameParts[0]) ?? 0,
                    invoiceFor: Number(nameParts[1]) ?? 0,
                    invoiceForDescription: formData.invoiceto ?? '',
                    invoiceDate:
                        moment(selectedInvoiceDate).format('DD/MM/YYYY') ?? '',
                    paymentDueDate:
                        moment(selectedDueDate).format('DD/MM/YYYY') ?? '',
                    total: tax + netTotal,
                    subTotal,
                    discountTotal: discount,
                    taxTotal: tax,
                    netTotal,
                    preparedBy: formData.risedbyId ?? 0,
                    paymentNotifyTo: 0,
                    paidTo: 0,
                    paidToDescription: formData.paidBy ?? '',
                    approvedBy: formData.approvedBy ?? 0,
                    invoiceStatus: 0,
                    paymentModeId: formData.paymentModeId ?? 0,
                    paymentOptionId: Number(payementOptionName?.value) ?? 0,
                    remarks: formData.remarks ?? '',
                    clientId: '',
                    clientName: setSelectedClient?.label?.toString() ?? '',
                    paymentOptionName: payementOptionName?.label ?? '',
                    acc_InvoiceDetailList: InvoiceDetailList ?? null,
                    acc_InvoiceDetailViewList: InvoiceDetailViewList ?? null,
                    isSent: 0,
                    sentDate: '',
                    serviceProcessId: 0,
                    isPaid: 0,
                    paidDate: '',
                    paidRemarks: '',
                    accountName: '',
                    accountNo: '',
                    branch: '',
                    swiftCode: '',
                    iban: '',
                }
                await SaveInvoiceDetails(dispatch, dataTosave)
                navigate('/invoicing/invoic-status')
            } else {
                ErrorMessage('Plese select Atleast One Service')
            }
        } catch (error) {
            console.error('Error:', error)
        }
    }

    const customizeRequiredMark = (
        label: React.ReactNode,
        { required }: { required: boolean }
    ): React.ReactElement => (
        <>
            {label}
            &nbsp;
            {required && <span className={commonStyles.requireIcon}>*</span>}
        </>
    )

    return (
        <Card title="Create Invoice" className={commonStyles.card}>
            <div className={commonStyles.formWrapper}>
                <Form
                    name="complex-form"
                    labelCol={{ span: 24 }}
                    wrapperCol={{ span: 24 }}
                    initialValues={{ remember: true }}
                    layout={'vertical'}
                    autoComplete="off"
                    form={form}
                    size="small"
                    requiredMark={customizeRequiredMark}
                >
                    <Row gutter={16}>
                        <Col span={12}>
                            <Form.Item
                                label="Client"
                                name="contactName"
                                rules={[
                                    {
                                        required: true,
                                        message: 'Please input your firstName!',
                                    },
                                ]}
                            >
                                <Select
                                    loading={isLoading}
                                    showSearch
                                    placeholder="Plese Enter 3 or more charector"
                                    onChange={(value) => {
                                        handleClientChange(value)
                                    }}
                                    onSearch={(value) => {
                                        setSearchValue(value)
                                    }}
                                    filterOption={false}
                                    allowClear
                                    onClear={() => {
                                        setData([])
                                    }}
                                    optionLabelProp="label"
                                    options={data}
                                    optionRender={(option) => (
                                        <>{option.data.desc}</>
                                    )}
                                    dropdownRender={(menu) => {
                                        // Default message
                                        let message =
                                            'Please enter 3 or more characters'

                                        // Check the length of searchValue before determining the message
                                        if (searchValue?.length === 1) {
                                            message =
                                                'Please enter 2 more characters'
                                        } else if (searchValue?.length === 2) {
                                            message =
                                                'Please enter 1 more character'
                                        } else if (searchValue?.length >= 3) {
                                            message = '' // No message if 3 or more characters are typed
                                        }

                                        return (
                                            <>
                                                {menu}
                                                {/* Dropdown footer */}
                                                <div
                                                    style={{
                                                        padding: '8px 16px',
                                                        borderTop:
                                                            '1px solid #e8e8e8',
                                                    }}
                                                >
                                                    <span
                                                        style={{
                                                            color: 'red',
                                                        }}
                                                    >
                                                        {message}
                                                    </span>
                                                </div>
                                            </>
                                        )
                                    }}
                                />
                            </Form.Item>
                        </Col>
                        <Col span={12}>
                            <Form.Item
                                label="Raised by"
                                name="risedbyId"
                                rules={[
                                    {
                                        required: true,
                                        message: 'Please Select Raised by!',
                                    },
                                ]}
                            >
                                <Select
                                    allowClear
                                    showSearch
                                    placeholder="Please select"
                                    onChange={() => {}}
                                    optionFilterProp="children"
                                    filterOption={(input, option) =>
                                        (option?.label ?? '')
                                            .toLowerCase()
                                            .includes(input.toLowerCase())
                                    }
                                    options={userList}
                                />
                            </Form.Item>
                        </Col>
                    </Row>
                    <Row gutter={16}>
                        <Col span={12}>
                            <Form.Item
                                label="Invoice Date"
                                name="invoicedate"
                                rules={[
                                    {
                                        required: true,
                                        message: 'Please input Invoice Date!',
                                    },
                                ]}
                            >
                                <Space direction="vertical" size={12}>
                                    <DatePicker
                                        onChange={(date, dateString) => {
                                            onChangeInvoiceDate(
                                                date,
                                                dateString
                                            )
                                        }}
                                        value={
                                            selectedInvoiceDate?.length > 0
                                                ? dayjs(selectedInvoiceDate)
                                                : null
                                        }
                                        className={commonStyles.dateWidth}
                                    />
                                </Space>
                            </Form.Item>
                        </Col>
                        <Col span={12}>
                            <Form.Item
                                label="Due Date"
                                name="duedate"
                                rules={[
                                    {
                                        required: true,
                                        message: 'Please input your Due Date!',
                                    },
                                ]}
                            >
                                <Space direction="vertical" size={12}>
                                    <DatePicker
                                        onChange={(date, dateString) => {
                                            onChangeDue(date, dateString)
                                        }}
                                        value={
                                            selectedDueDate?.length > 0
                                                ? dayjs(selectedDueDate)
                                                : null
                                        }
                                        className={commonStyles.dateWidth}
                                        disabledDate={(current) =>
                                            current !== null &&
                                            current < moment().startOf('day')
                                        }
                                    />
                                </Space>
                            </Form.Item>
                        </Col>
                    </Row>
                    <Row gutter={16}>
                        <Col span={12}>
                            <Form.Item
                                label="Invoice To"
                                name="invoiceto"
                                rules={[
                                    {
                                        required: true,
                                        message: 'Please input your Comments',
                                    },
                                ]}
                            >
                                <Input.TextArea rows={6} />
                            </Form.Item>
                        </Col>

                        <Col span={12}>
                            <Form.Item
                                label="Paid By"
                                name="paidBy"
                                rules={[
                                    {
                                        required: true,
                                        message: 'Please input your Comments',
                                    },
                                ]}
                            >
                                <Input.TextArea rows={6} />
                            </Form.Item>
                        </Col>
                    </Row>
                    <div className={invoive.editrowTableMargin}>
                        <EditabeRowTable
                            editstatus={true}
                            setTaxTotal={setTaxTotal}
                            setSubTotal={setSubTotal}
                            setDiscount={setDiscount}
                            setNetTotal={setNetTotal}
                            setTabledata={setTabledata}
                        />
                    </div>

                    <Row gutter={[48, 8]}>
                        <Col span={12}>
                            <Row gutter={16}>
                                <Col span={24}>
                                    <Form.Item
                                        label="Payment Mode"
                                        name="paymentModeId"
                                        rules={[
                                            {
                                                required: true,
                                                message:
                                                    'Please input your Payment Mode',
                                            },
                                        ]}
                                    >
                                        <Select
                                            allowClear
                                            showSearch
                                            placeholder="Please select"
                                            onChange={() => {}}
                                            optionFilterProp="children"
                                            filterOption={(input, option) =>
                                                (option?.label ?? '')
                                                    .toLowerCase()
                                                    .includes(
                                                        input.toLowerCase()
                                                    )
                                            }
                                            options={paymentModeList}
                                        />
                                    </Form.Item>
                                </Col>
                            </Row>
                            <Row gutter={16}>
                                <Col span={24}>
                                    <Form.Item
                                        label="Payment Option"
                                        name="paymentOptionId"
                                        rules={[
                                            {
                                                required: true,
                                                message:
                                                    'Please input your Comments',
                                            },
                                        ]}
                                    >
                                        <Select
                                            allowClear
                                            showSearch
                                            placeholder="Please select"
                                            onChange={handlePaymentOptionChange}
                                            optionFilterProp="children"
                                            value={selectedpaymentOption}
                                            optionLabelProp="label"
                                            options={paymentoptions}
                                            optionRender={(option) => (
                                                <>{option.data?.desc}</>
                                            )}
                                        />
                                    </Form.Item>
                                </Col>
                            </Row>
                            <Row gutter={16}>
                                <Col span={24}>
                                    <Form.Item
                                        label="Approved by"
                                        name="approvedBy"
                                        rules={[
                                            {
                                                required: true,
                                                message:
                                                    'Please input your Comments',
                                            },
                                        ]}
                                    >
                                        <Select
                                            allowClear
                                            showSearch
                                            placeholder="Please select"
                                            onChange={() => {}}
                                            optionFilterProp="children"
                                            filterOption={(input, option) =>
                                                (option?.label ?? '')
                                                    .toLowerCase()
                                                    .includes(
                                                        input.toLowerCase()
                                                    )
                                            }
                                            options={userList}
                                        />
                                    </Form.Item>
                                </Col>
                            </Row>
                            <Row gutter={16}>
                                <Col span={24}>
                                    <Form.Item label="Remarks" name="remarks">
                                        <Input.TextArea rows={4} />
                                    </Form.Item>
                                </Col>
                            </Row>
                        </Col>
                        <Col span={12}>
                            <div>
                                <Table
                                    dataSource={dataSource}
                                    columns={columns}
                                    pagination={false}
                                    showHeader={false}
                                    scroll={{ x: 12 }}
                                />
                            </div>
                        </Col>
                    </Row>
                    {ActivePremission('6000', PermissionType.SAVE) && (
                        <Row gutter={16}>
                            <Col offset={21} span={2}>
                                <Button
                                    type="primary"
                                    onClick={onSave}
                                    size="middle"
                                >
                                    <SaveOutlined />
                                </Button>
                            </Col>
                        </Row>
                    )}
                </Form>
            </div>
        </Card>
    )
}

const mapStateToProps = (state: any): InvoiceDetailsListInterface => {
    return {
        clientDropDownList: state.invoice.clientDropDownList,
        userList: state.user.userList,
        serviceDropDownList: state.initial.serviceDropDownList,
        paymentOptionList: state.invoice.paymentOptionList,
        paymentModeList: state.invoice.paymentModeList,
    }
}
export default connect(mapStateToProps)(CreateInvoice)
