import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector, useStore } from 'react-redux';
import { useRouter } from 'next/router';
import { LockOpen, LockPersonRounded } from '@mui/icons-material';

import { TAB_GENERAL } from '../constants';
import { ACCOUNT, API, EXTERNAL, INTERNAL } from '@/modules/@common/user/constants/rolesType';

import { getCanReadOnly } from '../helpers/getRestrictions';
import * as selectors from '../redux/selectors';
import {
  createItemAction,
  getItemAction,
  impersonateUserAction,
  setActiveTabIdAction,
  setErrorByPropAction,
  setInitialAction,
  setScrollToFieldNameAction,
  updateItemAction,
  validateFields,
} from '../redux/slices';
import { getUserPermissionsSelector, getUserRoleTypeSelector } from '@/modules/@common/user/redux/selectors';
import { resetPasswordAction } from '@/modules/users/List/redux/slices';

import { Form, FormContent, FormSection } from '@/modules/@common/Form';
import GeneralTab from './Tabs/GeneralTab/GeneralTab';
import {
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Divider,
  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 initialEmail = useSelector(selectors.initialEmailSelector);
  const initialRoleType = useSelector(selectors.initialRoleTypeSelector);
  const initialRoleName = useSelector(selectors.initialRoleNameSelector);
  const initialStatus = useSelector(selectors.initialStatusSelector);

  const firstName = useSelector(selectors.firstNameSelector);
  const lastName = useSelector(selectors.lastNameSelector);

  const activeTabId = useSelector(selectors.activeTabIdSelector);
  const [confirmResetPassword, setResetPassword] = useState(false);
  const userPermissions = useSelector(getUserPermissionsSelector);
  const hasAccount = useSelector(getUserRoleTypeSelector) === ACCOUNT;

  const id = parseInt(router.query.id, 10);

  const canReadOnly = getCanReadOnly(id, userPermissions);

  useEffect(() => {
    if (id) {
      dispatch(getItemAction({ id }));
    }

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

  const tabs = [
    {
      title: 'General',
      id: TAB_GENERAL,
      content: GeneralTab,
    },
  ].filter(Boolean);

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

    const { validation, errorList } = validateFields(
      selectors
        .schemeSelector(state)
        .filter(({ tabId, fieldName }) => {
          if (!tabs.some((tab) => tab.id === tabId)) {
            return false;
          }

          if (fieldName === 'account') {
            return !hasAccount && allProps.role && ![API, INTERNAL, EXTERNAL].includes(allProps.role.type);
          }

          if (fieldName === 'publisherIds' || fieldName === 'publisherId') {
            return allProps.role && ![EXTERNAL, INTERNAL, API].includes(allProps.role.type);
          }

          if (fieldName === 'contentOwner') {
            return allProps.role && allProps.role.type === API;
          }

          if (fieldName === 'email') {
            return !id;
          }

          return true;
        })
        .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));
    } else if (id) {
      dispatch(updateItemAction(id));
    } else {
      dispatch(createItemAction());
    }

    dispatch(setErrorByPropAction(validation));
  };

  const showLoginAs =
    initialRoleName !== 'admin' && !!initialStatus && !hasAccount && initialRoleType && initialRoleType !== API;

  return (
    <div className={styles.Wrapper}>
      <Stack direction="column" fullWidth justifyContent="center" className={styles.Title}>
        <Typography component="div" variant="h6" noWrap>
          {id ? `${firstName} ${lastName} > Settings` : 'New User'}
        </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}
            className={styles.Tabs}
            onChange={(event, value) => dispatch(setActiveTabIdAction(value))}
          >
            {tabs.map((tab) => (
              <Tab key={tab.id} label={tab.title} value={tab.id} />
            ))}
          </Tabs>
        )}
        <Stack spacing={2} justifyContent="flex-end" alignItems="center" direction="row">
          {!!id && initialRoleType && initialRoleType !== API && (
            <Button
              size="small"
              color="neutral"
              variant="text"
              onClick={() => setResetPassword(true)}
              startIcon={<LockOpen />}
            >
              Reset Password
            </Button>
          )}
          {!!id && showLoginAs && (
            <Button
              size="small"
              color="neutral"
              variant="text"
              onClick={() => {
                dispatch(impersonateUserAction(id));
              }}
              startIcon={<LockPersonRounded />}
            >
              Login As
            </Button>
          )}
          <Divider flexItem orientation="vertical" />
          <Button variant="outlined" size="small" color="primary" shape="rounded" onClick={() => router.push('/users')}>
            Cancel
          </Button>
          {!canReadOnly && (
            <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>
      {!!confirmResetPassword && (
        <Dialog maxWidth="sm" open={!!confirmResetPassword} onClose={() => setResetPassword(false)}>
          <DialogTitle onClose={() => setResetPassword(false)}>Reset Password</DialogTitle>
          <DialogContent>{`Are you sure you want to reset password for ${initialEmail}?`}</DialogContent>
          <DialogActions>
            <Button variant="outlined" size="small" color="neutral" onClick={() => setResetPassword(false)}>
              Cancel
            </Button>
            <Button
              variant="contained"
              size="small"
              color="primary"
              onClick={() => {
                dispatch(resetPasswordAction(initialEmail));
                setResetPassword(false);
              }}
            >
              Reset
            </Button>
          </DialogActions>
        </Dialog>
      )}
    </div>
  );
}

export default Editor;
