import clsx from "clsx";
import React from "react";

import {
  BoxBackground,
  ThemedSenseRowBoxSvg,
  ThemedSenseRowSmallBoxSvg,
  ThemedSenseRowMinimalSvg,
} from "@dndbeyond/character-components/es";
import {
  CharacterTheme,
  Constants,
  FormatUtils,
  RuleDataUtils,
  SenseInfo,
} from "@dndbeyond/character-rules-engine/es";

import { TypeScriptUtils } from "../../../Shared/utils";
import styles from "./styles.module.css";

interface Props {
  passivePerception: number;
  passiveInvestigation: number;
  passiveInsight: number;
  senses: SenseInfo;
  rowStyle: "small" | "normal" | "minimal";
  onClick?: () => void;
  theme: CharacterTheme;
}
export default class Senses extends React.PureComponent<Props> {
  static defaultProps = {
    rowStyle: "normal",
  };

  handleClick = (evt: React.MouseEvent): void => {
    const { onClick } = this.props;

    if (onClick) {
      evt.stopPropagation();
      evt.nativeEvent.stopImmediatePropagation();
      onClick();
    }
  };

  getSenseSummary = (senseKey: Constants.SenseTypeEnum): string | null => {
    const { senses } = this.props;

    let senseValue = senses[senseKey];
    if (!senseValue) {
      return null;
    }

    return `${RuleDataUtils.getSenseTypeLabel(
      senseKey
    )} ${FormatUtils.renderDistance(senseValue)}`;
  };

  renderSummaryInfo = (): React.ReactNode => {
    let senseKeys: Array<Constants.SenseTypeEnum> = [
      Constants.SenseTypeEnum.BLINDSIGHT,
      Constants.SenseTypeEnum.DARKVISION,
      Constants.SenseTypeEnum.TREMORSENSE,
      Constants.SenseTypeEnum.TRUESIGHT,
    ];

    let senseSummaries: Array<string> = senseKeys
      .map((senseKey) => this.getSenseSummary(senseKey))
      .filter(TypeScriptUtils.isNotNullOrUndefined);

    return (
      <div
        className={clsx([
          styles.summary,
          !senseSummaries.length && styles.summaryEmpty,
        ])}
      >
        {!senseSummaries.length
          ? "Additional Sense Types"
          : senseSummaries.join(", ")}
      </div>
    );
  };

  render() {
    const {
      passiveInsight,
      passiveInvestigation,
      passivePerception,
      rowStyle,
      theme,
    } = this.props;

    let isMinimal = false;
    let StyleComponent: React.ComponentType<any> = ThemedSenseRowBoxSvg;
    if (rowStyle === "small") {
      StyleComponent = ThemedSenseRowSmallBoxSvg;
    } else if (rowStyle === "minimal") {
      StyleComponent = ThemedSenseRowMinimalSvg;
      isMinimal = true;
    }

    return (
      <div className={styles.senses} onClick={this.handleClick}>
        {isMinimal ? (
          <div className={styles.minimalRow}>
            <div className={styles.minimalItem}>
              <div className={styles.minimalCallout}>
                <BoxBackground
                  StyleComponent={StyleComponent}
                  theme={{
                    ...theme,
                    themeColor: `${theme?.themeColor}80`,
                  }}
                />
                <div className={styles.calloutValue}>{passivePerception}</div>
              </div>
              <div
                className={clsx([
                  styles.calloutLabel,
                  styles.minimalCalloutLabel,
                ])}
              >
                Perception
              </div>
            </div>
            <div className={styles.minimalItem}>
              <div className={styles.minimalCallout}>
                <BoxBackground
                  StyleComponent={StyleComponent}
                  theme={{
                    ...theme,
                    themeColor: `${theme?.themeColor}80`,
                  }}
                />
                <div className={styles.calloutValue}>
                  {passiveInvestigation}
                </div>
              </div>
              <div
                className={clsx([
                  styles.calloutLabel,
                  styles.minimalCalloutLabel,
                ])}
              >
                Investigation
              </div>
            </div>
            <div className={styles.minimalItem}>
              <div className={styles.minimalCallout}>
                <BoxBackground
                  StyleComponent={StyleComponent}
                  theme={{
                    ...theme,
                    themeColor: `${theme?.themeColor}80`,
                  }}
                />
                <div className={styles.calloutValue}>{passiveInsight}</div>
              </div>
              <div
                className={clsx([
                  styles.calloutLabel,
                  styles.minimalCalloutLabel,
                ])}
              >
                Insight
              </div>
            </div>
          </div>
        ) : (
          <div>
            <div className={styles.callout}>
              <BoxBackground
                StyleComponent={StyleComponent}
                theme={{
                  ...theme,
                  themeColor: `${theme?.themeColor}80`,
                }}
              />
              <div className={styles.calloutValue}>{passivePerception}</div>
              <div
                className={clsx([
                  styles.calloutLabel,
                  styles.regularCalloutLabel,
                ])}
              >
                Passive Perception
              </div>
            </div>
            <div className={styles.callout}>
              <BoxBackground
                StyleComponent={StyleComponent}
                theme={{
                  ...theme,
                  themeColor: `${theme?.themeColor}80`,
                }}
              />
              <div className={styles.calloutValue}>{passiveInvestigation}</div>
              <div
                className={clsx([
                  styles.calloutLabel,
                  styles.regularCalloutLabel,
                ])}
              >
                Passive Investigation
              </div>
            </div>
            <div className={styles.callout}>
              <BoxBackground
                StyleComponent={StyleComponent}
                theme={{
                  ...theme,
                  themeColor: `${theme?.themeColor}80`,
                }}
              />
              <div className={styles.calloutValue}>{passiveInsight}</div>
              <div
                className={clsx([
                  styles.calloutLabel,
                  styles.regularCalloutLabel,
                ])}
              >
                Passive Insight
              </div>
            </div>
          </div>
        )}
        {this.renderSummaryInfo()}
      </div>
    );
  }
}
