import { ThemeOptions } from '@mui/material'
import { createTheme, ThemeProvider } from '@mui/material/styles'
import { CSSProperties } from '@mui/styles'
import { DatePicker } from '@mui/x-date-pickers'
import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment'
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'
import { FieldInputProps, FormikProps } from 'formik'
import React from 'react'

import { CustomField } from './CustomField'

const DATE_SIZE = 32
const compactStyles = {
  '& > div': {
    minWidth: 256,
  },
  '& > div > div, & > div > div > div, & .MuiCalendarPicker-root': {
    width: 256,
  },
  '& .MuiTypography-caption': {
    width: DATE_SIZE,
    margin: 0,
  },
  '& .PrivatePickersSlideTransition-root': {
    minHeight: DATE_SIZE * 6,
  },
  '& .PrivatePickersSlideTransition-root [role="row"]': {
    margin: 0,
  },
  '& .MuiPickersDay-dayWithMargin': {
    margin: 0,
  },
  '& .MuiPickersDay-root': {
    width: DATE_SIZE,
    height: DATE_SIZE,
  },
  '& .MuiPickersArrowSwitcher-spacer': {
    width: 0,
  },
  '& [role="presentation"] .PrivatePickersFadeTransitionGroup-root': {
    marginRight: -1,
  },
}

const getTheme = (isCompact: boolean, baseThemeOptions?: object | null) => {
  if (isCompact) {
    return createTheme(
      Object.assign(baseThemeOptions ?? {}, {
        components: {
          MuiPaper: {
            defaultProps: {
              sx: compactStyles,
            },
          },
        },
      })
    )
  }

  return createTheme(baseThemeOptions ?? {})
}

export interface IDatePickerFieldProps {
  label: string;

  field: FieldInputProps<any>;
  form: FormikProps<any>;
  theme: 'dark' | 'light';
  themeOptions?: ThemeOptions & {
    input?: CSSProperties;
    checkbox?: CSSProperties;
  };

  useCompact?: boolean;
}

interface IOtherProps {
  [key: string]: any;
}

export const DatePickerField = ({
  label,
  field,
  form,
  theme,
  useCompact = true,
  themeOptions,
  dateFormat = 'DD/MM/YYYY',
  placeholder = 'dd/mm/yyyy',
}: IDatePickerFieldProps & IOtherProps) => (
  <ThemeProvider theme={getTheme(useCompact, themeOptions ?? null)}>
    <LocalizationProvider dateAdapter={AdapterMoment}>
      <DatePicker
        value={field.value || ''}
        onChange={value => form.setFieldValue(field.name, value)}
        PopperProps={{
          placement: 'bottom-start',
        }}
        showDaysOutsideCurrentMonth={true}
        disableFuture={true}
        inputFormat={dateFormat}
        mask="__/__/____"
        renderInput={(params: any) => (
          <CustomField
            {...params}
            inputProps={{ ...params.inputProps, placeholder }}
            theme={theme}
            field={{
              ...field,
              onChange: (
                evt: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>
              ) => {
                if (params.inputProps && params.inputProps.onChange) {
                  params.inputProps.onChange(evt)
                }
              },
            }}
            form={form}
            label={label}
            type="tel"
          />
        )}
      />
    </LocalizationProvider>
  </ThemeProvider>
)
