import React from "react";
import { Refine, ResourceProps } from "@refinedev/core";
import {
  notificationProvider,
  ErrorComponent,
  ThemedLayoutV2,
} from "@refinedev/antd";
import { RefineKbar, RefineKbarProvider } from "@refinedev/kbar";
import routerProvider, {
  NavigateToResource,
  UnsavedChangesNotifier,
} from "@refinedev/react-router-v6";
import { BrowserRouter, Outlet, Route, Routes } from "react-router-dom";
import { useTranslation } from "react-i18next";
import resources from "generated/resources";
import { OffLayoutArea } from "components/offLayoutArea";
import { Header } from "components/layout";
import { CustomSider } from "./components/layout";
import { ColorModeContextProvider } from "components/contexts/color-mode";
import { BusinessContextProvider } from "components/contexts/business";
import { authProvider } from "authProvider";
import produce from "immer";
import Index from "pages/index";
import "@refinedev/antd/dist/reset.css";
import { auditLogProvider } from "auditLogProvider";
import {
  DashboardOutlined,
  SettingOutlined,
} from "@ant-design/icons";
import { gadminCrudProvider as dataProvider } from "./helpers/login";

const SYSTEM_MENU_NAME = "system";
const newResources: ResourceProps[] = produce(resources, (draft) => {
  draft.forEach((resource) => {
    if (
      resource.meta &&
      ["game", "studio", "role", "log"].includes(resource.name)
    ) {
      resource.meta.parent = SYSTEM_MENU_NAME;
      resource.list = `/${SYSTEM_MENU_NAME}${resource.list}`;
      resource.create = `/${SYSTEM_MENU_NAME}${resource.create}`;
      resource.edit = `/${SYSTEM_MENU_NAME}${resource.edit}`;
      resource.clone = `/${SYSTEM_MENU_NAME}${resource.clone}`;
      resource.show = `/${SYSTEM_MENU_NAME}${resource.show}`;
    }
  });
  draft.splice(0, 0, {
    name: "index",
    list: "/index",
    meta: { icon: <DashboardOutlined /> },
  });
  draft.push({
    name: SYSTEM_MENU_NAME,
    list: `/${SYSTEM_MENU_NAME}`,
    meta: { icon: <SettingOutlined /> },
  });
});

function App() {
  const { t, i18n } = useTranslation();

  const i18nProvider = {
    translate: (key: string, defaultMessage?: string) => t(key, defaultMessage),
    changeLocale: (lang: string) => i18n.changeLanguage(lang),
    getLocale: () => i18n.language,
  };

  return (
    <BrowserRouter>
      <RefineKbarProvider>
        <BusinessContextProvider>
          <ColorModeContextProvider>
            <Refine
              resources={newResources}
              notificationProvider={notificationProvider}
              routerProvider={routerProvider}
              i18nProvider={i18nProvider}
              authProvider={authProvider}
              auditLogProvider={auditLogProvider(dataProvider)}
              dataProvider={{
                default: dataProvider,
              }}
              options={{
                syncWithLocation: true,
                warnWhenUnsavedChanges: true,
              }}
            >
              <Routes>
                <Route
                  path="/"
                  element={
                    <ThemedLayoutV2
                      Sider={CustomSider}
                      Title={() => null}
                      Header={Header}
                      OffLayoutArea={OffLayoutArea}
                    >
                      <Outlet />
                    </ThemedLayoutV2>
                  }
                >
                  <Route
                    index
                    element={<NavigateToResource resource="index" />}
                  />
                  <Route path="index" element={<Index />} />
                  {newResources
                    .filter((resource) => !resource?.meta?.parent)
                    .map((resource) => {
                      const {
                        list: List,
                        create: Create,
                        edit: Edit,
                        show: Show,
                      } = resource?.meta?.components || {};
                      return (
                        <Route
                          key={`/${resource.name}`}
                          path={`/${resource.name}`}
                        >
                          {List ? <Route index element={<List />} /> : null}
                          {Create ? (
                            <Route path="create" element={<Create />} />
                          ) : null}
                          {Edit ? (
                            <Route path="edit/:id" element={<Edit />} />
                          ) : null}
                          {Show ? (
                            <Route path="show/:id" element={<Show />} />
                          ) : null}
                          {Edit ? (
                            <Route path="clone/:id" element={<Edit />} />
                          ) : null}
                        </Route>
                      );
                    })}
                  {[SYSTEM_MENU_NAME].map((name) => (
                    <Route path={name}>
                      {newResources
                        .filter((resource) => resource?.meta?.parent === name)
                        .map((resource) => {
                          const {
                            list: List,
                            create: Create,
                            edit: Edit,
                            show: Show,
                          } = resource?.meta?.components || {};

                          return (
                            <Route
                              key={`${resource.name}`}
                              path={`${resource.name}`}
                            >
                              {List ? <Route index element={<List />} /> : null}
                              {Create ? (
                                <Route path="create" element={<Create />} />
                              ) : null}
                              {Edit ? (
                                <Route path="edit/:id" element={<Edit />} />
                              ) : null}
                              {Show ? (
                                <Route path="show/:id" element={<Show />} />
                              ) : null}
                              {Edit ? (
                                <Route path="clone/:id" element={<Edit />} />
                              ) : null}
                            </Route>
                          );
                        })}
                    </Route>
                  ))}
                  <Route path="*" element={<ErrorComponent />} />
                </Route>
              </Routes>
              <RefineKbar />
              <UnsavedChangesNotifier />
            </Refine>
          </ColorModeContextProvider>
        </BusinessContextProvider>
      </RefineKbarProvider>
    </BrowserRouter>
  );
}

export default App;
