import { type Dispatch } from '@reduxjs/toolkit'
import axios from '../Config/AxiosConfig'
import { ErrorMessage, SuccessMessage } from '../Utils/Notification'
import type {
    ListBackendInterface,
    ListFrontEndInterface,
    TableListInterface,
} from '../Types/CommonType'
import { setLoadingStatus } from '../Reducer/Common'
import {
    type paidInvoice,
    type CommunicationHistory,
    type InvoiceTableData,
    type InvoiceFromData,
    type AdvanceSearchInterface,
    type EmailDetails,
} from '../Types/Invoice/Invoicing'
import {
    clientDropDownList,
    invoiceEmailTemplateTypeList,
    invoiceHistoryDetailsList,
    invoiceList,
    paymentModeList,
    paymentOptionList,
} from '../Reducer/Invoice'
import { SaveEmailAttachments } from './Corporate'
import { SendEmailUseNodeJs } from './Common'

export const GetInvoiceList = (
    dispatch: Dispatch,
    data: TableListInterface,
    searchData: AdvanceSearchInterface | undefined,
    flegId: number
): void => {
    dispatch(setLoadingStatus({ status: true }))
    const { pageNo, pageSize, searchCriteriaList, sortOrderList } = data
    const bodyData = searchData ?? { searchCriteriaList, sortOrderList }

    axios
        .post(
            `/api/AccountInvoice/GetInvoiceList/${flegId}/${pageNo}/${pageSize}/0/0`,
            bodyData
        )
        .then((response) => {
            if (response.status === 200) {
                const newData = response?.data?.data?.map(
                    (value: InvoiceTableData) => {
                        return {
                            ...value,
                            key: value.no,
                        }
                    }
                )
                response.data.data = newData
                dispatch(invoiceList({ ...response.data }))
            } else {
                dispatch(
                    invoiceList({
                        data: [],
                        noOfRecords: 0,
                    })
                )
                ErrorMessage(response.data.operationMsg)
            }
            dispatch(setLoadingStatus({ status: false }))
        })
        .catch((error) => {
            dispatch(
                invoiceList({
                    data: [],
                    noOfRecords: 0,
                })
            )
            console.error('Error fetching posts:', error)
            dispatch(setLoadingStatus({ status: false }))
        })
}

export const GetCilentList = async (
    dispatch: Dispatch,
    searchString: string
): Promise<any> => {
    dispatch(setLoadingStatus({ status: true }))
    await axios
        .get(`/api/GetStandardListingTwo/1/${searchString}`)
        .then((response) => {
            if (response.status === 200) {
                dispatch(clientDropDownList(response.data.data))
                return response?.data
            } else {
                ErrorMessage(response.data.operationMsg)
            }
            dispatch(setLoadingStatus({ status: false }))
        })
        .catch((error) => {
            console.error('Error fetching get:', error)
            dispatch(setLoadingStatus({ status: false }))
        })
}

export const GetInvoiceDetails = async (
    dispatch: Dispatch,
    serviceProcessId: number,
    getDetails: CallableFunction
): Promise<void> => {
    dispatch(setLoadingStatus({ status: true }))
    axios
        .get(`/api/ServiceProcess/GetCommunicationInfo/${serviceProcessId}`)
        .then((response) => {
            if (response.status === 200) {
                const details = response.data.data
                getDetails(details)
            } else {
                ErrorMessage(response.data.operationMsg)
            }

            dispatch(setLoadingStatus({ status: false }))
        })
        .catch((error) => {
            console.error('Error fetching data:', error)
            dispatch(setLoadingStatus({ status: false }))
        })
}

export const SaveCommuniCation = async (
    dispatch: Dispatch,
    data: CommunicationHistory
): Promise<any> => {
    dispatch(setLoadingStatus({ status: true }))
    return await axios
        .post(`/api/Communication/SetCommunicationByInvoiceId`, data)
        .then((response) => {
            dispatch(setLoadingStatus({ status: false }))
            if (response.status === 200) {
                SuccessMessage(response.data.operationMsg)
                return true
            } else {
                ErrorMessage(response.data.operationMsg)
                return false
            }
        })
        .catch((error) => {
            console.error('Error fetching posts:', error)
            dispatch(setLoadingStatus({ status: false }))
            return false
        })
}

export const GetInvoicetHistoryDetailsList = (
    dispatch: Dispatch,
    invoiceId: number,
    selectedButtonId: number,
    data: TableListInterface
): void => {
    dispatch(setLoadingStatus({ status: true }))
    const { pageNo, pageSize, searchCriteriaList, sortOrderList } = data
    const bodyData = {
        searchCriteriaList,
        sortOrderList,
    }

    axios
        .post(
            `/api/Communication/GetCommunicationHistoryListByInvoiceId/${invoiceId}/${selectedButtonId}/${pageNo}/${pageSize}`,
            bodyData
        )
        .then((response) => {
            if (response.status === 200) {
                const newData = response?.data?.data?.map(
                    (value: CommunicationHistory) => {
                        return {
                            ...value,
                            key: value.communicationHistoryId,
                        }
                    }
                )
                response.data.data = newData
                dispatch(invoiceHistoryDetailsList({ ...response.data }))
            } else {
                ErrorMessage(response.data.operationMsg)
            }
            dispatch(setLoadingStatus({ status: false }))
        })
        .catch((error) => {
            dispatch(
                invoiceHistoryDetailsList({
                    data: [],
                    noOfRecords: 0,
                })
            )
            console.error('Error fetching posts:', error)
            dispatch(setLoadingStatus({ status: false }))
        })
}

export const GetEmailTemplateTypeList = (dispatch: Dispatch): void => {
    dispatch(setLoadingStatus({ status: true }))
    axios
        .get('/api/GetStandardListingWithOneParameter/38/105')
        .then((response) => {
            if (response.status === 200) {
                const templateTypeList: ListFrontEndInterface[] =
                    response?.data?.data.map((data: ListBackendInterface) => {
                        return {
                            value: data.stdId,
                            label: data.stdName,
                        }
                    })

                dispatch(invoiceEmailTemplateTypeList(templateTypeList))
            } else {
                ErrorMessage(response.data.operationMsg)
            }
            dispatch(setLoadingStatus({ status: false }))
        })
        .catch((error) => {
            console.error('Error fetching posts:', error)
            dispatch(setLoadingStatus({ status: false }))
        })
}

export const GetPaymentOption = (dispatch: Dispatch): void => {
    dispatch(setLoadingStatus({ status: true }))
    axios
        .get(`/api/GetStandardListingTwo/2/=NA=`)
        .then((response) => {
            if (response.status === 200) {
                dispatch(paymentOptionList(response.data.data))
            } else {
                ErrorMessage(response.data.operationMsg)
            }
            dispatch(setLoadingStatus({ status: false }))
        })
        .catch((error) => {
            console.error('Error fetching get:', error)
            dispatch(setLoadingStatus({ status: false }))
        })
}

export const GetPaymentMode = (dispatch: Dispatch): void => {
    dispatch(setLoadingStatus({ status: true }))
    axios
        .get(`/api/GetStandardListing/20`)
        .then((response) => {
            if (response.status === 200) {
                const uList: ListFrontEndInterface[] = response?.data?.data.map(
                    (data: ListBackendInterface) => {
                        return {
                            value: data.stdId,
                            label: data.stdName,
                        }
                    }
                )
                dispatch(paymentModeList(uList))
            } else {
                ErrorMessage(response.data.operationMsg)
            }
            dispatch(setLoadingStatus({ status: false }))
        })
        .catch((error) => {
            console.error('Error fetching get:', error)
            dispatch(setLoadingStatus({ status: false }))
        })
}

export const SavePaidInvoice = async (
    dispatch: Dispatch,
    data: paidInvoice
): Promise<any> => {
    dispatch(setLoadingStatus({ status: true }))
    return await axios
        .post(`/api/AccountInvoice/SetInvoicePayment`, data)
        .then((response) => {
            dispatch(setLoadingStatus({ status: false }))
            if (response.status === 200) {
                SuccessMessage(response.data.operationMsg)
                return true
            } else {
                ErrorMessage(response.data.operationMsg)
                return false
            }
        })
        .catch((error) => {
            console.error('Error fetching posts:', error)
            dispatch(setLoadingStatus({ status: false }))
            return false
        })
}

export const GetInvoicePreview = async (
    dispatch: Dispatch,
    invoiceId: number
): Promise<any> => {
    dispatch(setLoadingStatus({ status: true }))

    try {
        const response = await axios.get(
            `/api/AccountInvoice/GetInvoicePreview/${invoiceId}`
        )

        if (response.status === 200) {
            return response?.data?.data
        } else {
            ErrorMessage(response.data.operationMsg)
        }
    } catch (error) {
        console.error('Error fetching client company details:', error)
        ErrorMessage('An error occurred while fetching data')
    } finally {
        dispatch(setLoadingStatus({ status: false }))
    }
}

export const GetSendEmailSetails = async (
    dispatch: Dispatch,
    invoiceId: number,
    tempId: number
): Promise<any> => {
    dispatch(setLoadingStatus({ status: true }))

    try {
        const response = await axios.get(
            `api/AccountInvoice/GetEmailDetailByInvoiceId/${invoiceId}/${tempId}`
        )

        if (response.status === 200) {
            SuccessMessage(response.data.operationMsg)
            return response.data.data
        } else {
            ErrorMessage(response.data.operationMsg)
        }
    } catch (error) {
        console.error('Error fetching client company details:')
    } finally {
        dispatch(setLoadingStatus({ status: false }))
    }
}

export const SaveEmail = async (
    dispatch: Dispatch,
    data: EmailDetails,
    attachment: string[],
    htmltmplate: string
): Promise<any> => {
    dispatch(setLoadingStatus({ status: true }))
    return await axios
        .post(`/api/Email/SetClientEmailByInvoiceId`, data)
        .then((response) => {
            dispatch(setLoadingStatus({ status: false }))
            if (response.status === 200) {
                // SuccessMessage(response.data.operationMsg)

                const emailSend = {
                    email: data.toAddress,
                    subject: data.subject,
                    htmlMessage: htmltmplate,
                    description: data.description,
                    attachments: attachment,
                    ccemailAddress: data.ccAddress,
                    bccEmailAddress: data.bccAddress,
                    contactName: data.fromName,
                    employeeName: '',
                    actionUrl: '',
                }
                void SendEmailUseNodeJs(dispatch, emailSend)
                const saveCommincationHistory = {
                    communicationHistoryId: 0,
                    communicationTypeId: 1,
                    invoiceId: data.invoiceId,
                    description: data.subject,
                    historyDate: '',
                    contactNumber: '',
                }
                void SaveCommuniCation(dispatch, saveCommincationHistory)
                attachment.forEach((path): void => {
                    const dataToUpload = {
                        clientAttachmentId: 0,
                        clientEmailId: response.data.identifierId,
                        attachmentPath: path,
                        uniqueCode: '',
                    }
                    void SaveEmailAttachments(dispatch, dataToUpload)
                    // Perform any desired operation with each path
                })
                return true
            } else {
                ErrorMessage(response.data.operationMsg)
                return false
            }
        })
        .catch((error) => {
            console.error('Error fetching posts:', error)
            dispatch(setLoadingStatus({ status: false }))
            return false
        })
}

export const SaveInvoiceDetails = async (
    dispatch: Dispatch,
    data: InvoiceFromData
): Promise<any> => {
    dispatch(setLoadingStatus({ status: true }))
    return await axios
        .post(`/api/AccountInvoice/SetInvoice`, data)
        .then((response) => {
            dispatch(setLoadingStatus({ status: false }))
            if (response.status === 200) {
                SuccessMessage(response.data.operationMsg)

                return true
            } else {
                ErrorMessage(response.data.operationMsg)
                return false
            }
        })
        .catch((error) => {
            console.error('Error fetching posts:', error)
            dispatch(setLoadingStatus({ status: false }))
            return false
        })
}
export const GetSendEmailInvoiceDetails = async (
    dispatch: Dispatch,
    invoiceId: number
): Promise<any> => {
    dispatch(setLoadingStatus({ status: true }))

    try {
        const response = await axios.get(
            `/api/AccountInvoice/GetInvoiceEmailDetail/${invoiceId}`
        )

        if (response.status === 200) {
            // SuccessMessage(response.data.operationMsg)
            return response.data.data
        } else {
            ErrorMessage(response.data.operationMsg)
        }
    } catch (error) {
        console.error('Error fetching client company details:', error)
        ErrorMessage('An error occurred while fetching data')
    } finally {
        dispatch(setLoadingStatus({ status: false }))
    }
}

export const GetClientAddressData = async (
    dispatch: Dispatch,
    businessId: string,
    corporateId: string,
    addressId: number,
    getAddress: CallableFunction
): Promise<void> => {
    dispatch(setLoadingStatus({ status: true }))
    axios
        .get(
            `/api/GetCompanyAddressInformation/${businessId}/${corporateId}/${addressId}`
        )
        .then((response) => {
            if (response.status === 200) {
                const addressData = response.data.data
                getAddress(addressData)
            } else {
                ErrorMessage(response.data.operationMsg)
            }
            dispatch(setLoadingStatus({ status: false }))
        })
        .catch((error) => {
            console.error('Error fetching data:', error)
            dispatch(setLoadingStatus({ status: false }))
        })
}
