// External dependencies.
import React, { ReactElement } from 'react';

// Divi dependencies.
import {
	StyleContainer,
	StylesProps,
} from '@divi/module';

// Local dependencies.
import { ListingCalendarAttrs } from './types';
import {
	createBorderStyles,
	createSpacingStyles,
	createTypographyStyles,
	extractBorderAttrs,
	extractSpasingAttrs,
	extractTypographyAttrs,
} from '../../utils';

const ModuleStyles = ({
	settings,
	mode,
	state,
	noStyleTag,
	elements,
	attrs,
	orderClass,
}: StylesProps<ListingCalendarAttrs>): ReactElement => {
	const selectors = {
		caption: `${orderClass} .jet-calendar-caption`,
		captionWrap: `${orderClass} .jet-calendar-caption__wrap`,
		captionName: `${orderClass} .jet-calendar-caption__name`,
		navLink: `${orderClass} .jet-calendar-nav__link`,
		navLinkNext: `${orderClass} .jet-calendar-nav__link.nav-link-next`,
		navLinkHover: `${orderClass} .jet-calendar-nav__link:hover`,
		weekDay: `${orderClass} .jet-calendar-header__week-day`,
		weekDayFirst: `${orderClass} .jet-calendar-header__week-day:first-child`,
		weekDayLast: `${orderClass} .jet-calendar-header__week-day:last-child`,
		day: `${orderClass} .jet-calendar-week__day`,
		dayContent: `${orderClass} .jet-calendar-week__day-content`,
		dayWrap: `${orderClass} .jet-calendar-week__day-wrap`,
		dayEventGap: `${orderClass} .jet-calendar-week__day-event + .jet-calendar-week__day-event`,
		dayDate: `${orderClass} .jet-calendar-week__day-date`,
		hasEventsDayDate: `${orderClass} .has-events .jet-calendar-week__day-date`,
		dayHeader: `${orderClass} .jet-calendar-week__day-header`,
		currentDay: `${orderClass} .jet-calendar-week__day.current-day`,
		currentDayDate: `${orderClass} .jet-calendar-week__day.current-day .jet-calendar-week__day-date`,
		disabledDay: `${orderClass} .jet-calendar-week__day.day-pad`,
		disabledDayDate: `${orderClass} .jet-calendar-week__day.day-pad .jet-calendar-week__day-date`,
		mobileTrigger: `${orderClass} .jet-calendar-week__day-mobile-trigger`,
		mobileTriggerActive: `${orderClass} .calendar-event-active .jet-calendar-week__day-mobile-trigger`,
		mobileWrap: `${orderClass} .jet-calendar-week__day-mobile-wrap`,
		mobileEvent: `${orderClass} .jet-calendar-week__day-mobile-event`,
	};

	const decoration = attrs?.module?.decoration;
	const captionTypographyStyles = createTypographyStyles( selectors.captionName, extractTypographyAttrs( decoration?.captionTypography ) );
	const captionSpacingStyles = createSpacingStyles( selectors.caption, extractSpasingAttrs( decoration?.captionSpacing ) );
	const captionBorderStyles = createBorderStyles( selectors.caption, extractBorderAttrs( decoration?.captionBorder ) );
	const navBorderStyles = createBorderStyles( selectors.navLink, extractBorderAttrs( decoration?.navBorder ) );
	const navBorderNextStyles = createBorderStyles( selectors.navLinkNext, extractBorderAttrs( decoration?.navBorderNext ) );
	const weekTypographyStyles = createTypographyStyles( selectors.weekDay, extractTypographyAttrs( decoration?.weekTypography ) );
	const weekPaddingStyles = createSpacingStyles( selectors.weekDay, extractSpasingAttrs( decoration?.weekPadding ) );
	const dayPaddingStyles = createSpacingStyles( selectors.dayContent, extractSpasingAttrs( decoration?.dayPadding ) );
	const dayLabelTypographyStyles = createTypographyStyles( selectors.dayDate, extractTypographyAttrs( decoration?.dayLabelTypography ) );
	const dayLabelBorderStyles = createBorderStyles( selectors.dayDate, extractBorderAttrs( decoration?.dayLabelBorder ) );
	const dayLabelSpacingStyles = createSpacingStyles( selectors.dayDate, extractSpasingAttrs( decoration?.dayLabelSpacing ) );
	const mobileTriggerBorderStyles = createBorderStyles( selectors.mobileTrigger, extractBorderAttrs( decoration?.mobileTriggerBorder ) );
	const mobileTriggerSpacingStyles = createSpacingStyles( selectors.mobileTrigger, extractSpasingAttrs( decoration?.mobileTriggerSpacing ) );
	const mobileEventSpacingStyles = createSpacingStyles( selectors.mobileEvent, extractSpasingAttrs( decoration?.mobileEventSpacing ) );

	return (
		<StyleContainer mode={mode} state={state} noStyleTag={noStyleTag}>
			{elements.style({
				attrName: 'module',
				styleProps: {
					disabledOn: {
						disabledModuleVisibility: settings?.disabledModuleVisibility,
					},
					advancedStyles: [
						...captionTypographyStyles,
						...captionSpacingStyles,
						...captionBorderStyles,
						...navBorderStyles,
						...navBorderNextStyles,
						...weekTypographyStyles,
						...weekPaddingStyles,
						...dayPaddingStyles,
						...dayLabelTypographyStyles,
						...dayLabelBorderStyles,
						...dayLabelSpacingStyles,
						...mobileTriggerBorderStyles,
						...mobileTriggerSpacingStyles,
						...mobileEventSpacingStyles,
						{ componentName: 'divi/common', props: { property: 'background-color', selector: selectors.caption, attr: decoration?.captionBgColor } },
						{ componentName: 'divi/common', props: { property: 'color', selector: selectors.captionName, attr: decoration?.captionTextColor } },
						{ componentName: 'divi/common', props: { property: 'gap', selector: selectors.captionWrap, attr: decoration?.captionGap } },
						{ componentName: 'divi/common', props: { property: 'width', selector: selectors.navLink, attr: decoration?.navWidth } },
						{ componentName: 'divi/common', props: { property: 'height', selector: selectors.navLink, attr: decoration?.navHeight } },
						{ componentName: 'divi/common', props: { property: 'font-size', selector: selectors.navLink, attr: decoration?.navSize } },
						{ componentName: 'divi/common', props: { property: 'color', selector: selectors.navLink, attr: decoration?.navColor } },
						{ componentName: 'divi/common', props: { property: 'background-color', selector: selectors.navLink, attr: decoration?.navBackgroundColor } },
						{ componentName: 'divi/common', props: { property: 'color', selector: selectors.navLinkHover, attr: decoration?.navColorHover } },
						{ componentName: 'divi/common', props: { property: 'background-color', selector: selectors.navLinkHover, attr: decoration?.navBackgroundColorHover } },
						{ componentName: 'divi/common', props: { property: 'border-color', selector: selectors.navLinkHover, attr: decoration?.navBorderColorHover } },
						{ componentName: 'divi/common', props: { property: 'background-color', selector: selectors.weekDay, attr: decoration?.weekBgColor } },
						{ componentName: 'divi/common', props: { property: 'color', selector: selectors.weekDay, attr: decoration?.weekTextColor } },
						{ componentName: 'divi/common', props: { property: 'border-width', selector: selectors.weekDay, attr: decoration?.weekBorderWidth } },
						{ componentName: 'divi/common', props: { property: 'border-color', selector: selectors.weekDay, attr: decoration?.weekBorderColor } },
						{ componentName: 'divi/common', props: { property: 'border-left-color', selector: selectors.weekDayFirst, attr: decoration?.weekBorderColorFirst } },
						{ componentName: 'divi/common', props: { property: 'border-right-color', selector: selectors.weekDayLast, attr: decoration?.weekBorderColorLast } },
						{ componentName: 'divi/common', props: { property: 'background-color', selector: selectors.day, attr: decoration?.dayBgColor } },
						{ componentName: 'divi/common', props: { property: 'min-height', selector: selectors.dayContent, attr: decoration?.dayMinHeight } },
						{ componentName: 'divi/common', props: { property: 'min-height', selector: selectors.dayWrap, attr: decoration?.dayMinHeight } },
						{ componentName: 'divi/common', props: { property: 'margin-top', selector: selectors.dayEventGap, attr: decoration?.dayEventsGap } },
						{ componentName: 'divi/common', props: { property: 'border-width', selector: selectors.day, attr: decoration?.dayBorderWidth } },
						{ componentName: 'divi/common', props: { property: 'border-color', selector: selectors.day, attr: decoration?.dayBorderColor } },
						{ componentName: 'divi/common', props: { property: 'color', selector: selectors.dayDate, attr: decoration?.dayLabelColor } },
						{ componentName: 'divi/common', props: { property: 'background-color', selector: selectors.dayDate, attr: decoration?.dayLabelBgColor } },
						{ componentName: 'divi/common', props: { property: 'color', selector: selectors.hasEventsDayDate, attr: decoration?.dayLabelColorHasEvents } },
						{ componentName: 'divi/common', props: { property: 'background-color', selector: selectors.hasEventsDayDate, attr: decoration?.dayLabelBgColorHasEvents } },
						{ componentName: 'divi/common', props: { property: 'justify-content', selector: selectors.dayHeader, attr: decoration?.dayLabelAlignment } },
						{ componentName: 'divi/common', props: { property: 'justify-content', selector: selectors.dayDate, attr: decoration?.dayLabelTextAlignment } },
						{ componentName: 'divi/common', props: { property: 'width', selector: selectors.dayDate, attr: decoration?.dayLabelWidth } },
						{ componentName: 'divi/common', props: { property: 'height', selector: selectors.dayDate, attr: decoration?.dayLabelHeight } },
						{ componentName: 'divi/common', props: { property: 'background-color', selector: selectors.currentDay, attr: decoration?.currentDayBgColor } },
						{ componentName: 'divi/common', props: { property: 'color', selector: selectors.currentDayDate, attr: decoration?.currentDayLabelColor } },
						{ componentName: 'divi/common', props: { property: 'background-color', selector: selectors.currentDayDate, attr: decoration?.currentDayLabelBgColor } },
						{ componentName: 'divi/common', props: { property: 'border-color', selector: selectors.currentDayDate, attr: decoration?.currentDayLabelBorderColor } },
						{ componentName: 'divi/common', props: { property: 'opacity', selector: selectors.disabledDay, attr: decoration?.dayOpacity } },
						{ componentName: 'divi/common', props: { property: 'background-color', selector: selectors.disabledDay, attr: decoration?.dayBgColorDisabled } },
						{ componentName: 'divi/common', props: { property: 'border-color', selector: selectors.disabledDay, attr: decoration?.dayBorderColorDisabled } },
						{ componentName: 'divi/common', props: { property: 'color', selector: selectors.disabledDayDate, attr: decoration?.dayLabelColorDisabled } },
						{ componentName: 'divi/common', props: { property: 'background-color', selector: selectors.disabledDayDate, attr: decoration?.dayLabelBgColorDisabled } },
						{ componentName: 'divi/common', props: { property: 'border-color', selector: selectors.disabledDayDate, attr: decoration?.dayLabelBorderColorDisabled } },
						{ componentName: 'divi/common', props: { property: 'background-color', selector: selectors.mobileTrigger, attr: decoration?.mobileTriggerColor } },
						{ componentName: 'divi/common', props: { property: 'background-color', selector: selectors.mobileTriggerActive, attr: decoration?.mobileTriggerColorActive } },
						{ componentName: 'divi/common', props: { property: 'width', selector: selectors.mobileTrigger, attr: decoration?.mobileTriggerWidth } },
						{ componentName: 'divi/common', props: { property: 'height', selector: selectors.mobileTrigger, attr: decoration?.mobileTriggerHeight } },
						{ componentName: 'divi/common', props: { property: 'justify-content', selector: selectors.mobileWrap, attr: decoration?.mobileTriggerAlignment } },
					],
				},
			})}
		</StyleContainer>
	);
};

export {
	ModuleStyles,
};
