import { Row } from "antd/lib/grid";
import Tooltip from "antd/lib/tooltip";
import classNames from "classnames";
import { ColorPickerInput } from "components/ColorPicker";
import ContextCard from "components/ContentCard";
import { Icon } from "components/Icon";
import { Text } from "components/Typography";
import {
  CUSTOM_THEME,
  DARK_THEME,
  LIGHT_THEME,
  OVERLAY_THEME,
} from "constants/profile-theme";
import { useDebouncedCallback } from "hooks/useDebouncedCallback";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { isMobile } from "react-device-detect";
import { useDispatch } from "react-redux";
import { useTypedSelector } from "redux/rootReducer";
import { setTalentProfileAction } from "redux/User/actions";
import { selectUserData } from "redux/User/selector";
import {
  TalentProfileThemeColor,
  TalentProfileThemeTypes,
  User,
} from "redux/User/types";
import { detectLightOrDark, isValidColorContrast } from "utils/color";
import config from "config";
import "./ProfileTheme.scss";

const THEME_TYPE_OPTIONS = [
  TalentProfileThemeTypes.LIGHT,
  TalentProfileThemeTypes.DARK,
  TalentProfileThemeTypes.CUSTOM,
];

const OVERLAY_TYPE_OPTIONS = [
  TalentProfileThemeTypes.LIGHT,
  TalentProfileThemeTypes.DARK,
];
interface ProfileThemeProps {
  className?: string;
  defaultCustomColor?: TalentProfileThemeColor;
  setDefaultCustomColor: (value: TalentProfileThemeColor) => void;
  firstThemeType?: TalentProfileThemeTypes;
  setFirstThemeType: (value?: TalentProfileThemeTypes) => void;
  isOnBoarding?: boolean;
}
const ProfileTheme: React.FC<ProfileThemeProps> = (props) => {
  const { className, isOnBoarding } = props;

  const {
    user,
    onChangeThemeType,
    showWarning,
    setShowWarning,
    onChangeBackgroundColor,
    getOverlayOptionActive,
    onChangeOverlayColor,
    onChangeTypographyColor,
  } = useProfileTheme(props);

  return (
    <div className={classNames("profile-theme", className)}>
      <div
        className={classNames(
          "onboarding-theme p__x--16 p__t--6 p__b--16",
          isOnBoarding && "active"
        )}
      >
        <div className="profile-theme__card">
          <Text
            preset="medium18"
            className="d--block m__b--8 leading-28"
            data-testid="profile-theme__subtitle"
          >
            Select Your Theme
          </Text>
          <div>
            <div className="profile-theme__card--theme-type">
              {THEME_TYPE_OPTIONS.map((option, index) => (
                <div
                  key={index}
                  className="profile-theme__card--theme-type__item--wrapper"
                >
                  <Text className="capitalize d--block leading-22 opacity--80 text--gray4">
                    {option.toLowerCase()}
                  </Text>
                  <div
                    key={index}
                    className={classNames({
                      "profile-theme__card--theme-type__item": true,
                      [`profile-theme__card--theme-type__item-${option.toLowerCase()}`]:
                        true,
                      "profile-theme__card--theme-type__item--active":
                        user?.talentProfile?.themeType === option,
                    })}
                    onClick={(event) => {
                      onChangeThemeType(option);
                    }}
                    data-testid={`profile-theme__toggle-${option.toLowerCase()}`}
                  >
                    <div className="profile-theme__card--theme-type__item--content">
                      {option === TalentProfileThemeTypes.CUSTOM ? (
                        <img
                          src={`${config.service.assetUrl}/assets/images/icon_custom_theme.png`}
                          className="profile-theme__card--theme-type__item--content--image"
                        />
                      ) : (
                        <div
                          className={classNames({
                            "profile-theme__card--theme-type__item--content__color--picker":
                              true,
                            [`profile-theme__card--theme-type__item--content__color--picker--${option.toLowerCase()}`]:
                              true,
                          })}
                        ></div>
                      )}
                    </div>
                  </div>
                </div>
              ))}
            </div>

            {showWarning && (
              <div className="m__t--20">
                <ContextCard
                  type="warning"
                  show={true}
                  content="This color combination may be hard to read. Try using a brighter background color and / or darker text color."
                  contentClassName="leading-20"
                  handleClose={() => setShowWarning(false)}
                />
              </div>
            )}

            <React.Fragment>
              <Text
                preset="medium18"
                className={classNames({
                  "d--block m__t--20 leading-28": true,
                  disabled:
                    user?.talentProfile?.themeType !==
                    TalentProfileThemeTypes.CUSTOM,
                })}
                data-testid="profile-theme__colors-title"
              >
                Colors
              </Text>
              <div
                className={classNames({
                  "profile-theme__card--theme-color": true,
                  disabled:
                    user?.talentProfile?.themeType !==
                    TalentProfileThemeTypes.CUSTOM,
                })}
                data-testid="profile-theme__colors"
              >
                <ColorPickerInput
                  className="m__t--8"
                  title="Background Color"
                  errorMessage={
                    !user?.talentProfile?.themeColor?.backgroundColor.replace(
                      "#",
                      ""
                    )
                      ? "Please add a background color"
                      : ""
                  }
                  value={
                    user?.talentProfile?.themeColor?.backgroundColor ||
                    CUSTOM_THEME.backgroundColor
                  }
                  onChange={(color) => onChangeBackgroundColor(color)}
                />
                <ColorPickerInput
                  className="m__t--20"
                  title="Typography & Icon Color"
                  errorMessage={
                    !user?.talentProfile?.themeColor?.typographyColor.replace(
                      "#",
                      ""
                    )
                      ? "Please add a typography & icon color"
                      : ""
                  }
                  value={
                    user?.talentProfile?.themeColor?.typographyColor ||
                    CUSTOM_THEME.typographyColor
                  }
                  onChange={(color) => onChangeTypographyColor(color)}
                />
              </div>
              <Row
                className={classNames({
                  "m__t--20 m__b--16": true,
                  disabled:
                    user?.talentProfile?.themeType !==
                    TalentProfileThemeTypes.CUSTOM,
                })}
                align="middle"
                data-testid="profile-theme__module-overlay-title"
              >
                <Text
                  preset="medium18"
                  className="d--block leading-28"
                  data-testid="profile-theme__module-overlay-title-text"
                >
                  Module Overlay
                </Text>
                <Tooltip
                  className="m__l--10 align__self--center"
                  overlayClassName="profile-theme__card--theme-overlay__tooltip"
                  placement={isMobile ? "bottom" : "bottomLeft"}
                  title="Overlay color is used to lighten or darken certain elements on the page, e.g. modules, in a way that blends in with your backround and branding. We recommend selecting the Lighten option for dark backgrounds and Darken option for light backgrounds. Recommended accent will apply automatically depending on your background and typography colors."
                  color={"#FFFFFF"}
                >
                  <div className="height--24 width--24">
                    <Icon name="question" width={24} height={24} />
                  </div>
                </Tooltip>
              </Row>
              <div
                className={classNames({
                  "profile-theme__card--theme-overlay": true,
                  disabled:
                    user?.talentProfile?.themeType !==
                    TalentProfileThemeTypes.CUSTOM,
                })}
                data-testid="profile-theme__module-overlay"
              >
                {OVERLAY_TYPE_OPTIONS.map((option, index) => (
                  <div
                    key={index}
                    className="profile-theme__card--theme-overlay__item--wrapper"
                  >
                    <Text className="capitalize d--block opacity--80 text--gray4 leading-22">
                      {`${option.toLowerCase()}en`}
                    </Text>
                    <div
                      key={index}
                      className={classNames({
                        "profile-theme__card--theme-overlay__item": true,
                        [`profile-theme__card--theme-overlay__item-${option.toLowerCase()}`]:
                          true,
                        "profile-theme__card--theme-overlay__item--active":
                          getOverlayOptionActive() === option,
                      })}
                      onClick={() => {
                        console.log("Click event fired!");
                        onChangeOverlayColor(option);
                      }}
                      data-testid={`profile-theme__overlay-${option.toLowerCase()}`}
                    >
                      <div className="profile-theme__card--theme-overlay__item--content">
                        <Icon name={`overlay-${option.toLowerCase()}` as any} />
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            </React.Fragment>
          </div>
        </div>
      </div>
    </div>
  );
};

export const useProfileTheme = ({
  defaultCustomColor,
  setDefaultCustomColor,
  firstThemeType,
  setFirstThemeType,
}: ProfileThemeProps) => {
  const dispatch = useDispatch();
  const user: User | null | undefined = useTypedSelector(selectUserData);

  const [showWarning, setShowWarning] = useState(false);

  const typographyColor = useMemo(
    () =>
      user?.talentProfile?.themeColor?.typographyColor ||
      DARK_THEME.typographyColor,
    [user]
  );

  const backgroundColor = useMemo(
    () =>
      user?.talentProfile?.themeColor?.backgroundColor ||
      DARK_THEME.backgroundColor,
    [user]
  );

  const overlayColor = useMemo(
    () =>
      user?.talentProfile?.themeColor?.overlayColor || DARK_THEME.overlayColor,
    [user]
  );

  useEffect(() => {
    setShowWarning(!isValidColorContrast(backgroundColor, typographyColor));
  }, [backgroundColor, typographyColor, overlayColor]);

  const onChangeThemeType = useCallback(
    (type: keyof typeof TalentProfileThemeTypes) => {
      dispatch(
        setTalentProfileAction({
          themeType: type,
        })
      );

      switch (type) {
        case TalentProfileThemeTypes.DARK:
          dispatch(
            setTalentProfileAction({
              themeColor: DARK_THEME,
            })
          );
          break;
        case TalentProfileThemeTypes.LIGHT:
          dispatch(
            setTalentProfileAction({
              themeColor: LIGHT_THEME,
            })
          );
          break;
        case TalentProfileThemeTypes.CUSTOM:
          const themeColor =
            firstThemeType === TalentProfileThemeTypes.CUSTOM
              ? defaultCustomColor
              : user?.talentProfile?.themeColor || DARK_THEME;
          dispatch(
            setTalentProfileAction({
              themeColor,
            })
          );
          break;
        default:
          break;
      }
    },
    [
      dispatch,
      user?.talentProfile?.themeColor,
      defaultCustomColor,
      firstThemeType,
    ]
  );

  const onChangeBackgroundColor = useDebouncedCallback((color: string) => {
    const themeColor = {
      ...user?.talentProfile?.themeColor,
      backgroundColor: color,
    };
    setDefaultCustomColor(themeColor as TalentProfileThemeColor);
    if (firstThemeType !== TalentProfileThemeTypes.CUSTOM) {
      setFirstThemeType(TalentProfileThemeTypes.CUSTOM);
    }
    const isLight = detectLightOrDark(color) === "light";
    themeColor.overlayColor = isLight
      ? OVERLAY_THEME.DARK.color
      : OVERLAY_THEME.LIGHT.color;
    dispatch(
      setTalentProfileAction({
        themeColor: themeColor,
      })
    );
  }, 500);

  const onChangeTypographyColor = useDebouncedCallback((color: string) => {
    const themeColor = {
      ...user?.talentProfile?.themeColor,
      typographyColor: color,
    };
    setDefaultCustomColor(themeColor as TalentProfileThemeColor);
    if (firstThemeType !== TalentProfileThemeTypes.CUSTOM) {
      setFirstThemeType(TalentProfileThemeTypes.CUSTOM);
    }
    dispatch(
      setTalentProfileAction({
        themeColor: themeColor,
      })
    );
  }, 500);

  const onChangeOverlayColor = useCallback(
    (color: string) => {
      const overlayColor =
        color === TalentProfileThemeTypes.DARK
          ? OVERLAY_THEME.DARK.color
          : OVERLAY_THEME.LIGHT.color;
      const themeColor = {
        ...user?.talentProfile?.themeColor,
        overlayColor: overlayColor,
        overlayOpacity: 0.1,
      };
      setDefaultCustomColor(themeColor as TalentProfileThemeColor);
      if (firstThemeType !== TalentProfileThemeTypes.CUSTOM) {
        setFirstThemeType(TalentProfileThemeTypes.CUSTOM);
      }
      dispatch(
        setTalentProfileAction({
          themeColor: themeColor,
        })
      );
    },
    [dispatch, user?.talentProfile?.themeColor]
  );

  const getOverlayOptionActive = () => {
    return user?.talentProfile?.themeColor?.overlayColor ===
      OVERLAY_THEME.DARK.color
      ? TalentProfileThemeTypes.DARK
      : TalentProfileThemeTypes.LIGHT;
  };

  return {
    user,
    onChangeThemeType,
    showWarning,
    setShowWarning,
    onChangeBackgroundColor,
    getOverlayOptionActive,
    onChangeOverlayColor,
    onChangeTypographyColor,
  };
};

export default ProfileTheme;
