import { createTheme as createMuiTheme } from '@mui/material';
import { deepmerge } from '@mui/utils';
import tinyColor from 'tinycolor2';

import { getBorderRadius, getFontSize, getFontWeight } from 'utils';

import type { SimplePaletteColorOptions, ThemeOptions } from '@mui/material';
import type { WidgetTheme } from './Auth0Widget';

export const createTheme = (widgetTheme: WidgetTheme) => {
	const {
		auth0Theme: _auth0Theme,
		primaryColor = {},
		secondaryColor = {},
		logo,
		...theme
	} = widgetTheme || {};

	const auth0Theme: Theme.Settings = deepmerge(
		{
			colors: {
				primaryButton:
					(theme?.palette?.primary as SimplePaletteColorOptions)
						?.main ?? '#635dff',
				primaryButtonLabel: '#ffffff',
				secondaryButton: '#FFFFFFFF',
				secondaryButtonBorder: '#c9cace',
				secondaryButtonLabel:
					theme?.palette?.text?.primary ?? '#1e212a',
				baseFocusColor:
					(theme?.palette?.primary as SimplePaletteColorOptions)
						?.main ?? '#635dff',
				baseHoverColor: '#000000',
				linksFocusedComponents:
					(theme?.palette?.primary as SimplePaletteColorOptions)
						?.main ?? '#635dff',
				headerText: theme?.palette?.text?.primary ?? '#1e212a',
				bodyText: theme?.palette?.text?.primary ?? '#1e212a',
				widgetBackground:
					theme?.palette?.background?.paper ?? '#ffffff',
				widgetBorder: '#c9cace',
				inputLabelsPlaceholders:
					theme?.palette?.text?.secondary ?? '#65676e',
				inputFilledText: '#000000',
				inputBorder: '#c9cace',
				inputBackground: '#ffffff',
				icons: theme?.palette?.text?.secondary ?? '#65676e',
				error:
					(theme?.palette?.error as SimplePaletteColorOptions)
						?.main ?? '#d03c38',
				success:
					(theme?.palette?.success as SimplePaletteColorOptions)
						?.main ?? '#13a688',
			},
			fonts: {
				fontUrl: '',
				fontFamily:
					'ulp-font, -apple-system, BlinkMacSystemFont, Roboto, Helvetica, sans-serif',
				referenceTextSize: 16,
				title: {
					bold: false,
					size: 150,
				},
				subtitle: {
					bold: false,
					size: 87.5,
				},
				bodyText: {
					bold: false,
					size: 87.5,
				},
				buttonsText: {
					bold: false,
					size: 100,
				},
				inputLabels: {
					bold: false,
					size: 100,
				},
				links: {
					bold: true,
					size: 87.5,
				},
				linksStyle: 'normal',
			},
			widget: {
				logoPosition: 'center',
				logoUrl: '',
				logoHeight: 52,
				headerTextAlignment: 'center',
				socialButtonsLayout: 'bottom',
			},
			pageBackground: {
				pageLayout: 'center',
				backgroundColor: '#000000',
				backgroundImageUrl: '',
			},
			borders: {
				buttonBorderWeight: 1,
				buttonsStyle: 'rounded',
				buttonBorderRadius: 3,
				inputBorderWeight: 1,
				inputBorderRadius: 3,
				inputsStyle: 'rounded',
				widgetCornerRadius: 5,
				widgetBorderWeight: 0,
				showWidgetShadow: true,
			},
		},
		_auth0Theme
	);

	const defaultTheme: ThemeOptions = {
		mixins: {
			loginLayout: auth0Theme?.pageBackground?.pageLayout,
		},
		palette: {
			primary: {
				...deepmerge(
					{ main: auth0Theme.colors.primaryButton },
					primaryColor
				),
			},
			secondary: {
				...deepmerge(
					{ main: auth0Theme.colors.secondaryButton },
					secondaryColor
				),
			},
			error: {
				...deepmerge(
					{ main: auth0Theme.colors.error },
					theme?.palette?.error ?? {}
				),
			},
			success: {
				...deepmerge(
					{ main: auth0Theme.colors.success },
					theme?.palette?.success ?? {}
				),
			},
		},
		typography: {
			h1: {
				color: auth0Theme.colors.headerText,
				fontSize: getFontSize(
					auth0Theme.fonts.referenceTextSize,
					auth0Theme.fonts.title.size
				),
				fontWeight: getFontWeight(auth0Theme.fonts.title.bold),
			},
			h2: { color: auth0Theme.colors.headerText },
			h3: { color: auth0Theme.colors.headerText },
			h4: { color: auth0Theme.colors.headerText },
			h5: { color: auth0Theme.colors.headerText },
			h6: { color: auth0Theme.colors.headerText },
			body1: {
				color: auth0Theme.colors.bodyText,
				fontWeight: getFontWeight(auth0Theme.fonts.bodyText.bold),
				size: getFontSize(
					auth0Theme.fonts.referenceTextSize,
					auth0Theme.fonts.bodyText.size
				),
			},
			body2: {
				color: auth0Theme.colors.bodyText,
				fontWeight: getFontWeight(auth0Theme.fonts.subtitle.bold),
				size: getFontSize(
					auth0Theme.fonts.referenceTextSize,
					auth0Theme.fonts.subtitle.size
				),
			},
			fontFamily: auth0Theme.fonts.fontFamily,
			fontSize: auth0Theme.fonts.referenceTextSize,
			button: {
				textTransform: 'none',
				fontSize: getFontSize(
					auth0Theme.fonts.referenceTextSize,
					auth0Theme.fonts.buttonsText.size
				),
				fontWeight: getFontWeight(auth0Theme.fonts.buttonsText.bold),
			},
		},
		components: {
			MuiButtonBase: {
				defaultProps: {
					disableRipple: true,
					disableTouchRipple: true,
				},
				styleOverrides: {
					root: {
						':focus-visible': {
							backgroundColor: tinyColor(
								auth0Theme.colors.baseFocusColor
							)
								.setAlpha(0.15)
								.toRgbString(),
							borderColor: tinyColor(
								auth0Theme.colors.baseFocusColor
							)
								.setAlpha(0.15)
								.toRgbString(),
							boxShadow: `0 0 0 4px ${tinyColor(
								auth0Theme.colors.baseFocusColor
							)
								.setAlpha(0.15)
								.toRgbString()} !important`,
						},
						':hover': {
							backgroundColor: 'inherit',
							boxShadow: `inset 0 0 0 150px ${tinyColor(
								auth0Theme.colors.baseHoverColor
							)
								.setAlpha(0.1)
								.toRgbString()}`,
						},
					},
				},
			},
			MuiButton: {
				styleOverrides: {
					root: {
						borderRadius: getBorderRadius(
							auth0Theme.borders.buttonBorderRadius,
							auth0Theme.borders.buttonsStyle
						),
						borderWidth: `${auth0Theme.borders.buttonBorderWeight}px`,
						minHeight: 48,
					},
					text: {
						color: auth0Theme.colors.linksFocusedComponents,
						':hover': {
							backgroundColor: 'unset',
							boxShadow: 'unset',
							color: auth0Theme.colors.linksFocusedComponents,
						},
					},
				},
				variants: [
					{
						props: { variant: 'primary' },
						style: {
							color: auth0Theme.colors.primaryButtonLabel,
							backgroundColor: auth0Theme.colors.primaryButton,
							borderColor: 'unset',
							'&:hover': {
								backgroundColor:
									auth0Theme.colors.primaryButton,
							},
						},
					},
					{
						props: { variant: 'secondary' },
						style: {
							color: auth0Theme.colors.secondaryButtonLabel,
							backgroundColor: auth0Theme.colors.secondaryButton,
							// borderColor:
							// 	auth0Theme.colors.secondaryButtonBorder,
							border: `${auth0Theme.borders.buttonBorderWeight}px solid ${auth0Theme.colors.secondaryButtonBorder}`,
							'&:hover': {
								backgroundColor:
									auth0Theme.colors.secondaryButton,
							},
							'&.MuiLoadingButton-root': {
								border: `${auth0Theme.borders.buttonBorderWeight}px solid ${auth0Theme.colors.secondaryButtonBorder}`,
								color: auth0Theme.colors.secondaryButtonLabel,
								backgroundColor:
									auth0Theme.colors.secondaryButton,
							},
						},
					},
				],
			},
			MuiPaper: {
				styleOverrides: {
					root: {
						borderRadius: getBorderRadius(
							auth0Theme.borders.widgetCornerRadius
						),
						border: `${auth0Theme.borders.widgetBorderWeight}px solid ${auth0Theme.colors.widgetBorder}`,
						boxShadow: auth0Theme.borders.showWidgetShadow
							? '0 12px 40px rgba(0,0,0,0.12)'
							: 'none',
					},
				},
			},
			MuiIcon: {
				styleOverrides: {
					root: {
						color: auth0Theme.colors.icons,
					},
				},
			},
			MuiInputBase: {
				styleOverrides: {
					root: {
						fontSize: getFontSize(
							auth0Theme.fonts.referenceTextSize,
							auth0Theme.fonts.inputLabels.size
						),
						fontWeight: getFontWeight(
							auth0Theme.fonts.inputLabels.bold
						),
						'&::placeholder': {
							color: auth0Theme.colors.inputLabelsPlaceholders,
						},
					},

					input: {
						borderWidth: `${auth0Theme.borders.inputBorderWeight}px`,
						borderRadius: getBorderRadius(
							auth0Theme.borders.inputBorderRadius,
							auth0Theme.borders.inputsStyle
						),
						borderColor: auth0Theme.colors.inputBorder,
						backgroundColor: auth0Theme.colors.inputBackground,
						color: auth0Theme.colors.inputFilledText,
						fontSize: getFontSize(
							auth0Theme.fonts.referenceTextSize,
							auth0Theme.fonts.inputLabels.size
						),
						fontWeight: getFontWeight(
							auth0Theme.fonts.inputLabels.bold
						),
					},
				},
			},
			MuiOutlinedInput: {
				styleOverrides: {
					// This controls the :hover color of any input boxes
					root: {
						'&.Mui-focused .MuiOutlinedInput-notchedOutline': {
							borderColor:
								auth0Theme.colors.linksFocusedComponents,
							borderWidth: `${auth0Theme.borders.inputBorderWeight}px`,
						},
						'&.Mui-focused:hover fieldset': {
							borderColor:
								auth0Theme.colors.linksFocusedComponents,
							borderWidth: `${auth0Theme.borders.inputBorderWeight}px`,
						},
						':hover .MuiOutlinedInput-notchedOutline': {
							borderColor: auth0Theme.colors.inputBorder,
						},
					},
				},
			},
			MuiLink: {
				styleOverrides: {
					root: {
						fontSize: getFontSize(
							auth0Theme.fonts.referenceTextSize,
							auth0Theme.fonts.links.size
						),
						fontWeight: auth0Theme.fonts.links.bold
							? 'bold'
							: 'normal',
						textDecoration:
							auth0Theme.fonts.linksStyle === 'underlined'
								? 'underlined'
								: 'unset',
					},
				},
			},
		},
	};

	const mergedTheme = deepmerge(defaultTheme || {}, theme);

	console.group('=== THEME ===');
	console.log(JSON.stringify(mergedTheme, null, 2));
	console.groupEnd();

	return createMuiTheme(mergedTheme);
};
