/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import React, { useReducer } from "react";
import { NavLink, useNavigate } from "react-router-dom";
import { sortBy, filter, isEmpty, map, upperCase, groupBy } from "lodash";
import closeIcon from "Images/close.svg";
import { getUserProfile, setUserProfile } from "Utils/appState";
import { fetchApi } from "Utils/fetchAPI";
import Select from "react-select";
import {
  hasAccessToTab,
  isAuditor,
  isKeyAdmin,
  isSystemAdmin,
  getBaseUrl,
  isKMSAuditor
} from "Utils/XAUtils";
import ResourceTagContent from "./ResourceTagContent";
import { toast } from "react-toastify";

function reducer(state, action) {
  switch (action.type) {
    case "SELECTED_SERVCIEDEF_DATA":
      return {
        ...state,
        selectedServiceDef: action.selectedServiceDef
      };
    default:
      throw new Error();
  }
}

export const SideBarBody = (props) => {
  const {
    loader,
    activeMenu,
    isDrawerOpen,
    accountDrawer,
    allServicesDefData,
    servicesDefData,
    tagServicesDefData,
    allServicesData,
    servicesData,
    tagServicesData,
    sideBarDispatch
  } = props;
  const [keyState, dispatch] = useReducer(reducer, {
    selectedServiceDef: []
  });

  const { selectedServiceDef } = keyState;

  const isKMSRole = isKeyAdmin() || isKMSAuditor();
  const navigate = useNavigate();
  const apiUrl = getBaseUrl() + "apidocs/swagger.html";

  const serviceSelectThemes = (theme) => {
    return {
      ...theme,
      colors: {
        ...theme.colors,
        text: "#444444",
        primary25: "#0b7fad;",
        primary: "#0b7fad;"
      }
    };
  };

  const serviceSelectCustomStyle = {
    option: (provided, state) => ({
      ...provided,
      color: state.isFocused ? "white" : "black"
    })
  };

  const getCurrentServiceDefs = (value) => {
    let filterServiceDef = [];
    value.filter((servicedefData) => {
      return Object.keys(groupBy(servicesData, "type"))?.map((servicedef) => {
        if (servicedefData.value == servicedef) {
          return filterServiceDef.push(servicedefData);
        }
      });
    });
    if (filterServiceDef?.length == 0 && value?.length > 0) {
      handleServiceDefChange(filterServiceDef);
    } else {
      return filterServiceDef;
    }
  };

  const serviceDefOptions = () => {
    let filterServiceDef = [];
    allServicesDefData?.filter((servicedefData) => {
      return Object.keys(groupBy(servicesData, "type"))?.map((servicedef) => {
        if (servicedefData.name == servicedef) {
          return filterServiceDef.push(servicedefData);
        }
      });
    });
    return sortBy(
      map(filterServiceDef, function (serviceDef) {
        return {
          value: serviceDef.name,
          label: upperCase(serviceDef.name)
        };
      }),
      "value"
    );
  };

  const handleServiceDefChange = (value) => {
    if (value.length !== 0) {
      let selectedServiceDefs = [];
      let selectedService = [];

      value.map((serviceDef) => {
        allServicesDefData?.filter((servicedefs) => {
          if (servicedefs.name === serviceDef.value) {
            selectedServiceDefs.push(servicedefs);
          }
        });
      });

      value.map((serviceDef) => {
        allServicesData.filter((services) => {
          if (services.type === serviceDef.value) {
            selectedService.push(services);
          }
        });
      });

      sideBarDispatch({
        type: "SERVICEDEF_DATA",
        allserviceDefData: filter(
          allServicesDefData,
          (serviceDef) => serviceDef.name !== "tag"
        ),
        serviceDefData: sortBy(
          filter(
            selectedServiceDefs,
            (serviceDef) => serviceDef.name !== "tag"
          ),
          "id"
        ),
        tagServiceDefData: tagServicesDefData
      });
    }

    if (value.length == 0) {
      let filterSelectedService = [];
      if (isKMSRole) {
        filterSelectedService = filter(allServicesData, ["type", "kms"]);
      } else {
        filterSelectedService = filter(
          allServicesData,
          (service) => service.type !== "tag" && service.type !== "kms"
        );
      }
      sideBarDispatch({
        type: "SERVICEDEF_DATA",
        allserviceDefData: allServicesDefData,
        serviceDefData: sortBy(
          filter(allServicesDefData, (serviceDef) => serviceDef.name !== "tag"),
          "id"
        ),
        tagServiceDefData: tagServicesDefData
      });
      sideBarDispatch({
        type: "SERVICES_DATA",
        allServiceData: allServicesData,
        serviceData: filterSelectedService,
        tagServiceData: tagServicesData
      });
    }
    dispatch({
      type: "SELECTED_SERVCIEDEF_DATA",
      selectedServiceDef: value
    });
  };

  const checkKnoxSSO = async (e) => {
    e.preventDefault();
    const userProfile = getUserProfile();
    let checkKnoxSSOresp = {};
    try {
      checkKnoxSSOresp = await fetchApi({
        url: "plugins/checksso",
        type: "GET",
        headers: {
          "cache-control": "no-cache"
        }
      });
      if (
        checkKnoxSSOresp?.data?.toString() == "true" &&
        userProfile?.configProperties?.inactivityTimeout > 0
      ) {
        window.location.replace("index.html?action=timeout");
      } else {
        handleLogout(checkKnoxSSOresp?.data);
      }
    } catch (error) {
      if (checkKnoxSSOresp?.status == "419") {
        setUserProfile(null);
        window.location.replace("login.jsp");
      }
      console.error(`Error occurred while logout! ${error}`);
    }
  };

  const handleLogout = async (checkKnoxSSOVal) => {
    try {
      await fetchApi({
        url: "logout",
        baseURL: "",
        headers: {
          "cache-control": "no-cache"
        }
      });
      if (checkKnoxSSOVal !== undefined || checkKnoxSSOVal !== null) {
        if (checkKnoxSSOVal?.toString() == "false") {
          window.location.replace("locallogin");
          window.localStorage.clear();
          setUserProfile(null);
        } else {
          navigate("/knoxSSOWarning");
        }
      } else {
        window.location.replace("login.jsp");
      }
    } catch (error) {
      toast.error(`Error occurred while logout! ${error}`);
    }
  };

  const closeCollapse = () => {
    props.closeCollapse();
  };

  return (
    <React.Fragment>
      <div
        className={`drawer ${isDrawerOpen ? "drawer-open" : "drawer-close"}`}
        id="drawer-content"
      >
        <div className="nav-drawer">
          <div
            id="resourcesCollapse"
            className={
              activeMenu !== null && activeMenu === "resourcesCollapse"
                ? "show-menu"
                : "hide-menu"
            }
          >
            <div className="drawer-menu-title">
              <span>RESOURCE POLICIES</span>
              <span className="drawer-menu-close">
                <img
                  src={closeIcon}
                  onClick={() => {
                    props.closeCollapse();
                  }}
                />
              </span>
            </div>
            <div
              title={`${isEmpty(servicesData) ? "Create Service first" : ""}`}
              className="position-relative"
            >
              <Select
                isMulti
                isClearable={true}
                placeholder="Select Service Types"
                menuPlacement="auto"
                className={`select-nav-drawer custom-nav-search  ${
                  loader ? "not-allowed" : ""
                }`}
                styles={serviceSelectCustomStyle}
                theme={serviceSelectThemes}
                isDisabled={loader || isEmpty(servicesData) ? true : false}
                isLoading={loader ? true : false}
                value={!loader ? getCurrentServiceDefs(selectedServiceDef) : ""}
                onChange={(e) => handleServiceDefChange(e)}
                options={serviceDefOptions()}
                components={{
                  DropdownIndicator: () => null,
                  IndicatorSeparator: () => null
                }}
              />
              {selectedServiceDef?.length > 0 && !loader && (
                <button
                  className={`custom-clear-btn ${loader ? "not-allowed" : ""}`}
                  disabled={loader ? true : false}
                  onClick={() => {
                    handleServiceDefChange([]);
                  }}
                >
                  X
                </button>
              )}
            </div>
            <ResourceTagContent
              serviceDefsData={sortBy(
                servicesDefData?.filter(Boolean)?.filter((serviceDef) => {
                  return serviceDef.name !== "tag";
                }),
                "name"
              )}
              servicesData={sortBy(
                servicesData?.filter(Boolean)?.filter((serviceDef) => {
                  return serviceDef.name !== "tag";
                }),
                "name"
              )}
              closeCollapse={closeCollapse}
              loader={loader}
            />
          </div>

          <div
            id="tagCollapse"
            className={
              activeMenu !== null && activeMenu === "tagCollapse"
                ? "show-menu"
                : "hide-menu"
            }
          >
            <div className="drawer-menu-title">
              <span>TAG POLICIES</span>
              <span className="drawer-menu-close">
                <img
                  src={closeIcon}
                  onClick={() => {
                    props.closeCollapse();
                  }}
                />
              </span>
            </div>
            <ResourceTagContent
              serviceDefsData={tagServicesDefData
                ?.filter(Boolean)
                .filter((serviceDef) => {
                  return serviceDef.name == "tag";
                })}
              servicesData={sortBy(
                tagServicesData.filter(Boolean)?.filter((serviceDef) => {
                  return serviceDef.type === "tag";
                }),
                "name"
              )}
              closeCollapse={closeCollapse}
              loader={loader}
            />
          </div>

          <div
            id="gdsCollapse"
            className={
              activeMenu !== null && activeMenu === "gdsCollapse"
                ? "show-menu"
                : "hide-menu"
            }
          >
            <div className="drawer-menu-title">
              <span>GOVERNED DATA SHARING</span>
              <span className="drawer-menu-close">
                <img
                  src={closeIcon}
                  onClick={() => {
                    props.closeCollapse();
                  }}
                />
              </span>
            </div>
            <ul className="list-group list-group-flush">
              <React.Fragment>
                <li className="list-group-item">
                  <NavLink
                    to="/gds/mydatasetlisting"
                    onClick={() => {
                      props.closeCollapse();
                    }}
                    className="list-group-item"
                  >
                    My Datasets
                  </NavLink>
                </li>
                <li className="list-group-item">
                  <NavLink
                    to="/gds/mydatasharelisting"
                    onClick={() => {
                      props.closeCollapse();
                    }}
                    className="list-group-item"
                  >
                    My Datashares
                  </NavLink>
                </li>
                <li className="list-group-item">
                  <NavLink
                    to="gds/request/list"
                    onClick={() => {
                      props.closeCollapse();
                    }}
                    className="list-group-item"
                  >
                    My Requests
                  </NavLink>
                </li>
                <li className="list-group-item">
                  <NavLink
                    to="gds/datasetlisting"
                    onClick={() => {
                      props.closeCollapse();
                    }}
                    className="list-group-item"
                  >
                    Datasets
                  </NavLink>
                </li>
                <li className="list-group-item">
                  <NavLink
                    to="gds/datasharelisting"
                    onClick={() => {
                      props.closeCollapse();
                    }}
                    className="list-group-item"
                  >
                    Datashares
                  </NavLink>
                </li>
              </React.Fragment>
            </ul>
          </div>

          <div
            id="auditCollapse"
            className={
              activeMenu !== null && activeMenu === "auditCollapse"
                ? "show-menu"
                : "hide-menu"
            }
          >
            <div className="drawer-menu-title">
              <span>AUDITS</span>
              <span className="drawer-menu-close">
                <img
                  src={closeIcon}
                  onClick={() => {
                    props.closeCollapse();
                  }}
                />
              </span>
            </div>
            <ul className="list-group list-group-flush">
              {hasAccessToTab("Audit") && (
                <React.Fragment>
                  <li className="list-group-item">
                    <NavLink
                      to="/reports/audit/bigData"
                      onClick={() => {
                        props.closeCollapse();
                      }}
                      className="list-group-item"
                    >
                      Access
                    </NavLink>
                  </li>
                  <li className="list-group-item">
                    <NavLink
                      to="/reports/audit/admin"
                      onClick={() => {
                        props.closeCollapse();
                      }}
                      className="list-group-item"
                    >
                      Admin
                    </NavLink>
                  </li>
                  <li className="list-group-item">
                    <NavLink
                      to="/reports/audit/loginSession"
                      onClick={() => {
                        props.closeCollapse();
                      }}
                      className="list-group-item"
                    >
                      Login Sessions
                    </NavLink>
                  </li>
                  <li className="list-group-item">
                    <NavLink
                      to="/reports/audit/agent"
                      onClick={() => {
                        props.closeCollapse();
                      }}
                      className="list-group-item"
                    >
                      Plugins
                    </NavLink>
                  </li>
                  <li className="list-group-item">
                    <NavLink
                      to="/reports/audit/pluginStatus"
                      onClick={() => {
                        props.closeCollapse();
                      }}
                      className="list-group-item"
                    >
                      Plugin Status
                    </NavLink>
                  </li>
                  <li className="list-group-item">
                    <NavLink
                      to="/reports/audit/userSync"
                      onClick={() => {
                        props.closeCollapse();
                      }}
                      className="list-group-item"
                    >
                      User Sync
                    </NavLink>
                  </li>
                </React.Fragment>
              )}
            </ul>
          </div>

          <div
            id="settingsCollapse"
            className={
              activeMenu !== null && activeMenu === "settingsCollapse"
                ? "show-menu"
                : "hide-menu"
            }
          >
            <div className="drawer-menu-title">
              <span>SETTINGS</span>
              <span className="drawer-menu-close">
                <img
                  src={closeIcon}
                  onClick={() => {
                    props.closeCollapse();
                  }}
                />
              </span>
            </div>
            <ul className="list-group list-group-flush">
              {hasAccessToTab("Users/Groups") && (
                <React.Fragment>
                  <li className="list-group-item">
                    <NavLink
                      to="/users/usertab"
                      onClick={() => {
                        props.closeCollapse();
                      }}
                      className="list-group-item"
                    >
                      Users
                    </NavLink>
                  </li>

                  <li className="list-group-item">
                    <NavLink
                      to="/users/grouptab"
                      onClick={() => {
                        props.closeCollapse();
                      }}
                      className="list-group-item"
                    >
                      Groups
                    </NavLink>
                  </li>

                  <li className="list-group-item">
                    <NavLink
                      to="/users/roletab"
                      onClick={() => {
                        props.closeCollapse();
                      }}
                      className="list-group-item"
                    >
                      Roles
                    </NavLink>
                  </li>
                </React.Fragment>
              )}
              {(isAuditor() || isSystemAdmin()) && (
                <li className="list-group-item">
                  <NavLink
                    to="/permissions/models"
                    onClick={() => {
                      props.closeCollapse();
                    }}
                    className="list-group-item"
                  >
                    Permissions
                  </NavLink>
                </li>
              )}
            </ul>
          </div>
        </div>
      </div>
      <div
        className={`account-drawer ${
          accountDrawer ? "account-drawer-open" : "account-drawer-close"
        }`}
        id="account-drawer-content"
      >
        <div className="account-nav-drawer">
          <div
            id="accountCollapse"
            className={
              activeMenu !== null && activeMenu === "accountCollapse"
                ? "show-account-menu"
                : "hide-account-menu"
            }
          >
            <div className="drawer-menu-title">
              <span>USER PROFILE</span>
              <span className="drawer-menu-close">
                <img
                  src={closeIcon}
                  onClick={() => {
                    props.closeCollapse();
                  }}
                />
              </span>
            </div>
            <ul className="list-group list-group-flush">
              <li className="list-group-item">
                <NavLink
                  to="/userprofile"
                  onClick={() => {
                    props.closeCollapse();
                  }}
                  className="list-group-item"
                >
                  Profile
                </NavLink>
              </li>
              <li className="list-group-item">
                <a
                  href={apiUrl}
                  rel="noreferrer"
                  target="_blank"
                  onClick={() => {
                    props.closeCollapse();
                  }}
                  className="text-decoration-none"
                >
                  API Documentation
                </a>
              </li>
              <li className="list-group-item">
                <NavLink
                  onClick={checkKnoxSSO}
                  to="#"
                  className="text-decoration-none"
                >
                  Log Out
                </NavLink>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </React.Fragment>
  );
};
