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

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

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

const popupBase = '.ui-datepicker';
const selectors = {
    filterContent: '.jet-date-range',
    inputs: '.jet-date-range__inputs',
    input: '.jet-date-range__inputs > input',
    applyButton: '.jet-date-range__submit.apply-filters__button',
    label: '.jet-filter-label',
    calendar: popupBase,
    calendarTitle: `${popupBase} .ui-datepicker-title`,
    prevSpan: `${popupBase}.ui-datepicker .ui-datepicker-prev > span`,
    nextSpan: `${popupBase}.ui-datepicker .ui-datepicker-next > span`,
    prevHoverSpan: `${popupBase}.ui-datepicker .ui-datepicker-prev:hover > span`,
    nextHoverSpan: `${popupBase}.ui-datepicker .ui-datepicker-next:hover > span`,
    weekHeader: `${popupBase} .ui-datepicker-calendar thead`,
    weekDay: `${popupBase} .ui-datepicker-calendar thead > tr > th`,
    weekDayContent: `${popupBase} .ui-datepicker-calendar thead > tr > th > span`,
    daysBody: `${popupBase} .ui-datepicker-calendar tbody`,
    dayCell: `${popupBase} .ui-datepicker-calendar tbody > tr > td`,
    dayCellFirst: `${popupBase} .ui-datepicker-calendar tbody > tr > td:first-child`,
    dayCellLast: `${popupBase} .ui-datepicker-calendar tbody > tr > td:last-child`,
    dayContent: `${popupBase} .ui-datepicker-calendar tbody > tr > td > span, ${popupBase} .ui-datepicker-calendar tbody > tr > td > a`,
    dayContentSpan: `${popupBase} .ui-datepicker-calendar tbody > tr > td > span`,
    dayContentLink: `${popupBase} .ui-datepicker-calendar tbody > tr > td > a`,
    dayContentHover: `${popupBase} .ui-datepicker-calendar tbody > tr > td > a:hover, ${popupBase} .ui-datepicker-calendar tbody > tr > td.ui-datepicker-today > a:hover`,
    dayContentActive: `${popupBase} .ui-datepicker-calendar tbody > tr > td > a.ui-state-active`,
    dayContentCurrent: `${popupBase} .ui-datepicker-calendar tbody > tr > td.ui-datepicker-today > a, ${popupBase} .ui-datepicker-calendar tbody > tr > td.ui-datepicker-today > span`,
};

const ModuleStyles = ({
	settings,
	mode,
	state,
	noStyleTag,
	elements,
	attrs,
	orderClass,
}: StylesProps<DateRangeFilterAttrs>): ReactElement => {
    const inputTypographyStyles = createTypographyStyles(`${orderClass} ${selectors.input}`, extractTypographyAttrs(attrs?.module?.decoration?.inputTypography));
    const inputBorderStyles = createBorderStyles(`${orderClass} ${selectors.input}`, extractBorderAttrs(attrs?.module?.decoration?.inputBorder));
    const inputSpacingStyles = createSpacingStyles(`${orderClass} ${selectors.input}`, extractSpasingAttrs(attrs?.module?.decoration?.inputSpacing));

    const calendarTypographyStyles = createTypographyStyles(selectors.calendar, extractTypographyAttrs(attrs?.module?.decoration?.calendarTypography));
    const calendarBorderStyles = createBorderStyles(selectors.calendar, extractBorderAttrs(attrs?.module?.decoration?.calendarBorder));
    const calendarSpacingStyles = createSpacingStyles(selectors.calendar, extractSpasingAttrs(attrs?.module?.decoration?.calendarSpacing));
    const calendarCaptionTypographyStyles = createTypographyStyles(selectors.calendarTitle, extractTypographyAttrs(attrs?.module?.decoration?.calendarCaptionTypography));

    const weekHeaderBorderStyles = createBorderStyles(selectors.weekHeader, extractBorderAttrs(attrs?.module?.decoration?.calendarWeekHeaderBorder));
    const weekDayPaddingStyles = createSpacingStyles(selectors.weekDay, extractSpasingAttrs(attrs?.module?.decoration?.calendarWeekDayPadding));
    const weekDayBorderStyles = createBorderStyles(selectors.weekDay, extractBorderAttrs(attrs?.module?.decoration?.calendarWeekDayBorder));
    const weekDayTypographyStyles = createTypographyStyles(selectors.weekDayContent, extractTypographyAttrs(attrs?.module?.decoration?.calendarWeekDayTypography));
    const weekDayContentBorderStyles = createBorderStyles(selectors.weekDayContent, extractBorderAttrs(attrs?.module?.decoration?.calendarWeekDayContentBorder));
    const weekDayContentPaddingStyles = createSpacingStyles(selectors.weekDayContent, extractSpasingAttrs(attrs?.module?.decoration?.calendarWeekDayContentPadding));

    const daysBorderStyles = createBorderStyles(selectors.daysBody, extractBorderAttrs(attrs?.module?.decoration?.calendarDaysBorder));
    const dayPaddingStyles = createSpacingStyles(selectors.dayCell, extractSpasingAttrs(attrs?.module?.decoration?.calendarDayPadding));
    const dayBorderStyles = createBorderStyles(selectors.dayCell, extractBorderAttrs(attrs?.module?.decoration?.calendarDayBorder));
    const dayTypographyStyles = createTypographyStyles(selectors.dayContent, extractTypographyAttrs(attrs?.module?.decoration?.calendarDayTypography));
    const dayContentBorderStyles = createBorderStyles(selectors.dayContent, extractBorderAttrs(attrs?.module?.decoration?.calendarDayContentBorder));
    const dayContentPaddingStyles = createSpacingStyles(selectors.dayContent, extractSpasingAttrs(attrs?.module?.decoration?.calendarDayContentPadding));

    const labelTypographyStyles = createTypographyStyles(`${orderClass} ${selectors.label}`, extractTypographyAttrs(attrs?.module?.decoration?.labelTypography));
    const applyTypographyStyles = createTypographyStyles(`${orderClass} ${selectors.applyButton}`, extractTypographyAttrs(attrs?.module?.decoration?.applyTypography));
    const applyBorderStyles = createBorderStyles(`${orderClass} ${selectors.applyButton}`, extractBorderAttrs(attrs?.module?.decoration?.applyBorder));
    const applySpacingStyles = createSpacingStyles(`${orderClass} ${selectors.applyButton}`, extractSpasingAttrs(attrs?.module?.decoration?.applySpacing));

	return (
		<StyleContainer mode={mode} state={state} noStyleTag={noStyleTag}>
			{elements.style({
				attrName: 'module',
				styleProps: {
					disabledOn: {
						disabledModuleVisibility: settings?.disabledModuleVisibility,
					},
                    advancedStyles: [
                        ...inputTypographyStyles,
                        ...inputBorderStyles,
                        ...inputSpacingStyles,
                        ...calendarTypographyStyles,
                        ...calendarBorderStyles,
                        ...calendarSpacingStyles,
                        ...calendarCaptionTypographyStyles,
                        ...weekHeaderBorderStyles,
                        ...weekDayPaddingStyles,
                        ...weekDayBorderStyles,
                        ...weekDayTypographyStyles,
                        ...weekDayContentBorderStyles,
                        ...weekDayContentPaddingStyles,
                        ...daysBorderStyles,
                        ...dayPaddingStyles,
                        ...dayBorderStyles,
                        ...dayTypographyStyles,
                        ...dayContentBorderStyles,
                        ...dayContentPaddingStyles,
                        ...labelTypographyStyles,
                        ...applyTypographyStyles,
                        ...applyBorderStyles,
                        ...applySpacingStyles,
                        { componentName: 'divi/common', props: { property: 'display', selector: `${orderClass} ${selectors.filterContent}`, attr: attrs?.module?.decoration?.contentPosition, declarationFunction: ({ attrValue }) => attrValue ? 'flex' : '' } },
                        { componentName: 'divi/common', props: { property: 'flex-direction', selector: `${orderClass} ${selectors.filterContent}`, attr: attrs?.module?.decoration?.contentPosition } },
                        { componentName: 'divi/common', props: { property: 'justify-content', selector: `${orderClass} ${selectors.filterContent}`, attr: attrs?.module?.decoration?.contentLineAlignment } },
                        { componentName: 'divi/common', props: { property: 'align-items', selector: `${orderClass} ${selectors.filterContent}`, attr: attrs?.module?.decoration?.contentBlockAlignment } },
                        { componentName: 'divi/common', props: { property: 'max-width', selector: `${orderClass} ${selectors.inputs}`, attr: attrs?.module?.decoration?.inputWidth } },
                        { componentName: 'divi/common', props: { property: 'color', selector: `${orderClass} ${selectors.input}`, attr: attrs?.module?.decoration?.inputColor } },
                        { componentName: 'divi/common', props: { property: 'color', selector: `${orderClass} ${selectors.input}::placeholder`, attr: attrs?.module?.decoration?.inputColor } },
                        { componentName: 'divi/common', props: { property: 'background-color', selector: `${orderClass} ${selectors.input}`, attr: attrs?.module?.decoration?.inputBackgroundColor } },
                        { componentName: 'divi/common', props: { property: 'margin-top', selector: selectors.calendar, attr: attrs?.module?.decoration?.calendarVerOffset } },
                        { componentName: 'divi/common', props: { property: 'margin-left', selector: selectors.calendar, attr: attrs?.module?.decoration?.calendarHorOffset } },
                        { componentName: 'divi/common', props: { property: 'width', selector: selectors.calendar, attr: attrs?.module?.decoration?.calendarWidth } },
                        { componentName: 'divi/common', props: { property: 'background-color', selector: selectors.calendar, attr: attrs?.module?.decoration?.calendarBgColor } },
                        { componentName: 'divi/common', props: { property: 'color', selector: selectors.calendarTitle, attr: attrs?.module?.decoration?.calendarCaptionColor } },
                        { componentName: 'divi/common', props: { property: 'border-width', selector: selectors.prevSpan, attr: attrs?.module?.decoration?.calendarPrevNextSize, declarationFunction: ({ attrValue }) => attrValue ? `calc(${attrValue} / 2) calc(${attrValue} / 2) calc(${attrValue} / 2) 0` : '' } },
                        { componentName: 'divi/common', props: { property: 'border-width', selector: selectors.nextSpan, attr: attrs?.module?.decoration?.calendarPrevNextSize, declarationFunction: ({ attrValue }) => attrValue ? `calc(${attrValue} / 2) 0 calc(${attrValue} / 2) calc(${attrValue} / 2)` : '' } },
                        { componentName: 'divi/common', props: { property: 'border-right-color', selector: selectors.prevSpan, attr: attrs?.module?.decoration?.calendarPrevNextNormalColor } },
                        { componentName: 'divi/common', props: { property: 'border-left-color', selector: selectors.nextSpan, attr: attrs?.module?.decoration?.calendarPrevNextNormalColor } },
                        { componentName: 'divi/common', props: { property: 'border-right-color', selector: selectors.prevHoverSpan, attr: attrs?.module?.decoration?.calendarPrevNextHoverColor } },
                        { componentName: 'divi/common', props: { property: 'border-left-color', selector: selectors.nextHoverSpan, attr: attrs?.module?.decoration?.calendarPrevNextHoverColor } },
                        { componentName: 'divi/common', props: { property: 'background-color', selector: selectors.weekHeader, attr: attrs?.module?.decoration?.calendarWeekHeaderBgColor } },
                        { componentName: 'divi/common', props: { property: 'color', selector: selectors.weekDayContent, attr: attrs?.module?.decoration?.calendarWeekDayColor } },
                        { componentName: 'divi/common', props: { property: 'background-color', selector: selectors.weekDayContent, attr: attrs?.module?.decoration?.calendarWeekDayBgColor } },
                        { componentName: 'divi/common', props: { property: 'background-color', selector: selectors.daysBody, attr: attrs?.module?.decoration?.calendarDaysBgColor } },
                        { componentName: 'divi/common', props: { property: 'color', selector: `${selectors.dayContentSpan}, ${selectors.dayContentLink}`, attr: attrs?.module?.decoration?.calendarDayDefaultColor } },
                        { componentName: 'divi/common', props: { property: 'background-color', selector: `${selectors.dayContentSpan}, ${selectors.dayContentLink}`, attr: attrs?.module?.decoration?.calendarDayDefaultBgColor } },
                        { componentName: 'divi/common', props: { property: 'color', selector: selectors.dayContentHover, attr: attrs?.module?.decoration?.calendarDayHoverColor } },
                        { componentName: 'divi/common', props: { property: 'background-color', selector: selectors.dayContentHover, attr: attrs?.module?.decoration?.calendarDayHoverBgColor } },
                        { componentName: 'divi/common', props: { property: 'border-color', selector: selectors.dayContentHover, attr: attrs?.module?.decoration?.calendarDayHoverBorderColor } },
                        { componentName: 'divi/common', props: { property: 'color', selector: selectors.dayContentActive, attr: attrs?.module?.decoration?.calendarDayActiveColor } },
                        { componentName: 'divi/common', props: { property: 'background-color', selector: selectors.dayContentActive, attr: attrs?.module?.decoration?.calendarDayActiveBgColor } },
                        { componentName: 'divi/common', props: { property: 'border-color', selector: selectors.dayContentActive, attr: attrs?.module?.decoration?.calendarDayActiveBorderColor } },
                        { componentName: 'divi/common', props: { property: 'color', selector: selectors.dayContentCurrent, attr: attrs?.module?.decoration?.calendarDayCurrentColor } },
                        { componentName: 'divi/common', props: { property: 'background-color', selector: selectors.dayContentCurrent, attr: attrs?.module?.decoration?.calendarDayCurrentBgColor } },
                        { componentName: 'divi/common', props: { property: 'border-color', selector: selectors.dayContentCurrent, attr: attrs?.module?.decoration?.calendarDayCurrentBorderColor } },
                        { componentName: 'divi/common', props: { property: 'text-align', selector: `${orderClass} ${selectors.label}`, attr: attrs?.module?.decoration?.labelAlignment } },
                        { componentName: 'divi/common', props: { property: 'color', selector: `${orderClass} ${selectors.label}`, attr: attrs?.module?.decoration?.labelColor } },
                        { componentName: 'divi/common', props: { property: 'margin-bottom', selector: `${orderClass} ${selectors.label}`, attr: attrs?.module?.decoration?.labelGapY } },
                        { componentName: 'divi/common', props: { property: 'color', selector: `${orderClass} ${selectors.applyButton}`, attr: attrs?.module?.decoration?.applyNormalColor } },
                        { componentName: 'divi/common', props: { property: 'background-color', selector: `${orderClass} ${selectors.applyButton}`, attr: attrs?.module?.decoration?.applyNormalBgColor } },
                        { componentName: 'divi/common', props: { property: 'color', selector: `${orderClass} ${selectors.applyButton}:hover`, attr: attrs?.module?.decoration?.applyHoverColor } },
                        { componentName: 'divi/common', props: { property: 'background-color', selector: `${orderClass} ${selectors.applyButton}:hover`, attr: attrs?.module?.decoration?.applyHoverBgColor } },
                        { componentName: 'divi/common', props: { property: 'border-color', selector: `${orderClass} ${selectors.applyButton}:hover`, attr: attrs?.module?.decoration?.applyHoverBorderColor } },
                        { componentName: 'divi/common', props: { property: 'align-self', selector: `${orderClass} ${selectors.applyButton}`, attr: attrs?.module?.decoration?.applyAlignment } },
                    ],
				},
			})}
		</StyleContainer>
	);
}

export {
	ModuleStyles,
};
