import {
  Button,
  Divider,
  Grid,
  Typography,
  TextField,
  InputAdornment,
} from '@material-ui/core';
import React, {useCallback, useEffect, useState} from 'react';
import {useTranslation} from 'react-i18next';
import CustomTable from '../../../Common/CustomTable/CustomTable';
import LazyTable from '../../../Common/LazyTable/LazyTable';

import {IJobReportProps} from './JobReport.types';
import FilterListIcon from '@material-ui/icons/FilterList';
import SaveIcon from '@material-ui/icons/Save';
import JobReportFilterDialog from '../../../Dialogs/JobReportFilterDialog/JobReportFilterDialog';
import {
  IJobInfo,
  IJobReportFilter,
} from '../../../../../../Application/DTOs/JobsDto/JobsDto.types';
import {JOB_STATUS, USER_ROLES} from '../../../../Types/Constants';
import {useDispatch, useSelector} from 'react-redux';
import {setLoader} from '../../../../Redux/Loader/actions';
import {Job} from '../../../../Api/Job/Job';
import {toast} from 'react-toastify';
import {getJobReportColumns} from './completedJobsColumns';
import ViewEditJob from '../../../Dialogs/ViewEditJob/ViewEditJob';
import {GridRowParams} from '@material-ui/data-grid';
import fileDownload from 'js-file-download';
import {generateJobReportFileNameCsv} from '../../../../Utilities/Formatting';
import {JOB_REPORT_COLUMNS} from './columns';
import SearchIcon from '@material-ui/icons/Search';
import {AppState} from '../../../../Redux';
import AlternateEmailIcon from '@material-ui/icons/AlternateEmail';

const {COMPLETED} = JOB_STATUS;

const jobApi = new Job();

const {
  AGREED_PRICE,
  BIDDING_COMPANY_NAME,
  JOB_TYPE,
  JOB_WAIT_TIME,
  MOVEMENT_TYPE,
  REFERENCE,
  VEHICLE_TYPE,
} = JOB_REPORT_COLUMNS;

const {SUPER_ADMIN, ADMIN_USER} = USER_ROLES;

export default function CompletedJobsReport(props: IJobReportProps) {
  const {type} = props;
  const [t, i18n] = useTranslation('JobReport');
  const dispatch = useDispatch();
  const user = useSelector((state: AppState) => state.user);
  const [isJobReportFilterDialogOpen, setIsJobReportFilterDialogOpen] =
    useState(false);
  const [isViewEditJobDialogOpen, setIsViewEditJobDialogOpen] = useState(false);
  const [filterState, setFilterState] = useState<IJobReportFilter>({
    job_status: [COMPLETED],
    reference:""
  });
  const [jobs, setJobs] = useState<IJobInfo[]>([]);
  const [selectedJob, setSelectedJob] = useState<IJobInfo | null>(null);
  const [searchByReference, setSearchByReference] = useState('');
  const [email, setEmail] = useState('');
  const isUserAdmin = [SUPER_ADMIN, ADMIN_USER].includes(
    user.response?.type ?? ''
  );

  const getJobsForReport = useCallback(
    (filters: IJobReportFilter) => {
      dispatch(setLoader(true));
      jobApi
        .getJobsForReport_v2({
          classification: type,
          filters,
        })
        .then((response) => {
          const jobs: IJobInfo[] = response.data.jobList;
          setJobs(jobs);
          dispatch(setLoader(false));
        })
        .catch((err :any) => {
          console.log('err', err);
          toast.error(t('error_getting_jobs_for_reports'));
          dispatch(setLoader(false));
        });
    },
    [dispatch, t, type]
  );



  const lazyGet = async( offset : number , pageNumber : number , limit :number)=>{
    return jobApi.getJobsForReport_lazy({
          classification: type,
          filters : filterState,
          offset,
          pageNumber,
          limit
        })
        .then((response) => {
          const jobs: IJobInfo[] = response.data.jobList;
          const count = response.data.jobsCount;

          return {jobs , count }
        })
        .catch((err :any) => {
          console.log('err', err);
          toast.error(t('error_getting_jobs_for_reports'));
        });
  }

  const downloadJobsForReport = useCallback(
    (filters: IJobReportFilter, sendAsEmail: boolean) => {
      dispatch(setLoader(true));
      jobApi
        .getJobsForReportCSV({
          classification: type,
          filters,
          columns: [
            AGREED_PRICE,
            BIDDING_COMPANY_NAME,
            JOB_TYPE,
            JOB_WAIT_TIME,
            MOVEMENT_TYPE,
            REFERENCE,
            VEHICLE_TYPE,
          ],
          lang: i18n.language,
          email,
          sendAsEmail,
        })
        .then((response) => {
          if (!sendAsEmail)
            fileDownload(response.data, generateJobReportFileNameCsv());
          dispatch(setLoader(false));
        })
        .catch((err :any) => {
          console.log('err', err);
          toast.error(t('error_downloading_jobs_for_reports'));
          dispatch(setLoader(false));
        });
    },
    [dispatch, t, type, i18n.language, email]
  );

  const handleJobReportFilterDialogClose = useCallback(() => {
    setIsJobReportFilterDialogOpen(false);
  }, []);

  const handleFilterClick = useCallback(() => {
    setIsJobReportFilterDialogOpen(true);
  }, []);

  // useEffect(() => {
  //   getJobsForReport(filterState);
  // }, [filterState, getJobsForReport]);

  const columns = getJobReportColumns(t, user);

  const handleOnFiltersApply = useCallback(
    (filters: IJobReportFilter) => {
      setFilterState(filters);
      handleJobReportFilterDialogClose();
    },
    [handleJobReportFilterDialogClose]
  );

  const handleOnViewEditJobDialogClose = useCallback(() => {
    setIsViewEditJobDialogOpen(false);
    setSelectedJob(null);
  }, []);

  const onRowClick = useCallback((params: GridRowParams) => {
    const job: IJobInfo = params.row as IJobInfo;

    setSelectedJob(job);
    setIsViewEditJobDialogOpen(true);
  }, []);

  const handleOnDownloadAsCSVClick = useCallback(() => {
    downloadJobsForReport(filterState, false);
  }, [downloadJobsForReport, filterState]);

  const handleSendEmailClick = useCallback(() => {
    downloadJobsForReport(filterState, true);
  }, [downloadJobsForReport, filterState]);

  useEffect(() => {
    let timeOutId = setTimeout(() => {
      setFilterState({
        ...filterState,
        reference: searchByReference,
      });
    }, 500);

    return () => {
      clearTimeout(timeOutId);
    };
  }, [searchByReference]); //! `filterState` should not be added here, will cause infinite call of useEffect

  return (
    <>
      <ViewEditJob
        hideActionButtons
        selectedJob={selectedJob}
        type={props.type}
        open={isViewEditJobDialogOpen}
        handleClose={handleOnViewEditJobDialogClose}
      />
      <JobReportFilterDialog
        onApplyCallback={handleOnFiltersApply}
        initialJobReportFilterState={filterState}
        open={isJobReportFilterDialogOpen}
        handleClose={handleJobReportFilterDialogClose}
      />
      <Grid
        direction="column"
        container
        justifyContent="space-between"
        alignItems="stretch"
        spacing={2}
      >
        <Grid item md={3}>
          <Typography>{t('job_report')}</Typography>
        </Grid>
       
        <Grid item md={12}>
          <Grid container spacing={2} justifyContent="flex-end">
            {isUserAdmin ? (
              <>
                <Grid item md={6}></Grid>
                <Grid item md={4}>
                  <TextField
                    value={email}
                    onChange={(e) => setEmail(e.target.value)}
                    variant="outlined"
                    fullWidth
                    label={t('email_address_to_send')}
                    InputProps={{
                      endAdornment: (
                        <InputAdornment position="end">
                          <AlternateEmailIcon />
                        </InputAdornment>
                      ),
                    }}
                    InputLabelProps={{
                      style: {
                        fontWeight: 'bold',
                      },
                    }}
                  />
                </Grid>
                <Grid item sm={6} md={2}>
                  <Button
                    onClick={handleSendEmailClick}
                    color="primary"
                    fullWidth
                    variant="contained"
                  >
                    {t('send')}
                  </Button>
                </Grid>
              </>
            ) : null}
            <Grid item md={6}></Grid>
            <Grid item md={4}>
              <TextField
                value={searchByReference}
                onChange={(e) => setSearchByReference(e.target.value)}
                variant="outlined"
                fullWidth
                label={t('search_by_reference')}
                InputProps={{
                  endAdornment: (
                    <InputAdornment position="end">
                      <SearchIcon />
                    </InputAdornment>
                  ),
                }}
                InputLabelProps={{
                  style: {
                    fontWeight: 'bold',
                  },
                }}
              />
            </Grid>
            <Grid item md={2}>
              <Button
                onClick={handleFilterClick}
                fullWidth
                color="primary"
                variant="contained"
                startIcon={<FilterListIcon />}
              >
                {t('filter')}
              </Button>
            </Grid>
            <Grid item md={12}>
              <LazyTable
                columns={columns}
                onRowClick={onRowClick}
                lazyFunction={lazyGet}
                lazyFilter={filterState}
              />
            </Grid>
            <Grid item sm={6} md={4}>
              <Button
                onClick={handleOnDownloadAsCSVClick}
                fullWidth
                variant="contained"
                startIcon={<SaveIcon />}
              >
                {t('download_as_csv')}
              </Button>
            </Grid>
          </Grid>
        </Grid>
      </Grid>
    </>
  );
}
