import { useEffect, useReducer } from 'react';
import {
  Alert,
  Button,
  Drawer,
  Grid,
  Icon,
  IconButton,
  IconName,
  TextField,
  Typography
} from '@noahspan/noahspan-components';
import { useForm, Controller, FormProvider } from 'react-hook-form';
import { initialState, reducer } from './reducer';
import { ProjectFormProps } from './ProjectFormProps.interface';
import { FormMode } from '../../enums/formMode';
import { useIsAuthenticated } from '@azure/msal-react';
import { useAccessToken } from '../../hooks/accessToken/UseAccessToken';
import { useHttpClient } from '../../hooks/httpClient/UseHttpClient';
import { AxiosError, AxiosInstance, AxiosResponse } from 'axios';

const ProjectForm = ({ isDrawerOpen, mode, onOpenClose, projectId }: ProjectFormProps) => {
  const [state, dispatch] = useReducer(reducer, initialState);
  const httpClient: AxiosInstance = useHttpClient();
  const { getAccessToken } = useAccessToken();
  const isAuthenticated = useIsAuthenticated();
  const defaultValues = {
    partitionKey: 'project',
    rowKey: '',
    title: '',
    subTitle: '',
    iconName: '',
    summary: '',
    repoName: '',
    siteUrl: '',
    order: ''
  }
  const methods = useForm({
    defaultValues: defaultValues
  });
  const watchRepoName = methods.watch(['repoName'])

  const onCancel = () => {
    methods.reset(defaultValues);
    dispatch({ type: 'SET_IS_DISABLED', payload: false });
    onOpenClose(FormMode.CANCEL);
  };

  const onSubmit = async (data: unknown) => {
    console.log(data)
    try {
      dispatch({ type: 'SET_IS_LOADING', payload: true });

      const accessToken: string = await getAccessToken();

      if (!projectId) {
        await httpClient.post(`api/projects`, data, {
          headers: {
            Authorization: accessToken
          }
        });
      } else {
        await httpClient.put(`api/projects/project/${projectId}`, data, {
          headers: {
            Authorization: accessToken
          }
        });
      }

      methods.reset(defaultValues);
      dispatch({ type: 'SET_IS_DISABLED', payload: false });
      onOpenClose(FormMode.CANCEL);
    } catch (error) {
      const axiosError = error as AxiosError;

      dispatch({ type: 'SET_ERROR', payload: axiosError.message });
    } finally {
      dispatch({ type: 'SET_IS_LOADING', payload: false });
    }
  };

  useEffect(() => {
    if (watchRepoName.length > 0) {
      methods.setValue('rowKey', watchRepoName[0])
    }
  }, [watchRepoName])

  useEffect(() => {
    if (mode === FormMode.VIEW) {
      dispatch({ type: 'SET_IS_DISABLED', payload: true });
    }
  }, [mode]);

  useEffect(() => {
    const getProject = async () => {
      try {
        dispatch({ type: 'SET_IS_LOADING', payload: true });

        const config = isAuthenticated
          ? { headers: { Authorization: await getAccessToken() } }
          : {};
        const response: AxiosResponse = await httpClient.get(
          `api/projects/project/${projectId}`,
          config
        );
        const entry = response.data;

        methods.reset(entry);
      } catch (error) {
        const axiosError = error as AxiosError;

        dispatch({ type: 'SET_ERROR', payload: axiosError.message });
      } finally {
        dispatch({ type: 'SET_IS_LOADING', payload: false });
      }
    };

    if (projectId && isDrawerOpen) {
      getProject();
    }
  }, [projectId]);

  return (
    <Drawer
      open={isDrawerOpen}
      anchor='right'
      PaperProps={{
        sx: {
          padding: '30px',
          width: '33%'
        }
      }}
    >
      <FormProvider {...methods}>
        <form onSubmit={methods.handleSubmit(onSubmit)}>
          <Grid container spacing={2}>
            <Grid size={11}>
              <Typography variant='h4'>{`${mode.toString().toLowerCase().charAt(0).toUpperCase() + mode.toString().slice(1).toLowerCase()} Project`}</Typography>
            </Grid>
            <Grid display="flex" justifyContent="right" size={1}>
              <IconButton onClick={onCancel}>
                <Icon iconName={IconName.XMARK} />
              </IconButton>
            </Grid>
            {state.error && (
              <Grid display="flex" justifyContent="center" size={12}>
                <Alert
                  onClose={() =>
                    dispatch({ type: 'SET_ERROR', payload: undefined })
                  }
                  severity="error"
                  sx={{ width: '100%' }}
                >
                  {state.error}
                </Alert>
              </Grid>
            )}
            <Grid alignItems="center" display="flex" size={4}>
              <Typography variant="body1">Order</Typography>
            </Grid>
            <Grid size={8}>
              <Controller
                name="order"
                control={methods.control}
                render={({ field: { onChange, value } }) => (
                  <TextField
                    disabled={state.isDisabled}
                    error={methods.formState.errors.siteUrl ? true : false}
                    fullWidth
                    helperText={
                      methods.formState.errors.siteUrl
                        ? methods.formState.errors.siteUrl.message?.toString()
                        : undefined
                    }
                    onChange={onChange}
                    value={value}
                  />
                )}
              />
            </Grid>
            <Grid alignItems="center" display="flex" size={4}>
              <Typography variant="body1">Title</Typography>
            </Grid>
            <Grid size={8}>
              <Controller
                name="title"
                control={methods.control}
                render={({ field: { onChange, value } }) => (
                  <TextField
                    disabled={state.isDisabled}
                    error={methods.formState.errors.title ? true : false}
                    fullWidth
                    helperText={
                      methods.formState.errors.title
                        ? methods.formState.errors.title.message?.toString()
                        : undefined
                    }
                    onChange={onChange}
                    value={value}
                  />
                )}
              />
            </Grid>
            <Grid alignItems="center" display="flex" size={4}>
              <Typography variant="body1">Sub Title</Typography>
            </Grid>
            <Grid size={8}>
              <Controller
                name="subTitle"
                control={methods.control}
                render={({ field: { onChange, value } }) => (
                  <TextField
                    disabled={state.isDisabled}
                    error={methods.formState.errors.siteUrl ? true : false}
                    fullWidth
                    helperText={
                      methods.formState.errors.siteUrl
                        ? methods.formState.errors.siteUrl.message?.toString()
                        : undefined
                    }
                    onChange={onChange}
                    value={value}
                  />
                )}
              />
            </Grid>
            <Grid alignItems="center" display="flex" size={4}>
              <Typography variant="body1">Icon Name</Typography>
            </Grid>
            <Grid size={8}>
              <Controller
                name="iconName"
                control={methods.control}
                render={({ field: { onChange, value } }) => (
                  <TextField
                    disabled={state.isDisabled}
                    error={methods.formState.errors.iconName ? true : false}
                    fullWidth
                    helperText={
                      methods.formState.errors.iconName
                        ? methods.formState.errors.iconName.message?.toString()
                        : undefined
                    }
                    onChange={onChange}
                    value={value}
                  />
                )}
              />
            </Grid>
            <Grid alignItems="center" display="flex" size={4}>
              <Typography variant="body1">Repo Name</Typography>
            </Grid>
            <Grid size={8}>
              <Controller
                name="repoName"
                control={methods.control}
                render={({ field: { onChange, value } }) => (
                  <TextField
                    disabled={state.isDisabled}
                    error={methods.formState.errors.repoName ? true : false}
                    fullWidth
                    helperText={
                      methods.formState.errors.repoName
                        ? methods.formState.errors.repoName.message?.toString()
                        : undefined
                    }
                    onChange={onChange}
                    value={value}
                  />
                )}
              />
            </Grid>
          <Grid alignItems="center" display="flex" size={4}>
            <Typography variant="body1">Site URL</Typography>
          </Grid>
          <Grid size={8}>
            <Controller
              name="siteUrl"
              control={methods.control}
              render={({ field: { onChange, value } }) => (
                <TextField
                  disabled={state.isDisabled}
                  error={methods.formState.errors.siteUrl ? true : false}
                  fullWidth
                  helperText={
                    methods.formState.errors.siteUrl
                      ? methods.formState.errors.siteUrl.message?.toString()
                      : undefined
                  }
                  onChange={onChange}
                  value={value}
                />
              )}
            />
          </Grid>
          <Grid alignItems="center" display="flex" size={4}>
            <Typography variant="body1">Summary</Typography>
          </Grid>
          <Grid size={8}>
            <Controller
              name="summary"
              control={methods.control}
              render={({ field: { onChange, value } }) => (
                <TextField
                  disabled={state.isDisabled}
                  error={methods.formState.errors.summary ? true : false}
                  fullWidth
                  helperText={
                    methods.formState.errors.summary
                      ? methods.formState.errors.summary.message?.toString()
                      : undefined
                  }
                  multiline
                  maxRows={5}
                  onChange={onChange}
                  value={value}
                />
              )}
            />
          </Grid>
          <Grid display="flex" gap={2} justifyContent="right" size={12}>
              <Button
                disabled={
                  state.isDisabled && mode.toString() !== FormMode.VIEW
                    ? state.isDisabled
                    : false
                }
                startIcon={<Icon iconName={IconName.XMARK} />}
                variant="outlined"
                onClick={onCancel}
                size="small"
              >
                {mode.toString() !== FormMode.VIEW ? 'Cancel' : 'Close'}
              </Button>
              {mode.toString() !== FormMode.VIEW && (
                <Button
                  disabled={state.isDisabled}
                  startIcon={<Icon iconName={IconName.SAVE} />}
                  size="small"
                  type="submit"
                  variant="contained"
                >
                  Save
                </Button>
              )}
            </Grid>
          </Grid>
        </form>
      </FormProvider>
    </Drawer>
  )
}

export default ProjectForm;