/* eslint-disable react/no-array-index-key */
/* eslint-disable react/jsx-key */
/* eslint no-underscore-dangle: ["error", { "allow": [ "_id"] }] */
import React, { useEffect, useState } from 'react';
import Box from '@mui/material/Box';
import { DataGrid, GridToolbarContainer, GridToolbarExport } from '@mui/x-data-grid';
// import { useNavigate } from 'react-router-dom';
import {
  Autocomplete,
  Stack,
  Typography,
  Card,
  CardContent,
  TextField,
  Grid,
  CircularProgress,
  Button,
  CardActions,
  MenuItem,
  Divider
} from '@mui/material';
import { Formik, Field } from 'formik';
import { useDispatch, useSelector } from 'react-redux';
import 'react-datepicker/dist/react-datepicker.css';
import LoadingSkeleton from '../../utils/LoadingSkeleton';
import NoRowsOverlay from '../../utils/NoRowOverlay';
import ReportAction from '../../store/actions/ReportAction';
import { ValidateReportDepartment, ValidateReportClient } from '../../assets/validation';

const printStyle = {
  '@media print': {
    '@page': {
      size: 'landscape'
    },
    '.MuiDataGrid-main': {
      overflow: 'scroll',
      width: '1100px',
      '.MuiDataGrid-root': {
        fontSize: '12px !important'
      },
      '.MuiDataGrid-columnHeader': {
        fontSize: '12px !important',
        minWidth: '150px !important',
        width: 'auto !important',
        textAlign: 'center !important'
      },
      '.MuiDataGrid-cell': {
        fontSize: '12px !important',
        padding: '6px !important',
        minWidth: '150px !important',
        width: 'auto !important',
        textAlign: 'center  !important',
        '.MuiTypography-root': {
          fontSize: '12px !important'
        }
      }
    }
  }
};

function CustomToolbar() {
  return (
    <Box
      className="tableTopWrap page__title"
      sx={{
        borderBottom: '1px solid rgba(0,0,0,0.1)',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'flex-end',
        p: 3
      }}
    >
      <GridToolbarContainer>
        <GridToolbarExport
          csvOptions={{
            fileName: 'financial-year-report',
            utf8WithBom: true
          }}
          printOptions={{
            disableToolbarButton: true
            // allColumns: true,
            // hideFooter: true,
            // hideToolbar: true,
            // bodyClassName: 'cardWrapper'
          }}
          variant="contained"
          size="small"
        />
      </GridToolbarContainer>
    </Box>
  );
}

export default function FinancialYearReport() {
  const [paginationModel, setPaginationModel] = useState({
    page: 0,
    pageSize: 10
  });

  const [sortInfo, setSortInfo] = useState({
    sort_by: null,
    order_by: null
  });

  // const navigate = useNavigate();
  const [rowCountState, setRowCountState] = useState(0);
  const [clientData, setClientData] = useState({});
  const [deptData, setDeptData] = useState([]);
  const [type, setType] = useState(1);
  const dispatch = useDispatch();

  const { clientReportData, departmentReportData, isLoading, filterData } = useSelector(
    (state) => state.report
  );

  const { clients, currency, departments, financialYears } = filterData;

  const initialValues = {
    client: [],
    department: null,
    financial_year: '',
    currency: null
  };

  useEffect(() => {
    dispatch(ReportAction.getFilters());
  }, [dispatch]);

  useEffect(() => {
    if (clientReportData) {
      if (clientReportData.data) {
        setClientData(clientReportData.data);
      } else {
        setClientData([]);
      }
      setRowCountState((prevRowCountState) =>
        clientReportData?.pagination?.total !== undefined
          ? clientReportData?.pagination?.total
          : prevRowCountState
      );
    }
  }, [clientReportData]);

  useEffect(() => {
    if (departmentReportData && departmentReportData?.data) {
      setDeptData(departmentReportData.data);
    } else {
      setDeptData([]);
    }
  }, [departmentReportData]);

  const columns = [
    {
      field: 'client_name',
      headerName: 'Client Name',
      flex: 1,
      sortable: false
    },
    {
      field: 'raised',
      headerName: 'Raised Count | Cost',
      flex: 1,
      sortable: false
    },
    {
      field: 'overdue',
      headerName: 'Overdue Count | Cost',
      flex: 1,
      sortable: false
    },
    {
      field: 'paid',
      headerName: 'Paid Count | Cost',
      flex: 1,
      sortable: false
    },
    {
      field: 'partial',
      headerName: 'Partial Payment Count | Cost',
      flex: 1,
      sortable: false
    },
    {
      field: 'pending',
      headerName: 'Pending Count | Cost',
      flex: 1,
      sortable: false
    },
    {
      field: 'write_off',
      headerName: 'Write-Off Count | Cost',
      flex: 1,
      sortable: false
    }
  ];
  const deptColumns = [
    {
      field: 'departments',
      headerName: 'Departments Name',
      flex: 1,
      sortable: false
    },
    {
      field: 'raised',
      headerName: 'Raised Count | Cost',
      flex: 1,
      sortable: false
    },
    {
      field: 'overdue',
      headerName: 'Overdue Count | Cost',
      flex: 1,
      sortable: false
    },
    // {
    //   field: 'manual',
    //   headerName: 'Manual Count | Cost',
    //   flex: 1,
    //   sortable: false
    // },
    {
      field: 'paid',
      headerName: 'Paid Count | Cost',
      flex: 1,
      sortable: false
    },
    {
      field: 'partial',
      headerName: 'Partial Payment Count | Cost',
      flex: 1,
      sortable: false
    },
    {
      field: 'pending',
      headerName: 'Pending Count | Cost',
      flex: 1,
      sortable: false
    },
    {
      field: 'write_off',
      headerName: 'Write-Off Count | Cost',
      flex: 1,
      sortable: false
    }
  ];

  const handleSortModelChange = React.useCallback((sortModel) => {
    // Here you save the data you need from the sort model
    if (sortModel.length > 0) {
      const { field, sort } = sortModel[0];
      const sortData = {
        sort_by: field,
        order_by: sort
      };
      setSortInfo(sortData);
      const newValues = { ...initialValues, ...paginationModel, ...sortData };
      if (type === 1) {
        dispatch(ReportAction.clientBasedReport(newValues));
      } else {
        dispatch(ReportAction.deptBasedReport(newValues));
      }
    }
    // eslint-disable-next-line
  }, []);

  const handlePageModelChange = React.useCallback((pageOption) => {
    setPaginationModel(pageOption);
    const newValues = { ...initialValues, ...pageOption, ...sortInfo };
    if (type === 1) {
      dispatch(ReportAction.clientBasedReport(newValues));
    } else {
      dispatch(ReportAction.deptBasedReport(newValues));
    }
  }, []);

  return (
    <Box sx={{ mb: 3 }} className="cardWrapper">
      <div className="pageTitleWrap">
        <Stack direction="row" spacing={1} alignItems="center">
          <Typography component="h2" variant="h2">
            Financial Year Report
          </Typography>
        </Stack>
      </div>
      <Card className="pageTitleWrap" sx={{ mb: 3 }}>
        <Formik
          initialValues={initialValues}
          validationSchema={type === 1 ? ValidateReportClient : ValidateReportDepartment}
          onSubmit={(values, { setErrors, setSubmitting }) => {
            const newValues = { ...values };
            console.log(newValues, 'newValues');
            if (newValues.currency && newValues.currency._id) {
              newValues.currency = newValues.currency._id;
            }
            delete newValues.type;
            if (type === 1) {
              delete newValues.department;
              const newClientId = newValues.client.map((item) => item._id);
              newValues.client = newClientId;
              dispatch(ReportAction.clientBasedReport(newValues, setErrors, setSubmitting));
            } else {
              delete newValues.client;
              const newDepartId = newValues.department?._id;
              newValues.department = [newDepartId];
              dispatch(ReportAction.deptBasedReport(newValues, setErrors, setSubmitting));
            }
          }}
        >
          {({
            errors,
            touched,
            values,
            handleBlur,
            handleChange,
            handleSubmit,
            isSubmitting,
            handleReset,
            setFieldValue
          }) => (
            <form onSubmit={handleSubmit} autoComplete="off">
              <CardContent>
                <Grid container columnSpacing={3} rowSpacing={2}>
                  <Grid item md={3} lg={3}>
                    <TextField
                      id="type"
                      fullWidth
                      size="small"
                      label="Type of Report"
                      name="type"
                      margin="normal"
                      select
                      value={type}
                      onChange={(e) => {
                        handleChange(e);
                        setType(e.target.value);
                      }}
                      onBlur={handleBlur}
                      required={false}
                      InputLabelProps={{ required: true }}
                    >
                      <MenuItem value={1}>Client Wise</MenuItem>
                      <MenuItem value={2}>Department Wise</MenuItem>
                    </TextField>
                  </Grid>
                </Grid>
                <Divider sx={{ mt: 2, mb: 3 }} />
                <Grid container columnSpacing={3} rowSpacing={2}>
                  {type === 1 ? (
                    <Grid item md={3} lg={3}>
                      <Field
                        className="filter"
                        name="client"
                        value={values.client}
                        component={Autocomplete}
                        filterSelectedOptions
                        isOptionEqualToValue={(option, value) => option._id === value._id}
                        fullWidth
                        multiple
                        size="small"
                        options={clients ?? []}
                        onChange={(e, newvalue) => {
                          if (newvalue) {
                            setFieldValue('client', newvalue);
                          }
                        }}
                        sx={{ mt: 0 }}
                        getOptionLabel={(option) => option.name}
                        renderOption={(props, option) => {
                          return (
                            <li {...props} key={option._id}>
                              {option.name}
                            </li>
                          );
                        }}
                        renderInput={(params) => (
                          <TextField
                            {...params}
                            label="Client"
                            placeholder="Search Client"
                            variant="outlined"
                            margin="none"
                            required={false}
                            InputLabelProps={{ required: true }}
                            error={errors.client && touched.client}
                            helperText={errors.client && touched.client && errors.client}
                          />
                        )}
                      />
                    </Grid>
                  ) : (
                    ''
                  )}
                  {type === 2 ? (
                    <Grid item md={3} lg={3}>
                      <Field
                        name="department"
                        component={Autocomplete}
                        value={values.department}
                        className="filter"
                        fullWidth
                        size="small"
                        isOptionEqualToValue={(option, value) => option._id === value._id}
                        filterSelectedOptions
                        // multiple
                        options={departments ?? []}
                        onChange={(e, newvalue) => {
                          if (newvalue) {
                            setFieldValue('department', newvalue);
                          } else {
                            setFieldValue('department', null);
                          }
                        }}
                        sx={{ mt: 0 }}
                        getOptionLabel={(option) => option.name}
                        renderOption={(props, option) => {
                          return (
                            <li {...props} key={option._id}>
                              {option.name}
                            </li>
                          );
                        }}
                        renderInput={(params) => (
                          <TextField
                            {...params}
                            label="Department"
                            placeholder="Search Departments"
                            variant="outlined"
                            margin="none"
                            required={false}
                            InputLabelProps={{ required: true }}
                            error={errors.department && touched.department}
                            helperText={
                              errors.department && touched.department && errors.department
                            }
                          />
                        )}
                      />
                    </Grid>
                  ) : (
                    ''
                  )}

                  <Grid item md={3} lg={3}>
                    <Field
                      component={Autocomplete}
                      className="filter"
                      name="financial_year"
                      value={values.financial_year}
                      fullWidth
                      size="small"
                      isOptionEqualToValue={(option, value) => option === value}
                      filterSelectedOptions
                      options={financialYears ?? []}
                      onChange={(e, newvalue) => {
                        if (newvalue) {
                          setFieldValue('financial_year', newvalue);
                        } else {
                          setFieldValue('financial_year', null);
                        }
                      }}
                      sx={{ mt: 0 }}
                      getOptionLabel={(option) => option}
                      renderOption={(props, option) => {
                        return (
                          <li {...props} key={option}>
                            {option}
                          </li>
                        );
                      }}
                      renderInput={(params) => (
                        <TextField
                          {...params}
                          name="financial_year"
                          label="Financial Years"
                          placeholder="Search Year"
                          variant="outlined"
                          margin="none"
                          required={false}
                          InputLabelProps={{ required: true }}
                          error={errors.financial_year && touched.financial_year}
                          helperText={
                            errors.financial_year && touched.financial_year && errors.financial_year
                          }
                        />
                      )}
                    />
                  </Grid>
                  <Grid item md={3} lg={3}>
                    <Field
                      className="status"
                      name="currency"
                      value={values.currency}
                      component={Autocomplete}
                      fullWidth
                      size="small"
                      isOptionEqualToValue={(option, value) => option._id === value._id}
                      filterSelectedOptions
                      options={currency ?? []}
                      onChange={(e, newvalue) => {
                        if (newvalue) {
                          setFieldValue('currency', newvalue);
                        } else {
                          setFieldValue('currency', null);
                        }
                      }}
                      sx={{ mt: 0 }}
                      getOptionLabel={(option) => option.name}
                      renderOption={(props, option) => {
                        return (
                          <li {...props} key={option._id}>
                            {option.name}
                          </li>
                        );
                      }}
                      renderInput={(params) => (
                        <TextField
                          {...params}
                          label="Currency"
                          placeholder="Search Currency"
                          variant="outlined"
                          margin="none"
                          required={false}
                          InputLabelProps={{ required: true }}
                          error={errors.currency && touched.currency}
                          helperText={errors.currency && touched.currency && errors.currency}
                        />
                      )}
                    />
                  </Grid>
                </Grid>
              </CardContent>
              <CardActions sx={{ justifyContent: 'center', p: 3 }}>
                <Button
                  type="submit"
                  className="save__btn"
                  variant="contained"
                  color="secondary"
                  // fullWidth
                  disabled={isSubmitting}
                  size="medium"
                >
                  {isSubmitting ? <CircularProgress size={20} /> : 'Get Report'}
                </Button>
                <Button
                  type="button"
                  className="cancel__btn"
                  variant="contained"
                  // fullWidth
                  color="info"
                  size="medium"
                  onClick={() => {
                    handleReset();
                    setDeptData([]);
                    setClientData([]);
                  }}
                >
                  Clear
                </Button>
              </CardActions>
            </form>
          )}
        </Formik>
      </Card>
      <Box sx={{ bgcolor: 'white' }} className="dataTable__wrap reportWrap">
        {clientData && clientData.length > 0 && (
          <DataGrid
            rows={clientData}
            getRowId={(row) => row.client_name}
            rowCount={rowCountState}
            columns={columns}
            initialState={{
              pagination: {
                paginationModel: {
                  pageSize: 10
                }
              }
            }}
            autoHeight
            sx={{ minHeight: 650, '--DataGrid-overlayHeight': '50vh', ...printStyle }}
            disableColumnFilter
            disableColumnMenu
            disableColumnSorting
            rowHeight={50}
            slots={{
              toolbar: CustomToolbar,
              loadingOverlay: LoadingSkeleton,
              noRowsOverlay: NoRowsOverlay
            }}
            slotProps={{
              toolbar: {
                exportButton: {
                  csvOptions: {
                    fieldSeparator: ',',
                    fields: columns.map((column) => ({
                      label: column.headerName,
                      value: column.valueGetter
                        ? (params) => column.valueGetter(params)
                        : (params) => params.value
                    }))
                  }
                }
              }
            }}
            pageSizeOptions={[10, 25, 50, 100]}
            paginationModel={paginationModel}
            paginationMode="server"
            onPaginationModelChange={handlePageModelChange}
            sortingMode="server"
            onSortModelChange={handleSortModelChange}
            disableRowSelectionOnClick
            loading={isLoading}
          />
        )}
      </Box>
      <Box sx={{ bgcolor: 'white' }} className="dataTable__wrap">
        {deptData && deptData.length > 0 && (
          <DataGrid
            rows={deptData}
            getRowId={(row) => row.departments}
            rowCount={rowCountState}
            columns={deptColumns}
            autoHeight
            sx={{ '--DataGrid-overlayHeight': '30vh', ...printStyle }}
            disableColumnFilter
            rowHeight={50}
            hideFooter
            hideFooterPagination
            disableColumnMenu
            disableColumnSorting
            slots={{
              toolbar: CustomToolbar,
              loadingOverlay: LoadingSkeleton,
              noRowsOverlay: NoRowsOverlay
            }}
            slotProps={{
              toolbar: {
                exportButton: {
                  csvOptions: {
                    fieldSeparator: ',',
                    fields: columns.map((column) => ({
                      label: column.headerName,
                      value: column.valueGetter
                        ? (params) => column.valueGetter(params)
                        : (params) => params.value
                    }))
                  }
                }
              }
            }}
            disableRowSelectionOnClick
            loading={isLoading}
          />
        )}
      </Box>
    </Box>
  );
}
