/* eslint-disable spire/export-styles */
import { getFocalPointStyles } from "@insite/client-framework/Common/BasicSelectors";
import StyledWrapper from "@insite/client-framework/Common/StyledWrapper";
import Zone from "@insite/client-framework/Components/Zone";
import translate from "@insite/client-framework/Translate";
import { HasFields } from "@insite/client-framework/Types/ContentItemModel";
import WidgetModule from "@insite/client-framework/Types/WidgetModule";
import WidgetProps from "@insite/client-framework/Types/WidgetProps";
import baseTheme, { BaseTheme } from "@insite/mobius/globals/baseTheme";
import breakpointMediaQueries from "@insite/mobius/utilities/breakpointMediaQueries";
// eslint-disable-next-line spire/fenced-imports
import { TS } from "@insite/shell/TS";
import * as React from "react";
import { css } from "styled-components";

type FlexChild = {
    fields: {
        flexGrow: number;
        flexShrink: number;
        flexBasis: string;
    };
};

const enum fields {
    flexZones = "flexZones",
    gap = "gap",
    direction = "direction",
    wrap = "wrap",
    justifyContent = "justifyContent",
    alignItems = "alignItems",
    alignContent = "alignContent",
    isFullWidth = "isFullWidth",
    fullWidthStylingType = "fullWidthStylingType",
    fullWidthColor = "fullWidthColor",
    fullWidthImage = "fullWidthImage",
    fullWidthImageFocalPoint = "fullWidthImageFocalPoint",
}

interface Props extends WidgetProps {
    fields: {
        [fields.flexZones]: FlexChild[];
        [fields.gap]: number;
        [fields.direction]: string;
        [fields.wrap]: string;
        [fields.justifyContent]: string;
        [fields.alignItems]: string;
        [fields.alignContent]: string;
        [fields.isFullWidth]: boolean;
        [fields.fullWidthStylingType]: string;
        [fields.fullWidthColor]: string;
        [fields.fullWidthImage]: string;
        [fields.fullWidthImageFocalPoint]:
            | "topLeft"
            | "topCenter"
            | "topRight"
            | "centerLeft"
            | "center"
            | "centerRight"
            | "bottomLeft"
            | "bottomCenter"
            | "bottomRight";
    };
}

const FlexRow = (props: Props) => {
    const {
        fields: {
            flexZones,
            gap,
            direction,
            wrap,
            justifyContent,
            alignItems,
            alignContent,
            isFullWidth,
            fullWidthStylingType,
            fullWidthColor,
            fullWidthImage,
            fullWidthImageFocalPoint,
        },
        id,
    } = props;

    const zoneElements: JSX.Element[] = [];

    for (let x = 0; x < flexZones.length; x += 1) {
        const wrapperProps = getWrapperProps(flexZones[x]);
        zoneElements.push(
            <StyledWrapper key={x} {...wrapperProps} data-test-selector={`flexZone_${x}`}>
                <Zone normalWidth={true} contentId={id} zoneName={`FlexZone${x}`} />
            </StyledWrapper>,
        );
    }

    const fullWidthBackgroundCss = !isFullWidth
        ? undefined
        : fullWidthStylingType === "solidColor"
        ? `background-color: ${fullWidthColor};`
        : fullWidthStylingType === "image"
        ? `
              background-image: url("${fullWidthImage}");
              background-size: cover;
              ${getFocalPointStyles(fullWidthImageFocalPoint)}
          `
        : undefined;

    const fieldStyle = css`
        margin: 0 auto;
        display: flex;
        flex-direction: ${direction};
        flex-wrap: ${wrap};
        justify-content: ${justifyContent};
        align-items: ${alignItems};
        align-content: ${alignContent};
        gap: ${gap};
        ${({ theme }: { theme: BaseTheme }) => {
            if (isFullWidth) {
                return "max-width: 100%;";
            }

            const { maxWidths } = theme.breakpoints || baseTheme.breakpoints;
            return breakpointMediaQueries(
                theme,
                maxWidths.map(mw =>
                    mw
                        ? css`
                              max-width: ${mw}px;
                          `
                        : null,
                ),
            );
        }}
        ${fullWidthBackgroundCss}
    `;
    return <StyledWrapper css={fieldStyle}>{zoneElements}</StyledWrapper>;
};

function validateCssLength(value: string) {
    if (value === "") {
        return "";
    }
    const lengthRegex = /[\d]+([a-zA-Z]+|%)/gi;
    if (!lengthRegex.test(value) || value === "0") {
        return TS("Value must use a valid CSS length format (e.g. 10px or 30%)");
    }
    return null;
}

function getWrapperProps(options: FlexChild) {
    if (!options || !options.fields) {
        return;
    }
    const zoneOptions = options.fields;
    return {
        css: css`
            min-width: 0;
            flex-basis: ${zoneOptions.flexBasis};
            flex-grow: ${zoneOptions.flexGrow};
            flex-shrink: ${zoneOptions.flexShrink};
        `,
    };
}

const widgetModule: WidgetModule = {
    component: FlexRow,
    definition: {
        canAdd: context => context.permissions?.canUseAdvancedFeatures || false,
        group: "Basic",
        icon: "distribute-spacing-vertical",
        fieldDefinitions: [
            {
                name: fields.gap,
                displayName: "Gap Between Zones",
                editorTemplate: "TextField",
                defaultValue: "",
                fieldType: "Contextual",
                validate: validateCssLength,
            },
            {
                name: fields.direction,
                editorTemplate: "DropDownField",
                defaultValue: "row",
                fieldType: "Contextual",
                options: [
                    {
                        displayName: "Row",
                        value: "row",
                    },
                    {
                        displayName: "Row Reverse",
                        value: "row-reverse",
                    },
                    {
                        displayName: "Column",
                        value: "column",
                    },
                    {
                        displayName: "Column Reverse",
                        value: "column-reverse",
                    },
                ],
            },
            {
                name: fields.wrap,
                editorTemplate: "DropDownField",
                defaultValue: "nowrap",
                fieldType: "Contextual",
                options: [
                    {
                        displayName: "No Wrap",
                        value: "nowrap",
                    },
                    {
                        displayName: "Wrap",
                        value: "wrap",
                    },
                    {
                        displayName: "Wrap Reverse",
                        value: "wrap-reverse",
                    },
                ],
            },
            {
                name: fields.justifyContent,
                editorTemplate: "DropDownField",
                defaultValue: "flex-start",
                fieldType: "Contextual",
                options: [
                    {
                        displayName: "Start",
                        value: "flex-start",
                    },
                    {
                        displayName: "End",
                        value: "flex-end ",
                    },
                    {
                        displayName: "Center",
                        value: "center",
                    },
                ],
            },
            {
                name: fields.alignItems,
                editorTemplate: "DropDownField",
                defaultValue: "stretch",
                fieldType: "Contextual",
                options: [
                    {
                        displayName: "Stretch",
                        value: "stretch",
                    },
                    {
                        displayName: "Start",
                        value: "flex-start",
                    },
                    {
                        displayName: "End",
                        value: "flex-end",
                    },
                    {
                        displayName: "Center",
                        value: "center",
                    },
                    {
                        displayName: "Baseline",
                        value: "baseline",
                    },
                ],
            },
            {
                name: fields.alignContent,
                editorTemplate: "DropDownField",
                defaultValue: "normal",
                fieldType: "Contextual",
                isVisible: (item: HasFields) => {
                    return item.fields[fields.wrap]?.startsWith("wrap");
                },
                options: [
                    {
                        displayName: "Normal",
                        value: "normal",
                    },
                    {
                        displayName: "Start",
                        value: "start",
                    },
                    {
                        displayName: "End",
                        value: "end",
                    },
                    {
                        displayName: "Flex Start",
                        value: "flex-start",
                    },
                    {
                        displayName: "Flex End",
                        value: "flex-end",
                    },
                    {
                        displayName: "Center",
                        value: "center",
                    },
                    {
                        displayName: "Space Between",
                        value: "space-between",
                    },
                    {
                        displayName: "Space Around",
                        value: "space-around",
                    },
                    {
                        displayName: "Space Evenly",
                        value: "space-evenly",
                    },
                    {
                        displayName: "Stretch",
                        value: "stretch",
                    },
                    {
                        displayName: "Baseline",
                        value: "baseline",
                    },
                ],
            },

            {
                name: fields.isFullWidth,
                displayName: "Full Width",
                editorTemplate: "CheckboxField",
                defaultValue: false,
                fieldType: "General",
                isVisible: (_item, _advancedFeaturesEnabled, theme) => !!theme?.content?.isFullWidth,
            },
            {
                name: fields.fullWidthStylingType,
                displayName: "Styling",
                editorTemplate: "RadioButtonsField",
                options: [
                    {
                        displayName: "Solid Color",
                        value: "solidColor",
                    },
                    {
                        displayName: "Image",
                        value: "image",
                    },
                ],
                defaultValue: "solidColor",
                horizontal: true,
                fieldType: "General",
                isVisible: ({ fields: { isFullWidth } }, _advancedFeaturesEnabled, theme) =>
                    !!theme?.content?.isFullWidth && !!isFullWidth,
            },
            {
                name: fields.fullWidthColor,
                displayName: "Color",
                editorTemplate: "ColorPickerField",
                defaultValue: "transparent",
                fieldType: "General",
                isVisible: ({ fields: { isFullWidth, fullWidthStylingType } }, _advancedFeaturesEnabled, theme) =>
                    !!theme?.content?.isFullWidth && !!isFullWidth && fullWidthStylingType === "solidColor",
            },
            {
                name: fields.fullWidthImage,
                displayName: "Image",
                editorTemplate: "ImagePickerField",
                defaultValue: "",
                fieldType: "General",
                isVisible: ({ fields: { isFullWidth, fullWidthStylingType } }, _advancedFeaturesEnabled, theme) =>
                    !!theme?.content?.isFullWidth && !!isFullWidth && fullWidthStylingType === "image",
            },
            {
                name: fields.fullWidthImageFocalPoint,
                displayName: "Focal Point",
                editorTemplate: "DropDownField",
                options: [
                    { displayName: "Top Left", value: "topLeft" },
                    { displayName: "Top Center", value: "topCenter" },
                    { displayName: "Top Right", value: "topRight" },
                    { displayName: "Center Left", value: "centerLeft" },
                    { displayName: "Center", value: "center" },
                    { displayName: "Center Right", value: "centerRight" },
                    { displayName: "Bottom Left", value: "bottomLeft" },
                    { displayName: "Bottom Center", value: "bottomCenter" },
                    { displayName: "Bottom Right", value: "bottomRight" },
                ],
                defaultValue: "center",
                fieldType: "General",
                hideEmptyOption: true,
                isVisible: ({ fields: { isFullWidth, fullWidthStylingType } }, _advancedFeaturesEnabled, theme) =>
                    !!theme?.content?.isFullWidth && !!isFullWidth && fullWidthStylingType === "image",
            },
            {
                name: fields.flexZones,
                editorTemplate: "ListField",
                getDisplay: (item: HasFields, state) => {
                    return translate("Zone");
                },
                defaultValue: [],
                fieldType: "General",
                fieldDefinitions: [
                    {
                        name: "flexGrow",
                        editorTemplate: "IntegerField",
                        defaultValue: 1,
                        min: 0,
                    },
                    {
                        name: "flexShrink",
                        editorTemplate: "IntegerField",
                        defaultValue: 1,
                        min: 0,
                    },
                    {
                        name: "flexBasis",
                        editorTemplate: "TextField",
                        defaultValue: "",
                        validate: validateCssLength,
                    },
                ],
            },
        ],
    },
};

export default widgetModule;
