import React, { useEffect } from 'react';
import { useDispatch, useSelector, useStore } from 'react-redux';
import { useRouter } from 'next/router';

import { TAB_DETAILS, TAB_PERMISSIONS } from '../constants';

import * as selectors from '../redux/selectors';
import {
  createItemAction,
  getItemAction,
  setActiveTabIdAction,
  setErrorByPropAction,
  setInitialAction,
  setScrollToFieldNameAction,
  updateItemAction,
  validateFields,
} from '../redux/slices';

import { Form, FormContent, FormSection } from '@/modules/@common/Form';
import DetailsTab from './Tabs/DetailsTab/DetailsTab';
import PermissionsTab from './Tabs/PermissionsTab/PermissionsTab';
import { Button, Stack, Tab, TabContent, Tabs, Typography } from '@/mui/components';

import styles from './Editor.module.scss';

function Editor() {
  const store = useStore();
  const dispatch = useDispatch();
  const router = useRouter();

  const activeTabId = useSelector(selectors.activeTabIdSelector);
  const displayName = useSelector(selectors.displayNameSelector);

  const id = parseInt(router.query.id, 10);
  const isDuplicate = router.asPath.split('/').filter(Boolean).reverse()[0] === 'duplicate';

  const tabs = [
    {
      title: 'Role Details',
      id: TAB_DETAILS,
      content: DetailsTab,
    },
    {
      title: 'Permissions',
      id: TAB_PERMISSIONS,
      content: PermissionsTab,
    },
  ].filter(Boolean);

  const getTitle = () => {
    if (id && !isDuplicate) {
      return `${displayName} > Settings`;
    }

    if (isDuplicate) {
      return 'Duplicate Role';
    }

    return 'New Role';
  };

  const saveToServerForm = () => {
    const state = store.getState();
    const allProps = selectors.fullAccessToStoreFieldsForValidation(state);

    const { validation, errorList } = validateFields(
      selectors
        .schemeSelector(state)
        .filter(({ tabId }) => tabs.some((tab) => tab.id === tabId))
        .map(({ fieldName }) => fieldName),
      allProps,
    );

    if (errorList.length) {
      const errorField = errorList.find((error) => error.tabId === activeTabId) ?? errorList[0];

      dispatch(setActiveTabIdAction(errorField.tabId));
      dispatch(setScrollToFieldNameAction(errorField.fieldName));
    }

    if (!errorList.length) {
      const action = id && !isDuplicate ? updateItemAction(id) : createItemAction(id);
      dispatch(action);
    }

    dispatch(setErrorByPropAction(validation));
  };

  useEffect(() => {
    dispatch(getItemAction({ id, isDuplicate }));

    return () => {
      dispatch(setInitialAction());
    };
  }, [id]);

  return (
    <div className={styles.Wrapper}>
      <Stack direction="column" fullWidth justifyContent="center" className={styles.Title}>
        <Typography component="div" variant="h6" noWrap>
          {getTitle()}
        </Typography>
      </Stack>
      <Stack
        spacing={1}
        fullWidth
        direction="row"
        alignItems="center"
        justifyContent="space-between"
        className={styles.Controls}
      >
        {tabs.length > 1 && (
          <Tabs
            size="medium"
            orientation="horizontal"
            value={activeTabId}
            onChange={(event, value) => dispatch(setActiveTabIdAction(value))}
            className={styles.Tabs}
          >
            {tabs.map((tab) => (
              <Tab key={tab.id} label={tab.title} value={tab.id} />
            ))}
          </Tabs>
        )}
        <Stack spacing={2} justifyContent="flex-end" alignItems="center" direction="row">
          <Button
            variant="outlined"
            size="small"
            color="primary"
            shape="rounded"
            onClick={() => router.push('/roles-permissions')}
          >
            Cancel
          </Button>
          <Button variant="contained" size="small" color="primary" shape="rounded" onClick={saveToServerForm}>
            Save
          </Button>
        </Stack>
      </Stack>
      <Form scrollFieldSelector={selectors.scrollFieldSelector}>
        <FormContent>
          {tabs.map((tab) => {
            const Content = tab.content;

            return (
              <TabContent key={tab.id} component={FormContent} selectedId={activeTabId} id={tab.id}>
                <FormSection>
                  <Content />
                </FormSection>
              </TabContent>
            );
          })}
        </FormContent>
      </Form>
    </div>
  );
}

export default Editor;
