import React, { useState, useEffect, useReducer, useContext } from "react";
import MainContainer from "../../components/MainContainer";
import api from "../../services/api";
import SelectField from "../../components/Report/SelectField"; 
import DatePicker1 from '../../components/Report/DatePicker'
import DatePicker2 from '../../components/Report/DatePicker'
import MTable from "../../components/Report/MTable";
import PropTypes from 'prop-types';
import Box from '@mui/material/Box';
import { AuthContext } from "../../context/Auth/AuthContext";
import { Can } from "../../components/Can";

import { Button } from "@material-ui/core";

import ReportModal from "../../components/ReportModal";
import MaterialTable from 'material-table';

import LogoutIcon from '@material-ui/icons/CancelOutlined';

import apiBroker from "../../services/apiBroker";
import fileDownload from 'js-file-download'

 
import openSocket from "socket.io-client";  

import { i18n } from "../../translate/i18n";
 

const report = [{ 'value': '1', 'label': 'Atendimento por atendentes' }, { 'value': '2', 'label': 'Usuários online/offline' }]

     
const reducerQ = (state, action) => {

  if (action.type === "DELETE_USER_STATUS") {

    const userId = action.payload;
 
    const userIndex = state.findIndex((u) => `${u.id}` === `${userId}`); 

    if (userIndex !== -1) {
      state.splice(userIndex, 1);
    }

    return [...state];
  }



  if (action.type === 'LOAD_QUERY') {

    const queries = action.payload
    const newQueries = []

    queries.forEach((query) => {

      const queryIndex = state.findIndex((q) => q.id === query.id)

      if (queryIndex !== -1) {
        state[queryIndex] = query
      }
      else {
        newQueries.push(query)
      }

    })

    return [...state, ...newQueries]
  }


  if (action.type === "UPDATE_STATUS_ONLINE") {

    let onlineUser = action.payload
    let index = -1
 
    if (onlineUser.sumOpen || onlineUser.sumClosed) {
      index = state.findIndex((e) => ((onlineUser.sumOpen && e.id === onlineUser.sumOpen.userId) || (onlineUser.sumClosed && e.id === onlineUser.sumClosed.userId)))
    }
    else {
      index = state.findIndex((e) => `${e.id}` === `${onlineUser.userId}`)
    }
 

    if (index !== -1) { 

      if (!("statusOnline" in state[index])) {
        state[index].statusOnline = onlineUser
      }
      else if ("statusOnline" in state[index]) {
        state[index].statusOnline['status'] = onlineUser.status
      }


      if ("onlineTime" in onlineUser) {

        if ("sumOnlineTime" in state[index]) {
          state[index].sumOnlineTime['sum'] = (onlineUser.onlineTime).split(" ")[1]
        }
        else if (!("sumOnlineTime" in state[index])) {
          state[index].sumOnlineTime = { userId: onlineUser.userId, sum: (onlineUser.onlineTime).split(" ")[1] }
        }
      }


      if (onlineUser.sumOpen) {

        if ("sumOpen" in state[index]) { 
          state[index].sumOpen['count'] = onlineUser.sumOpen.count
        } else if (!("sumOpen" in state[index])) { 
          state[index].sumOpen = onlineUser.sumOpen
        }

      }

      if (onlineUser.sumClosed) {

        if ("sumClosed" in state[index]) { 
          state[index].sumClosed['count'] = onlineUser.sumClosed.count
        } else if (!("sumClosed" in state[index])) { 
          state[index].sumClosed = onlineUser.sumClosed
        }

      }


    }
    return [...state]

  }



  if (action.type === "RESET") {
    return [];
  }

}



const reducer = (state, action) => {

  if (action.type === "LOAD_USERS") {
    const users = action.payload;
    const newUsers = [];

    users.forEach((user) => {
      const userIndex = state.findIndex((u) => u.id === user.id);
      if (userIndex !== -1) {
        state[userIndex] = user;
      } else {
        newUsers.push(user);
      }
    });

    return [...state, ...newUsers];
  }

  if (action.type === "DELETE_USER") {
    const userId = action.payload;

    const userIndex = state.findIndex((u) => u.id === userId);
    if (userIndex !== -1) {
      state.splice(userIndex, 1);
    }
    return [...state];
  }

  if (action.type === "RESET") {
    return [];
  }
};




function Item(props) {
  const { sx, ...other } = props;
  return (
    <Box
      sx={{
        bgcolor: (theme) => (theme.palette.mode === 'dark' ? '#101010' : '#fff'),
        color: (theme) => (theme.palette.mode === 'dark' ? 'grey.300' : 'grey.800'),
        border: '1px solid',
        borderColor: (theme) =>
          theme.palette.mode === 'dark' ? 'grey.800' : 'grey.300',
        p: 1,
        m: 1,
        borderRadius: 2,
        fontSize: '0.875rem',
        fontWeight: '700',
        ...sx,
      }}
      {...other}
    />
  );
}

Item.propTypes = {
  sx: PropTypes.oneOfType([
    PropTypes.arrayOf(
      PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool]),
    ),
    PropTypes.func,
    PropTypes.object,
  ]),
};



let columnsData = [
  { title: `${i18n.t("reports.listColumns.column1_1")}`, field: 'whatsapp.name' },
  { title: `${i18n.t("reports.listColumns.column1_2")}`, field: 'user.name' },
  { title: `${i18n.t("reports.listColumns.column0_4")}`, field: 'contact.number' },
  { title: `${i18n.t("reports.listColumns.column0_3")}`, field: 'contact.name' },
  { title: `${i18n.t("reports.listColumns.column1_5")}`, field: 'queue.name' },

  { title: 'Status', field: 'status' },

  { title: `${i18n.t("reports.listColumns.column1_7")}`, field: 'createdAt' },
  {title: `${i18n.t("reports.listColumns.column1_8")}`, field: 'updatedAt'},
  { title: `${i18n.t("reports.listColumns.column1_9")}`, field: 'statusChatEnd' }];


const Report = () => {  

  const { user: userA } = useContext(AuthContext);

  //-------- 
  const [searchParam] = useState("");

  const [loading, setLoading] = useState(false);
  const [hasMore, setHasMore] = useState(false);
  const [pageNumberTickets, setTicketsPageNumber] = useState(1);
  const [totalCountTickets, setTotalCountTickets] = useState(0);



  const [pageNumber, setPageNumber] = useState(1);
  const [users, dispatch] = useReducer(reducer, []); 
  const [startDate, setDatePicker1] = useState(new Date())
  const [endDate, setDatePicker2] = useState(new Date())
  const [userId, setUser] = useState(null)
  const [query, dispatchQ] = useReducer(reducerQ, []) 
  

  const [reportOption, setReport] = useState('1')
  const [reporList,] = useState(report)
  const [profile, setProfile] = useState('')
  const [dataRows, setData] = useState([]);

  const [onQueueStatus, setOnQueueProcessStatus] = useState(undefined)
  const [csvFile, setCsvFile] = useState()

 



  useEffect(() => {
    dispatch({ type: "RESET" });
    dispatchQ({ type: "RESET" })
    setTicketsPageNumber(1)
    setPageNumber(1);
  }, [searchParam, profile]);



  useEffect(() => {
    //setLoading(true); 

    const delayDebounceFn = setTimeout(() => {

      const fetchUsers = async () => {
        try {
  
          const { data } = await api.get("/users/", {
            params: { searchParam, pageNumber, profile },
          });

          dispatch({ type: "LOAD_USERS", payload: data.users }); 
          //setLoading(false);  

        } catch (err) {
          console.log(err);
        }
      };

      fetchUsers();

    }, 500);
    return () => clearTimeout(delayDebounceFn);
  }, [searchParam, pageNumber, reportOption, profile]);



  useEffect(() => {

    //setLoading(true);

    const delayDebounceFn = setTimeout(() => {

      setLoading(true);
      const fetchQueries = async () => {
        try {

          if (reportOption === '1') {

            const { data } = await api.get("/reports/", { params: { userId, startDate, endDate, pageNumber: pageNumberTickets }, }); 
          
            dispatchQ({ type: "LOAD_QUERY", payload: data.tickets }); 

            setHasMore(data.hasMore);
            setTotalCountTickets(data.count)
            setLoading(false);


          }
          else if (reportOption === '2') {

            const dataQuery = await api.get("/reports/user/services", { params: { userId, startDate, endDate }, });
            dispatchQ({ type: "RESET" })
            dispatchQ({ type: "LOAD_QUERY", payload: dataQuery.data });  
            //setLoading(false);   

          }

        } catch (err) {
          console.log(err);
        }
      };

      fetchQueries();

    }, 500);
    return () => clearTimeout(delayDebounceFn);

  }, [userId, startDate, endDate, reportOption, pageNumberTickets, totalCountTickets]);


  // Get from child 1
  const datePicker1Value = (data) => {

    setDatePicker1(data)
  }

  // Get from child 2
  const datePicker2Value = (data) => {

    setDatePicker2(data)
  }

  // Get from child 3
  const textFieldSelectUser = (data) => {

    setUser(data)
  }




  // Get from report option
  const reportValue = (data) => {

    setReport(data)
 
  }

  useEffect(() => {

    if (reportOption === '1') {
      setProfile('')
    }
    else if (reportOption === '2') {
      setProfile('user')
    }

  }, [reportOption])



  useEffect(() => {

    const delayDebounceFn = setTimeout(() => {

      const fetchReportOnQueue = async () => {
        try {

          const queryOnQueue = await apiBroker.get("/reports/status/query/onqueue", {
            params: {
              adminId: userA.id,
              baseURL: process.env.REACT_APP_BACKEND_URL_PRIVATE,
              identifier: 'csv'
            }
          });


          if (queryOnQueue.data) {
            setCsvFile(queryOnQueue.data.app.file)
            setOnQueueProcessStatus(queryOnQueue.data.app.status)
          }
          else {
            setOnQueueProcessStatus('empty')
          }
 

        } catch (err) {
          console.log(err);
        }
      };

      fetchReportOnQueue();

    }, 500);
    return () => clearTimeout(delayDebounceFn);

  }, [ userA ])
 

  const handleCSVDownload = async () => {   
    
    setOnQueueProcessStatus('downloading')

    try {

      let res = await apiBroker.get(`/reports/download/${csvFile}`, { responseType: 'blob' });

      if (res) {
        fileDownload(res.data, `${csvFile}`); 
        setOnQueueProcessStatus('empty')  
      }
      

    } catch (err) {
      console.log(err);
    }
     

  }

 

  const handleCSVMessages = () => {

    const fetchQueries = async () => {

      try {

        // const dataQuery = await api.get("/reports/messages", { params: { userId, startDate, endDate }, });

        const querySavedOnQueue = await apiBroker.post("/reports/messages",
          {
            app: {
              adminId: userA.id,
              baseURL: process.env.REACT_APP_BACKEND_URL_PRIVATE,
              frontURL: process.env.REACT_APP_FRONTEND_URL,
              identifier: 'csv'
            },
            query_params: {
              userId: userId,
              startDate: startDate,
              endDate: endDate
            }
          }); 

        const onQueueStatus = querySavedOnQueue.data.queueStatus

        setOnQueueProcessStatus(onQueueStatus) 

      } catch (err) {
        console.log(err);
      }
    };

    fetchQueries();

  }

 

  useEffect(() => {

    const socket = openSocket(process.env.REACT_APP_BACKEND_URL);

    socket.on("queryOnQueueStatus", (data) => {
      if (data.action === 'update') {

        if (String(data.queryOnQueue.adminId) === String(userA.id)) {

          setCsvFile(data.queryOnQueue.file)
          setOnQueueProcessStatus(data.queryOnQueue.queueStatus)

        }

      }
    })

    if (reportOption === '2') {
 

      socket.on("onlineStatus", (data) => {

        let date = new Date().toLocaleDateString('pt-BR').split('/')
        let dateToday = `${date[2]}-${date[1]}-${date[0]}`

        if (data.action === "logout" || (data.action === "update" &&
          ((`${startDate}` === `${endDate}`) && (`${endDate}` === `${dateToday}`) && (`${startDate}` === `${dateToday}`)))) { 

          dispatchQ({ type: "UPDATE_STATUS_ONLINE", payload: data.userOnlineTime });

        }
        else if (data.action === "delete") {
          dispatchQ({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime });
        }

      });

      socket.on("user", (data) => {

        if (data.action === "delete") { 
          dispatch({ type: "DELETE_USER", payload: +data.userId });
        }
      }); 
 

    }
    else if (reportOption === "1") {
      dispatchQ({ type: "RESET" })
      setTicketsPageNumber(1)
    }

    return () => {
      socket.disconnect();
    };


  }, [reportOption, startDate, endDate, userId, userA]);
 

  useEffect(() => {    

    setData(query.map((column) => { return { ...column } }))


  }, [query])

  const handleLogouOnlineUser = async (userId) => {
    try {
      await api.get(`/users/logout/${userId}`);
      //toast.success(("Desloged!"));
      //handleDeleteRows(scheduleId) 
    } catch (err) {
      // toastError(err);
    }


  };


  const loadMore = () => {
    setTicketsPageNumber((prevState) => prevState + 1);
  };

  const handleScroll = (e) => {

    if (!hasMore || loading) return;

    const { scrollTop, scrollHeight, clientHeight } = e.currentTarget; 

    if (scrollHeight - (scrollTop + 1) < clientHeight) {

      loadMore();
 
    }
  };


  const renderSwitch = (param) => {
    switch (param) {
      case 'empty':
        return (
          <>
            <Button
              disabled={query && query.length > 0 ? false : true}
              variant="contained"
              color="primary"
              onClick={(e) => {
                handleCSVMessages()
              }}
            >
              {"CSV ALL"}
            </Button>
          </>);

      case 'pending' || 'processing':
        return (
          <>
            <span>PROCESSING...</span>
          </>);

      case 'success':
        return (
          <>
            <Button
              variant="contained"
              color="primary" 
              onClick={(e) => {
                handleCSVDownload(e)
              }}
            >
              {'CSV DOWNLOAD'}
            </Button>
          </>);
        case 'downloading':
          return (
            <>
              <span>DOWNLOADING...</span>
            </>);
  

      default:
        return (<><span>WAITING...</span></>);
    }
  }


  return (

    <Can
      role={userA.profile}
      perform="ticket-report:show"
      yes={() => (

        <MainContainer>
          <Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)' }}>

            <Item><SelectField func={textFieldSelectUser} emptyField={true} header={i18n.t("reports.user")} currencies={users.map((obj) => {
              return { 'value': obj.id, 'label': obj.name }
            })} /></Item>

            <Item><DatePicker1 func={datePicker1Value} minDate={false} startEmpty={false} title={i18n.t("reports.dateStart")} /></Item>
            <Item><DatePicker2 func={datePicker2Value} minDate={false} startEmpty={false} title={i18n.t("reports.dateEnd")} /></Item>

            <Item sx={{ display: 'grid', gridColumn: '4 / 5', }}>

              <ReportModal currencies={reporList} func={reportValue} reportOption={reportOption} />

              <div style={{ margin: '2px' }}></div>

              {reportOption === '1' &&
                <div>
                  {renderSwitch(onQueueStatus)}
                </div>

              }


            </Item>

          </Box>

          <Box sx={{
            display: 'grid',
          }}>

            <Item sx={{ gridColumn: '1', gridRow: 'span 1' }}>

              {reportOption === '1' && 

                <>

                  <MTable data={query}
                    columns={columnsData}
                    hasChild={true}
                    removeClickRow={false}

                    handleScroll={handleScroll}

                    table_title={i18n.t("reports.listTitles.title1_1")} />

                </>

              }
              {reportOption === '2' &&

                <MaterialTable

                  localization={{

                    header: {
                      actions: 'Deslogar'
                    },

                  }}

                  title={i18n.t("reports.listTitles.title3_1")}
                  columns={
                    [

                      // { title: 'Foto', field: 'ticket.contact.profilePicUrl', render: rowData => <img src={rowData['ticket.contact.profilePicUrl']} alt="imagem de perfil do whatsapp" style={{ width: 40, borderRadius: '50%' }} /> },
                      { title: 'Nome', field: 'name', cellStyle: { whiteSpace: 'nowrap' }, },

                      {
                        title: 'Status', field: 'statusOnline.status',

                        cellStyle: (e, rowData) => {

                          if (rowData['statusOnline'] && rowData['statusOnline'].status) {

                            if (rowData['statusOnline'].status === 'offline') {

                              return { color: "red" };
                            }
                            else if (rowData['statusOnline'].status === 'online') {
                              return { color: "green" };
                            }
                            else if (rowData['statusOnline'].status === 'logout...') {
                              return { color: "orange" };
                            }
                            else if (rowData['statusOnline'].status === 'waiting...') {
                              return { color: "orange" };
                            }
                          }


                        },

                      },

                      { title: 'Tempo online', field: 'sumOnlineTime.sum' },
                      { title: `${i18n.t("reports.dateStart")}`, field: 'startDate' },
                      { title: `${i18n.t("reports.dateStart")}`, field: 'endDate' },
                      { title: 'Em atendimento', field: 'sumOpen.count' },
                      { title: 'Finalizado', field: 'sumClosed.count' },

                    ]
                  }
                  data={dataRows} 

                  actions={[
                    (rowData) => {

                      if (rowData.statusOnline &&
                        rowData.statusOnline['status'] &&
                        rowData.statusOnline['status'] === 'online') {


                        return {
                          icon: LogoutIcon,
                          tooltip: 'deslogar',
                          disable: false,
                          onClick: (event, rowData) => {  
                            handleLogouOnlineUser(rowData.id)
                          }
                        }


                      }
                    }
                  ]}


                  options={
                    {
                      search: true,
                      selection: false,
                      paging: false,
                      padding: 'dense',
                      sorting: true, 
                      searchFieldStyle: {
                        width: 300,
                      },

                      pageSize: 20,
                      headerStyle: {
                        position: "sticky",
                        top: "0"
                      },
                      maxBodyHeight: "400px",

                      rowStyle: {
                        fontSize: 14,
                      } 

                    }}
                />

              }

            </Item>

          </Box>
        </MainContainer>

      )}
    />
  )
};

export default Report;