import React, { useState, useCallback, useEffect, useMemo } from 'react';
import { Box, Grid, TextField, makeStyles, Typography, Divider } from '@material-ui/core';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
import { AppState } from '../../../Redux';
import { USER_ROLES } from '../../../Types/Constants';
import { JobV2 } from '../../../Api/Job/JobV2';
import { IShowJobsProps } from '../Jobs/ShowJobs/ShowJobs.types';
import LazyLoadingTable from './LazyloadTable';
import { getColumns } from './columnsConfig';
import useDebouncedValue from '../../../hooks/useDebouncedValue';
import { JobDataV2, jobDataV2Extended } from '../../../../../Application/DTOs/JobsDto/JobsDto.types';
import { POST_TO, JOB_STATUS } from '../../../Types/Constants';
import { toast } from 'react-toastify';
import { Job } from '../../../Api/Job/Job';
import Swal from 'sweetalert2'
import fileDownload from 'js-file-download';

// import ViewEditJob from '../../Dialogs/ViewEditJob/ViewEditJob';
import ViewEditJob from './ViewEditJobDialog';
import DateEntryDialog from '../../Dialogs/DateEntryDialog/DateEntryDialog';
import AdditionalStepDialog from '../../Dialogs/AdditionalStepDialog/AdditionalStepdialog';
import MarkCompleteDialog from '../../Dialogs/MarkCompleteDialog/MarkCompleteDialog';

import { TActualDateTypes } from '../../../Types/Constants';
import { useLocation } from 'react-router-dom';
import {
    AVAILABLE,
    BIDS_TO_CONFIRM,
    JOBS_WILDCARDS_KEYS,
} from '../Jobs/Jobs.constans';
const _ = require('lodash');

const { PUBLIC } = POST_TO;

const useStyles = makeStyles(() => ({
    mapBox: {
        width: '100%',
        height: '40vh',
        display: 'flex',
        flexFlow: 'row nowrap',
        justifyContent: 'center',
        padding: 0
    },

}));

const { ADMIN_USER } = USER_ROLES;
const jobApi = new Job();
const { IN_PROGRESS, DELIVERED, PICKEDUP, ASSIGNED, FUMIGATION, VIA_YARD, STORAGE } = JOB_STATUS;

const App = (props: IShowJobsProps) => {
    const { pageType } = props;
    const [jobsApiV2] = useState(new JobV2());
    const [t] = useTranslation(['ShowJobs', 'Columns']);
    const classes = useStyles();
    const user = useSelector((state: AppState) => state.user);
    const isAdminUser = user.response?.type === ADMIN_USER;

    const location = useLocation();
    const queryParams = new URLSearchParams(location.search);
    const referenceParam = queryParams.get('reference') || '';

    const [searchParam, setSearchParam] = useState(referenceParam);

    const [updateTable, setUpdateTable] = useState(false);
    const [selectedJob, setSelectedJob] = useState<JobDataV2 | null>(null)
    const [isViewEditJobDialogOpen, setIsViewEditJobDialogOpen] = useState(false);
    const [isDateEntryDialogOpen, setIsDateEntryDialogOpen] = useState(false);
    const [isAdditionalDialogOpen, setIsAdditionalDialogOpen] = useState(false);
    const [isMarkCompleteDialogOpen, setIsMarkCompleteDialogOpen] = useState(false);
    let dateType: TActualDateTypes | undefined = useMemo(() => {
        switch (selectedJob?.status) {
            case IN_PROGRESS:
            case ASSIGNED:

                return 'pickup';
            case PICKEDUP:
            case FUMIGATION:
            case VIA_YARD:
            case STORAGE:
                return 'delivery';
            case DELIVERED:
                return 'return';

            default:
                return undefined;
        }
    }, [selectedJob?.status]);
    const fetchDataFromAPI = useCallback(
        async (limit, offset, sortConfig, filters) => {
            try {
                const response = await jobsApiV2.getJobListing(
                    props.type,
                    isAdminUser ? user.response?.country : undefined,
                    offset,
                    limit,
                    pageType,
                    sortConfig,
                    filters
                )
                const { rows, count } = response.data;
                return { rows, count };
            } catch (err) {
                console.error('Error fetching data:', err);
                return { rows: [], count: 0 };
            }
        },
        [props.type, pageType, user.response?.country, isAdminUser]
    );


    const handleRowClick = useCallback(
        (rowParams: jobDataV2Extended) => {
            setSelectedJob(rowParams)

            setIsViewEditJobDialogOpen(true);

            // if (pageType === BIDS_TO_CONFIRM) {
            //     // setIsShowBiddersDialogOpen(true);
            // } else {
            //     setIsViewEditJobDialogOpen(true);
            // }
        },
        [setSelectedJob, setIsViewEditJobDialogOpen]
    );
    const handleOnViewEditJobDialogClose = useCallback(() => {
        setIsViewEditJobDialogOpen(false);
        setSelectedJob(null)
    }, [setIsViewEditJobDialogOpen]);

    const makePublic = useCallback(
        (job: jobDataV2Extended) => {
            const formData = new FormData();
            formData.append('post_to', PUBLIC);
            jobApi.update(job.id, formData)
                .then(() => {
                    toast.success(t('success_make_public'));
                    setUpdateTable((prev) => !prev);
                })
                .catch((err) => {
                    console.log('err', err);
                    toast.error(t('error_make_public'));
                });
        },
        [t, updateTable]
    );

    const onCancelJob = useCallback(
        (job: jobDataV2Extended) => {
            jobApi.cancelJob(job.id)
                .then(() => {
                    toast.success(t('success_cancelling_job'));
                    setUpdateTable((prev) => !prev);
                })
                .catch((err) => {
                    console.log('err', err);
                    toast.error(t('error_canceling_job'));
                });
        },
        [t]
    );
    const onSetDate = useCallback(
        (job: jobDataV2Extended) => {
            setSelectedJob(job)
            setIsDateEntryDialogOpen(true);

        },
        [t]
    );
    const handleOnDateEntryDialogClose = useCallback(() => {
        setUpdateTable((prev) => !prev);
        setSelectedJob(null)
        setIsDateEntryDialogOpen(false);
    }, [setSelectedJob]);


    const onMarkAsComplete = useCallback(
        (job: jobDataV2Extended) => {
            setSelectedJob(job)
            setIsMarkCompleteDialogOpen(true);
        },
        [t]
    );

    const handleOnMarkCompleteDialogClose = useCallback(() => {
        setUpdateTable((prev) => !prev);
        setSelectedJob(null)
        setIsMarkCompleteDialogOpen(false);
    }, [setSelectedJob]);


    const onAdditionalStep = useCallback(
        (job: jobDataV2Extended) => {
            setSelectedJob(job)
            setIsAdditionalDialogOpen(true);
        },
        [t]
    );
    const handleOnDialogClose = useCallback(() => {
        setUpdateTable((prev) => !prev);
        setSelectedJob(null)
        setIsAdditionalDialogOpen(false);
    }, [setSelectedJob]);


    const isNotNullOrEmpty = str => !_.isNil(str) && !_.isEmpty(_.toString(str));

    const onConnoteClick = useCallback(
        (job: jobDataV2Extended) => {

            Swal.fire({
                title: 'Select a file',
                input: 'file',
                inputAttributes: {
                    accept: '.pdf', // specify accepted file types, e.g., 'image/*,.pdf,.doc'
                    'aria-label': 'Upload Connote files',
                    multiple: 'multiple' // allow multiple file selection
                },
                showCancelButton: true,
                confirmButtonText: 'Upload',
                cancelButtonText: 'Cancel',
                showLoaderOnConfirm: true,
                preConfirm: (files) => {
                    // You can process the selected file here

                    return files;
                }
            }).then((result) => {


                if (result.isConfirmed) {
                    const files = result.value;
                    if (!files) {
                        toast.error("File not found");
                        return
                    }
                    if (!isNotNullOrEmpty(job.pickup_address_email)) {
                        toast.error("Email recipient not found");
                        return
                    }
                    if (result.isConfirmed) {
                        //12 is connotation in database. can be adjusted to be dynamic
                        jobApi.uploadFiles(12, files, job.id, true, 12).then(() => {
                            toast.success('The file has been uploaded, and the email has been sent.');

                            jobApi.sendConnotationEmail(job.id, files).then((response) => {
                            }).catch((err: any) => {
                                console.log('err', err);
                                toast.error(t(err.response?.data || 'error_uploading_file'));
                            })
                        })
                            .catch((err: any) => {
                                console.log('err', err);
                                toast.error(t(err.response?.data || 'error_uploading_file'));
                            });
                    }
                }
            });
            // dispatch(setSelectedJob(job));

        },
        [t]
    );

    const onDownloadPod = useCallback(
        (job: JobDataV2) => {
            jobApi
                .downloadAllJobFiles(job.id)
                .then((response) => {
                    fileDownload(response.data, 'job_files.zip', 'application/zip');
                })
                .catch((err: any) => {
                    console.log('err', err);
                    toast.error(t('error_download_proof_of_delivery'));
                });
        },
        [t]
    );

    const callbacks = {
        makePublic, //adjusted ok
        onCancelJob, //adjusted ok
        onSetDate, // adjusted ok
        onAdditionalStep, // adjusted ok
        onMarkAsComplete, // adjusted ok
        onConnoteClick, //adjusted ok
        onDownloadPod // adjusted ok
    };
    const columns = getColumns(t, pageType, user, callbacks);

    return (
        <Box sx={{ textAlign: 'center' }}>
            <Grid item>
                <Typography style={{ textAlign: 'left' }}>
                    {`${t(pageType)} `}
                </Typography>
            </Grid>
           
            <LazyLoadingTable
                columns={columns}
                fetchDataFromAPI={fetchDataFromAPI}
                onRowClick={handleRowClick}
                searchParam={searchParam}
                pageType={pageType}
                updateTable={updateTable}
            />
            <ViewEditJob
                hideActionButtons
                selectedJobId={selectedJob ? selectedJob.id : null}
                type={props.type}
                open={isViewEditJobDialogOpen}
                handleClose={handleOnViewEditJobDialogClose}
                mode={'edit'}
            />
            <DateEntryDialog
                type={dateType}
                selectedJob={selectedJob}
                open={isDateEntryDialogOpen}
                handleClose={handleOnDateEntryDialogClose}
            />
            <AdditionalStepDialog
                selectedJob={selectedJob}
                open={isAdditionalDialogOpen}
                handleClose={handleOnDialogClose}
            />
            <MarkCompleteDialog
                selectedJob={selectedJob}
                open={isMarkCompleteDialogOpen}
                handleClose={handleOnMarkCompleteDialogClose}
            />
        </Box>

    );
};

export default App;
