import { useEffect, useState } from 'react';
import { Routes, Route, useNavigate } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import {
  getEmpAccesData,
  GenerateLogout,
  getSAdminUserAccesData,
  PricingAppPricingName,
  checkSession,
  getCompBranchData,
  getCommonAppPreference,
  changeWarehouse,
} from './Features/BrachLogin/BranchLogin.js';
import { clearSession, getSession } from './Services/Others';
import {
  FeatureAddon,
  GlobalFeatAddOnData,
} from './Features/BookingScreen/BookingData/BookingData.js';
import { Suspense } from 'react';
import { gettableData } from './Features/PreferenceMaster/PreferenceMaster.js';
import { useSelector } from 'react-redux';
import { useTemplate } from './utils/useTemplate.js';

const commonUrl = import.meta.env.ENV_COMMON_BASE_URL;
const subDirectory = import.meta.env.BASE_URL;

const ProtectedRoutes = ({ routesConfig }) => {

  useTemplate(
    getSession('CompId'),
    getSession('BranchId'),
    getSession('AppId')
  );
  const navigate = useNavigate();
  const dispatch = useDispatch();
  const UserType = getSession('UserType');
  const [hasRedirected, setHasRedirected] = useState(false);
  const AppId = getSession('AppId');
  const CompId = getSession('CompId');
  const BranchId = getSession('BranchId');
  const UserId = getSession('UserId');
  const sessionId = getSession('SessionId');
  const Warehouse = getSession('Warehouse');
  const [accessCheckComplete, setAccessCheckComplete] = useState(false);
  const FeatureAddonData = useSelector(GlobalFeatAddOnData);
  useTemplate(CompId, BranchId, AppId);

  useEffect(() => {
    getApplicationPreference();
  }, []);
  //sri
  useEffect(() => {
    if (Warehouse) {
      dispatch(changeWarehouse(true));
    }
  }, [Warehouse]);
  const getApplicationPreference = async () => {
    await dispatch(getCommonAppPreference(AppId)).unwrap();
  };

  const getEmpAccess = async () => {
    let data = {
      UserId: UserId,
      AppId: AppId,
      CompId: CompId,
      BranchId: BranchId,
    };

    const response = await dispatch(getEmpAccesData(data)).unwrap();
    if (response?.data?.statusCode === 1) {
      return response?.data?.data?.[0]?.EmpAccessDetails;
    }
    return null;
  };

  const getSadminUserAccess = async () => {
    let data = {
      UserId: UserId,
      AppId: AppId,
    };
    const response = await dispatch(getSAdminUserAccesData(data)).unwrap();
    if (response?.data?.statusCode === 1) {
      return response?.data?.data?.[0]?.AppMenuAccessDetails;
    }
    return null;
  };

  const Dinein = async () => {
    if (AppId && CompId && BranchId) {
      let DineinData = {
        AppId: AppId,
        CompId: CompId,
        BranchId: BranchId,
        UserId:UserId
      };
      const response = await dispatch(gettableData(DineinData)).unwrap();
      if (response?.data?.statusCode === 1) {
        const SettingValueData = response?.data?.data
          ?.find((e) => e.AppId === AppId)
          ?.SettingDtlDetails?.some(
            (e) => e.SettingIdName === 'DineIn' && e.SettingValue === 'Y'
          );
        const EstimateValueData = response?.data?.data
          ?.find((e) => e.AppId === AppId)
          ?.SettingDtlDetails?.some(
            (e) => e.SettingIdName === 'Estimation' && e.SettingValue === 'Y'
          );
        return (SettingValueData, EstimateValueData);
      }
    }
  };

  const checkAccess = async (empAccess) => {
    if (!empAccess) return false;
    let DineinData,
      EstimateData = await Dinein();
    switch (empAccess) {
      case 'Dine In':
      case 'KOT':
        return !!DineinData;
      case 'Estimate':
        return !!EstimateData;
      default:
        return false; // Restrict access if no valid match found
    }
  };

  const getPricingName = async () => {
    if (!AppId || !UserId) return;
    const data = {
      appId: AppId,
      userId: UserId,
    };
    try {
      const response = await dispatch(PricingAppPricingName(data)).unwrap();
      const responseData = response?.data;
      const pricingData = responseData?.data;
      const hasAdvance = pricingData?.some(
        (item) => item.PricingName === 'Premium'
      );
      const hasProOrAdvance =
        hasAdvance ||
        pricingData.some((item) => item.PricingName === 'Customized');
      return (hasAdvance, hasProOrAdvance);
    } catch (error) {
      console.error('Error fetching pricing name:', error);
    }
  };

  const checkPlanAccess = async (empAccess, featureAddonData) => {
    if (!empAccess) return false;
    let Advance,
      ProORAdvance = await getPricingName();
    switch (empAccess) {
      case 'Product Catalogue':
        return (
          ProORAdvance ||
          featureAddonData?.some(
            (item) => item?.FeatureAddonName?.toLowerCase() === 'catalog'
          )
        );
      case 'Sales Setup':
      case 'Print Setup':
        return (
          Advance ||
          featureAddonData?.some(
            (item) =>
              item?.FeatureAddonName?.toLowerCase() === 'customized template'
          )
        );
      case 'Kiosk Setup':
      case 'Kiosk Sales':
        return featureAddonData?.some(
          (item) => item?.FeatureAddonName?.toLowerCase() === 'kiosk sales'
        );
      default:
        return false; // Restrict access if no valid match found
    }
  };

  const checkEmpAccess = async (empAccess, currentPath) => {
    if (!empAccess) return false;
    const Access = await getEmpAccess();
    let accessType;
    if (currentPath.endsWith('/new')) {
      accessType = 'AddAccess';
    } else if (currentPath.endsWith('/update')) {
      accessType = 'UpdateAccess';
    } else {
      accessType = 'ReadAccess';
    }
    // const config = Access?.find(config =>
    //   config.ConfigName === empAccess && config[accessType] === 'Y'
    // );
    const config = Access?.find(
      (config) =>
        (config.ConfigName === empAccess && config[accessType] === 'Y') ||
        (currentPath.includes('supplier-master') &&
          (config.ConfigName === 'Supplier' ||
            config.ConfigName === 'Seller') &&
          config[accessType] === 'Y')
    );

    return !!config;
  };

  const checkSuperAdminUserAccess = async (empAccess, currentPath) => {
    console.log('empAccessData1', empAccess, currentPath);
    if (!empAccess) return false;
    const Access = await getSadminUserAccess();
    let accessType;
    if (currentPath.endsWith('/new')) {
      accessType = 'AddAccess';
    } else if (currentPath.endsWith('/update')) {
      accessType = 'UpdateAccess';
    } else {
      accessType = 'ReadAccess';
    }
    console.log('empAccessData2', Access, accessType);
    // const config = Access?.find(config =>
    //   config.MenuName === empAccess && config[accessType] === 'Y'
    // );
    const config = Access?.find(
      (config) =>
        (config.MenuName === empAccess && config[accessType] === 'Y') ||
        (currentPath.includes('supplier-master') &&
          (config.MenuName === 'Supplier' || config.MenuName === 'Seller') &&
          config[accessType] === 'Y')
    );
    console.log('empAccessData3', config);

    return !!config;
  };

  const getEmpAccessFromChildren = (route, currentPath) => {
    if (route.path === currentPath) {
      return route.empAccess || null;
    }

    if (route.children) {
      for (const child of route.children) {
        const childPath = `${route.path}/${child.path}`;
        if (childPath === currentPath) {
          return child.empAccess || null;
        }
      }
    }

    return null;
  };

  const getEmpAccessDataFromChildren = (route, currentPath) => {
    if (route.path === currentPath) {
      return route.access || null;
    }
    if (route.children) {
      for (const child of route.children) {
        const childPath = `${route.path}/${child.path}`;
        if (childPath === currentPath) {
          return child.access || null;
        }
      }
    }
    return null;
  };

  const fetchBranchData = async () => {
    const response = await dispatch(
      getCompBranchData({ CompId: CompId, AppId: AppId })
    ).unwrap();
    if (response?.data?.statusCode === 1) {
      if (response?.data?.data?.length == 1) {
        navigate(`${subDirectory}app-page/home`);
      } else {
        navigate(`${subDirectory}app-page/branch-login`);
      }
    }
  };
  useEffect(() => {
    const performAccessChecks = async () => {
      if (!hasRedirected) {
        let featureAddon;
        let featureAddonData;

        if (UserType !== 'Super Admin' && UserType !== 'Super Admin User') {
          if (FeatureAddonData?.FeatureDtls?.length > 0) {
            featureAddonData = FeatureAddonData?.FeatureDtls;
          } else {
            featureAddon = await dispatch(
              FeatureAddon({ AppId: AppId, UserId: UserId })
            ).unwrap();
            if (featureAddon?.data?.statusCode === 1) {
              featureAddonData =
                featureAddon?.data?.data?.[0]?.FeatAddonHdr?.[0]?.FeatureDtls;
            } else {
              featureAddonData = [];
            }
          }
        }

        const currentPath = location.pathname.replace(/\/$/, ''); // Remove trailing slash
        let shouldNavigate = false;

        // Find the current route in routesConfig based on currentPath
        const currentRoute = routesConfig?.find((route) => {
          if (route.path === currentPath) return true;
          if (route.children) {
            return route.children.some((child) => {
              const childPath = `${route.path}/${child.path}`;
              return childPath === currentPath;
            });
          }
          return false;
        });

        if (!currentRoute) {
          // alert("Unauthorized action detected. You have been logged out.")
          Logout();
          setHasRedirected(true);
          return;
        }

        const empAccessData = getEmpAccessFromChildren(
          currentRoute,
          currentPath
        );
        const accessData = getEmpAccessDataFromChildren(
          currentRoute,
          currentPath
        );

        const checkPreferenceAccessData = ['Dine In', 'KOT', 'Estimate'];
        const checkPlanAccessData = [
          'Product Catalogue',
          'Sales Setup',
          'Print Setup',
          'Kiosk Setup',
          'Kiosk Sales',
        ];
        // Cmd it start

        // if (!UserId && empAccessData != 'Public') {
        //   if (!UserId && (empAccessData === "Kiosk Sales" || empAccessData === "View Bill")) {
        //     // Allow KioskBookingPage to load and set session values
        //     setAccessCheckComplete(true);
        //     return;
        //   }else{
        // console.log("UserId is undefined, logging out...");
        //   // alert("User invalid. Redirecting to login...")
        //   sessionStorage.clear();
        //   window.location.replace(`${commonUrl}`);
        //   setHasRedirected(true);
        //   return;
        //   }
        // }

        // Cmd it End
        const userAccessChecks = {
          'Super Admin': () => {
            let empPreferenceCheck = true;
            if (checkPreferenceAccessData.includes(empAccessData)) {
              empPreferenceCheck = checkAccess(empAccessData);
            } else {
              empPreferenceCheck = true;
            }
            return !empPreferenceCheck;
          },
          'Super Admin User': async () => {
            const SAdminuserPin = await dispatch(
              checkSession({ UserId, sessionId })
            ).unwrap();
            if (
              (SAdminuserPin?.data?.statusCode === 1 &&
                SAdminuserPin?.data?.data?.filter(
                  (item) =>
                    item?.AppId == AppId &&
                    item?.CompId == CompId &&
                    item?.BranchId == BranchId
                )?.[0]?.Status === 'L') ||
              BranchId === null ||
              BranchId === '' ||
              BranchId === undefined
            ) {
              if (sessionStorage.getItem('BranchId') !== null) {
                clearSession('BranchId');
              }
              fetchBranchData();
            } else {
              if (empAccessData) {
                const superAdminUserAccessCheck =
                  await checkSuperAdminUserAccess(empAccessData, currentPath);
                let empPreferenceCheck = true;
                if (checkPreferenceAccessData.includes(empAccessData)) {
                  empPreferenceCheck = checkAccess(empAccessData);
                } else {
                  empPreferenceCheck = true;
                }
                return !superAdminUserAccessCheck || !empPreferenceCheck;
              } else {
                return false;
              }
            }
          },
          Admin: () => {
            if (accessData === 'Super Admin') {
              return true;
            } else {
              let empPreferenceCheck = true;
              let empPlanAccessCheck = true;

              if (checkPreferenceAccessData.includes(empAccessData)) {
                empPreferenceCheck = checkAccess(empAccessData);
              } else {
                empPreferenceCheck = true;
              }

              if (checkPlanAccessData.includes(empAccessData)) {
                empPlanAccessCheck = checkPlanAccess(
                  empAccessData,
                  featureAddonData
                );
              } else {
                empPlanAccessCheck = true;
              }

              return !empPreferenceCheck || !empPlanAccessCheck;
            }
          },
          Employee: async () => {
            if (empAccessData && accessData !== 'Super Admin') {
              const empAccessCheck = await checkEmpAccess(
                empAccessData,
                currentPath
              );
              let empPreferenceCheck = true;
              let empPlanAccessCheck = true;

              if (checkPreferenceAccessData.includes(empAccessData)) {
                empPreferenceCheck = checkAccess(empAccessData);
              } else {
                empPreferenceCheck = true;
              }

              if (checkPlanAccessData.includes(empAccessData)) {
                empPlanAccessCheck = checkPlanAccess(
                  empAccessData,
                  featureAddonData
                );
              } else {
                empPlanAccessCheck = true;
              }
              if (location.pathname === '/app-page/relieve-request') {
                return false;
              }
              return (
                !empAccessCheck || !empPreferenceCheck || !empPlanAccessCheck
              );
            } else {
              if (accessData === 'Super Admin') {
                return true;
              } else {
                return false;
              }
            }
          },
        };

        if (userAccessChecks[UserType]) {
          shouldNavigate = await userAccessChecks[UserType]();
        } else {
          shouldNavigate = true;
        }
        console.log('shouldNavigate', shouldNavigate);
        if (shouldNavigate) {
          // alert("Unauthorized action detected. You have been logged out.")
          Logout();
          setHasRedirected(true);
        } else {
          console.log('Access granted for current route.');
        }

        setAccessCheckComplete(true);
      }
    };

    performAccessChecks();
  }, [UserType, routesConfig, navigate, hasRedirected, location.pathname]);

  const Logout = async () => {
    const status = 'N'; // replace with your actual status
    const res = await dispatch(GenerateLogout({ UserId, status })).unwrap();
    if (res?.data?.statusCode === 1) {
      sessionStorage.clear();
      window.location.replace(`${commonUrl}`);
    }
  };

  const renderRoutes = (routes) => {
    return routes.map(({ path, component: Component, children }) => {
      const fullPath = `${path}`;

      if (!Component) {
        console.error(`Component not found for path: ${fullPath}`);
        return null;
      }

      if (children) {
        return (
          <Route key={fullPath} path={fullPath} element={<Component />}>
            {children.map(({ path: childPath, component: ChildComponent }) => {
              if (!ChildComponent) {
                console.error(
                  `Child component not found for path: ${childPath}`
                );
                return null;
              }
              return (
                <Route
                  key={childPath}
                  path={childPath}
                  element={<ChildComponent />}
                />
              );
            })}
          </Route>
        );
      }

      return <Route key={fullPath} path={fullPath} element={<Component />} />;
    });
  };

  return (
    <Suspense fallback={<div></div>}>
      <Routes>{accessCheckComplete && renderRoutes(routesConfig)}</Routes>
    </Suspense>
  );
};

export default ProtectedRoutes;
