import React, { useState, useEffect, useCallback } from "react";
import BarChart from "../../components/Barchart.js";
import DropdownMenu from "../../utils/Dropdown.js";
import SearchInput from "../../components/SearchInput.js";
import { Button, Tooltip, Grid } from "@mui/material";
import { activityChartsReport,CallAcivityReports,sessionReports,logActivityReport,getActivityReportFilterDrodowns } from "../../constants/apiEndPoints.js";
import useApiService from "../../services/apiService.js";
import Loader from "../../components/Loader.js";
import DateFilterDropdown from "../../components/DateFilterDropdown.js";
import PieChart from "../../utils/PieCharts.js";
import { FilterAltOff } from "@mui/icons-material/";
import PropTypes from "prop-types";

import BarChartStack from "../../components/BarChartStack.js";
import "./ActivityReportsCharts.css";
import { getTodayDateRange } from "../../constants/dateUtils.js";

function ActivityReports(props) {
  const [activityTypeDropDownData, setActivityTypeDropDownData] = useState([]);
  const [resultTypeDropDownData, setResultTypeDropDownData] = useState([]);
  const [deviceTypeDropDownData, setDeviceTypeDropDownData] = useState([]);
  const [loading, setLoading] = useState(false);
  const [searchTextState, setSearchTextState] = useState('');
  const [chartDiv, setChartDiv] = useState("");
  const { getApi, postApi } = useApiService();
  const [selectedRange, setSelectedRange] = useState(getTodayDateRange());
  const chartTypes = [
    { name: "pie" },
    { name: "bar" },
    { name: "error" },
    { name: "bar2" },
  ];
  const dropDowns = [
    { key: "activityType", title: "Activity Type" },
    { key: "resultType", title: "Result Type" },
    { key: "deviceType", title: "Device Type" },
  ];

  const [allFilters, setAllFilters] = useState({
    activityType: "",
    resultType: "",
    deviceType: "",
    displayChartType: "",
  });

  const [apiPayloadFilter, setApiPayloadFilter] = useState({
    EmpCode: null,
    ChartType: "Applications",
    Show: null,
    Type: allFilters.resultType,
    Device: null,
    StartDate: new Date().toISOString(),
    EndDate: new Date().toISOString(),
  });

  const handleDropDown = async (value, key) => {
    const values =
      key === dropDowns[0].key
        ? { [key]: value, resultType: null }
        : { [key]: value };
    let chart = chartTypes[1].name; 
    if (
      key === dropDowns[1].key &&
      (value === "Application(Top 10)" || value === "Calls(Top 10)")
    ) {
      chart = chartTypes[0].name; 
    }
    updateFilterState({ ...allFilters, ...values, displayChartType: chart });
  };

  // Combined initialization  
  useEffect(() => {
    const initializeData = async () => {
      fetchInitialData();
      getData(true);
    };
    initializeData();
  }, []);

  const updateFilterState = async (newState) => {
    setAllFilters((prevState) => ({
      ...prevState,
      ...newState,
    }));
  };

  const fetchInitialData = async () => {
    await fetchDataDropdown(getActivityReportFilterDrodowns, null)
    const payloadFilter = {
      ...apiPayloadFilter,
      Type: "Applications",
      ChartType: "Applications",
    };
    setAllFilters({ ...allFilters, activityType: "Applications" })
    CreateChart(true, payloadFilter);
  };

  const getData = useCallback(async (isReset, updatedFilter) => {
    setLoading(true);
    try {
      const type =
        allFilters.resultType === "All Applications" || !allFilters.resultType
          ? "Applications"
          : allFilters.resultType;
      const payloadFilter = {
        ...updatedFilter,
        Type: isReset ? "Applications" : type,
      };

      const result = await postApi(activityChartsReport, payloadFilter);

      if (result[0].Results?.length < 1) {
        renderChart(allFilters, chartTypes[2].name, null);
      } else {
        if (isReset) {
          renderChart(allFilters, null, result);
          return;
        }
        renderChart(
          allFilters,
          allFilters.resultType === "Application(Top 10)"
            ? chartTypes[0].name
            : chartTypes[1].name,
          result
        );
      }
    } catch (error) {
      console.error("Error fetching data:", error);
    } finally {
      setLoading(false);
    }
  }, [allFilters, postApi]);


  const getCallActivityData = async (updatedFilter) => {
    setLoading(true);
    try {
      const updatedFilterData = {
        ...updatedFilter,
        ChartType: null,
        Show: null,
        Type:
          allFilters.resultType == null || allFilters.resultType == "All Calls"
            ? "Calls"
            : allFilters.resultType,
        StartDate: selectedRange.startDate,
        EndDate: selectedRange.endDate,
      };
      const result = await postApi(CallAcivityReports, updatedFilterData);
      if (result[0].Results?.length < 1) {
        renderChart(allFilters, chartTypes[2].name, null);
      } else {
        renderChart(
          allFilters,
          allFilters.resultType === "Calls(Top 10)"
            ? chartTypes[0].name
            : chartTypes[1].name,
          result
        );
      }
    } catch (error) {
      console.error("Error fetching data:", error);
    } finally {
      setLoading(false);
    }
  };

  const renderChart = (allFilters, chartType, data) => {
    let chartDiv = null;
    switch (chartType) {
      case chartTypes[0].name:
        chartDiv = (
          <PieChart
            selectedValue={allFilters.activityType}
            selectedValue3={allFilters.resultType}
            data={data}
          />
        );
        break;
      case chartTypes[1].name:
        chartDiv = (
          <BarChart
            selectedValue={allFilters.activityType}
            selectedValue3={allFilters.resultType}
            data={data}
          />
        );
        break;
      case chartTypes[2].name:
        chartDiv = (
          <div className="no-data-filters">
            {" "}
            No data found for the selected filters{" "}
          </div>
        );
        break;
      case chartTypes[3].name:
        chartDiv = (
          <BarChartStack
            selectedValue={allFilters.activityType}
            selectedValue3={allFilters.resultType}
            data={data}
          />
        );
        break;
      default:
        chartDiv = (
          <BarChart
            selectedValue="Applications"
            selectedValue3="Applications"
            data={data}
          />
        );
    }
    setChartDiv(chartDiv);
  };



  const getSessionsData = async (EmpCode) => {
    setLoading(true);
    try {
      let result;
      const isLogActivity =
        allFilters.resultType == "Log In" || allFilters.resultType == "Log Out";

      if (isLogActivity) {
        const updatedDateFilter = {
          StartedOn: selectedRange.startDate,
          EndedOn: selectedRange.endDate,
          ChartType: allFilters.resultType,
          EmpCode,
        };
        result = await postApi(logActivityReport, updatedDateFilter);
      } else {
        const updatedFilterData = {
          Show: allFilters.activityType,
          Type: allFilters.resultType,
          Device: allFilters.deviceType,
          StartedOn: selectedRange.startDate,
          EndedOn: selectedRange.endDate,
          ChartType:
            allFilters.resultType === "All Sessions"
              ? null
              : allFilters.resultType,
          EmpCode,
        };
        result = await postApi(sessionReports, updatedFilterData);
      }

      if (result[0]?.Results?.length < 1) {
        renderChart(allFilters, chartTypes[2].name, null);
      } else {
        const chart =
          allFilters.resultType == null ||
            allFilters.resultType == "All Sessions"
            ? chartTypes[3].name
            : chartTypes[1].name;
        renderChart(allFilters, chart, result);
      }
    } catch (error) {
      console.error("Error fetching data:", error);
    } finally {
      setLoading(false);
    }
  };


  const handleSearch = (searchText) => {
      setSearchTextState(searchText); // Update state once
      const updatedFilterSearch = {
        ...apiPayloadFilter,
        EmpCode: searchText,
        StartDate: selectedRange.startDate || null,
        EndDate: selectedRange.endDate || null,
      };
  
      switch (allFilters.activityType) {
        case "Applications":
          getData(false, updatedFilterSearch); // Pass required params
          break;
  
        case "Calls":
          getCallActivityData(updatedFilterSearch); // Call specific data handler
          break;
  
        case "Sessions":
          getSessionsData(searchText); // Use raw searchText for sessions
          break;
  
        default:
          getData(true, updatedFilterSearch); // Default data fetch
          break;
      }
  };

  const handleDateFilterChange = (filterType, dateRange) => {
    const updatedDateFilter = {
      ...apiPayloadFilter,
      StartDate: dateRange?.startDate,
      EndDate: dateRange?.endDate,
    };
    setApiPayloadFilter(updatedDateFilter);
  };


// Activity type change handler
  useEffect(() => {
    dropDownToUse();
  }, [allFilters.activityType]);

  const dropDownToUse = () => {
    switch (allFilters.activityType) {
      case "Calls":
        setResultTypeDropDownData(activityTypeDropDownData[1]?.ActivityTypeData);
        break;
      case "Sessions":
        setResultTypeDropDownData(activityTypeDropDownData[2]?.ActivityTypeData);
        break;
      case "Applications":
        setResultTypeDropDownData(activityTypeDropDownData[0]?.ActivityTypeData);
        break;
      default:
        setResultTypeDropDownData(activityTypeDropDownData[0]?.ActivityTypeData);
        break;
    }
  };

  const fetchDataDropdown = async (apiEndpoint, setData) => {
    try {
      const response = await getApi(apiEndpoint);
      if (setData === null) {
        const transformedData = {
          ActivityType: response.ActivityType.map(activity => ({
            ParentId: activity.ParentId,
            Name: activity.ParentName,
            ActivityTypeData: activity.ActivityTypeData.map(item => ({
              Id: item.Id,
              Name: item.Name,
              Type: item.Type,
              UniqueId: item.UniqueId
            }))
          })),
          DeviceType: response.DeviceType.map(device => ({
            Name: device.Name
          }))
        };
        setActivityTypeDropDownData(transformedData.ActivityType);
        setDeviceTypeDropDownData(transformedData.DeviceType || []);
        if (transformedData.ActivityType && transformedData.ActivityType?.length > 0) {
          setResultTypeDropDownData(
            transformedData.ActivityType[0].ActivityTypeData || []);
          setAllFilters((prev) => ({
            ...prev,
            activityType: transformedData.ActivityType[0].Name,
            resultType: transformedData.ActivityType[0].ActivityTypeData[0]?.Name,
          }));
        }
      } else {
        setData(response || []);
      }
    } catch (error) {
      console.error("Error fetching dropdown data:", error);
      setData([]);
    } finally {
      setLoading(false);
    }
  };

  const CreateChart = (isReset, payloadFilter) => {
    if (isReset) {
      getData(isReset, payloadFilter);
      return;
    }
    switch (allFilters.activityType) {
      case "Sessions":
        getSessionsData(null);
        break;
      case "Calls":
        getCallActivityData(apiPayloadFilter);
        break;
      case "Applications":
        getData(false, payloadFilter);
        break;
      default:
        getData(true, payloadFilter);
    }
  };

  const OnClear = () => {
    switch (allFilters.activityType) {
      case "Applications":
        getData(apiPayloadFilter)

        break;
      case "Calls":
        getCallActivityData(apiPayloadFilter)

        break;
      case "Sessions":
        getSessionsData()

        break;
      default:
        getData(apiPayloadFilter)
        break;
    }
  }


  const resetFilters = async () => {
    setSearchTextState('');
    updateFilterState({ ...allFilters, activityType: "Applications", resultType: "All Applications" });
    setSelectedRange({ startDate: null, endDate: null });
    const payloadFilter = { ...apiPayloadFilter, Type: "Applications", StartDate: null, EndDate: null };
    CreateChart(true, payloadFilter);
  };

  const callToCreateChart = () => {
    const payloadFilter = {
      ...apiPayloadFilter,
      Type: allFilters.resultType,
      ChartType:
        allFilters.activityType === "Sessions" ? allFilters.resultType : null,
        EmpCode: searchTextState,
        StartDate: selectedRange.startDate || null,
        EndDate: selectedRange.endDate || null,
    };
    CreateChart(false, payloadFilter);
  };



  return (
    <div className="activity-reports-charts">
      <Grid container className="widgets-activity-reports">
        <Grid item>
          <DropdownMenu
            value={allFilters.activityType}
            onSelectChange={handleDropDown}
            dropDownData={activityTypeDropDownData}
            dropDownKeys={dropDowns[0]}
          />
           
        </Grid>

        <Grid item>
          <DropdownMenu
            value={allFilters.resultType}
            onSelectChange={handleDropDown}
            dropDownData={resultTypeDropDownData}
            dropDownKeys={dropDowns[1]}
          />
        </Grid>

        <Grid item style={{ display: "none" }}>
          <DropdownMenu
            value={allFilters.deviceType}
            onSelectChange={handleDropDown}
            dropDownData={deviceTypeDropDownData}
            dropDownKeys={dropDowns[2]}
          />
        </Grid>

        <Grid item>
          <DateFilterDropdown
            onChange={handleDateFilterChange}
            initialFilter="Today"
            isRangePicker={true}
            placeholder="Select Date Range"
          />
        </Grid>

        <Grid item>
          <div className="other-filters width-widget">
            {!props.employeeId && (
              <SearchInput
                placeholder="Activity Reports"
                style={{ height: "40px !important" }}
                onSearch={handleSearch}
                onClear={() => {
                  setSearchTextState("")
                  OnClear()
                }}
                textToSearch={searchTextState}
                changeHandler={(val) => {
                  setSearchTextState(val)
                }}
              />
            )}
          </div>
        </Grid>

        <Grid item>
          <Tooltip 
            title="Clear filters">
            <Button
              className="clear-btn"
              variant="outlined"
              onClick={resetFilters}
              color="error"
            >
              <FilterAltOff />
            </Button>
          </Tooltip>
        </Grid>

        <Grid item>
          <Button
            className="create-chart-btn"
            onClick={callToCreateChart}
            variant="contained"
          >
            Create Chart
          </Button>
        </Grid>
      </Grid>
      <div className="charts">
        {chartDiv}
        {loading && <Loader />}
      </div>
    </div>
  );
}
ActivityReports.propTypes = {
  employeeId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
};
ActivityReports.defaultProps = {
  employeeId: null,
};

export default ActivityReports;