import { observer } from "mobx-react-lite";
import { Col, Row } from "reactstrap";
import { useTranslation } from "react-i18next";
import { sprintf } from "sprintf-js";
import { sanitize } from "dompurify";

import { useSiteStore } from "src/Stores";
import {
  AbilitySiteYell,
  CommentSiteYell,
  InviteSiteYell,
  LevelSiteYell,
  OnSiteYellInput,
  SiteYell,
  TVSiteYell,
} from "src/site/Site";
import {
  formatText,
  getAbilityUpText,
  getGenreText,
  getHitPointsClass,
} from "src/Utility";
import AvatarDrawing from "src/AvatarDrawing";
import AvatarTitle from "src/AvatarTitle";

import { ReactComponent } from "src/assets/TwitchGlitchPurple.svg";
import scss from "src/site/SiteYellItem.module.scss";
import SiteComponent from "src/site/SiteComponent";

const EventPB = require("src/Event_pb");

export default observer(
  ({
    data,
    onSiteYellInput,
  }: {
    data: SiteYell;
    onSiteYellInput: OnSiteYellInput;
  }) => {
    const { siteYellVariety, date, avatarID, avatarName, siteYell } = data;
    const { saveTraffic } = useSiteStore();
    const { t } = useTranslation();

    const doSiteYell = (siteYell: string) => {
      siteYell = siteYell.replace("&nbsp;", " ");
      const m = siteYell.match(/(http|https|mailto|rtmp):\/\/[^ ]+/i);
      if (m != null) {
        const t = m[0];

        if (
          !saveTraffic &&
          t.match(/(\.aac|\.flac|\.mid|\.midi|\.mp3|\.ogg|\.wav|\.wma)($|\?)/i)
        ) {
          return siteYell.replace(
            t,
            `<audio class="${scss.file}" src="${t}" controls></audio>`,
          );
        }

        if (
          !saveTraffic &&
          t.match(/(\.bmp|\.gif|\.heic|\.jpeg|\.jpg|\.png|\.webp)($|\?)/i)
        ) {
          return siteYell.replace(
            t,
            `<a href="${t}" target="_blank">
              <img class="${scss.file}" src="${t}" alt="">
            </a>`,
          );
        }

        if (
          !saveTraffic &&
          t.match(/(\.avi|\.mkv|\.mp4|\.mpeg|\.mpg|\.wmv)($|\?)/i)
        ) {
          return siteYell.replace(
            t,
            `<video class="${scss.file}" src="${t}" controls></video>`,
          );
        }

        return siteYell.replace(t, `<a href="${t}" target="_blank">${t}</a>`);
      }

      return siteYell;
    };

    switch (siteYellVariety) {
      case "@Enter":
        return (
          <Row
            className="g-0"
            style={{ flexWrap: "nowrap" }}
            onContextMenu={(e) => {
              e.preventDefault();
              avatarID && onSiteYellInput && onSiteYellInput(e, avatarID);
            }}
          >
            {avatarID && (
              <Col className="m-1" xs="auto">
                <AvatarDrawing avatarID={avatarID} />
              </Col>
            )}
            <Col className="m-1" xs="auto">
              {avatarID && <AvatarTitle avatarID={avatarID} />}{" "}
              <span>{avatarName}</span> <span className="date">{date}</span>
              <br />
              <span className={scss.enter}>{t("siteYellEnter")}</span>
            </Col>
          </Row>
        );
      case "@Quit":
        return (
          <Row
            className="g-0"
            style={{ flexWrap: "nowrap" }}
            onContextMenu={(e) => {
              e.preventDefault();
              avatarID && onSiteYellInput && onSiteYellInput(e, avatarID);
            }}
          >
            {avatarID && (
              <Col className="m-1" xs="auto">
                <AvatarDrawing avatarID={avatarID} />
              </Col>
            )}
            <Col className="m-1" xs="auto">
              {avatarID && <AvatarTitle avatarID={avatarID} />}{" "}
              <span>{avatarName}</span> <span className="date">{date}</span>
              <br />
              <span className={scss.quit}>{t("siteYellQuit")}</span>
            </Col>
          </Row>
        );
      case "@Site":
        return (
          <Row
            className="g-0"
            style={{ flexWrap: "nowrap" }}
            onContextMenu={(e) => {
              e.preventDefault();
              avatarID && onSiteYellInput && onSiteYellInput(e, avatarID);
            }}
          >
            {avatarID && (
              <Col className="m-1" xs="auto">
                <AvatarDrawing avatarID={avatarID} />
              </Col>
            )}
            <Col className="m-1" xs="auto">
              {avatarID && <AvatarTitle avatarID={avatarID} />}{" "}
              <span>{avatarName}</span> <span className="date">{date}</span>
              <br />
              <span className={scss.enter}>{t("siteYellNewSite")}</span>
            </Col>
          </Row>
        );
      case "@Net":
        return (
          <Row
            className="g-0"
            style={{ flexWrap: "nowrap" }}
            onContextMenu={(e) => {
              e.preventDefault();
              avatarID && onSiteYellInput && onSiteYellInput(e, avatarID);
            }}
          >
            {avatarID && (
              <Col className="m-1" xs="auto">
                <AvatarDrawing avatarID={avatarID} />
              </Col>
            )}
            <Col className="m-1" xs="auto">
              {avatarID && <AvatarTitle avatarID={avatarID} />}{" "}
              <span>{avatarName}</span> <span className="date">{date}</span>
              <br />
              <span className={scss.enter}>{t("siteYellNewNetSite")}</span>
            </Col>
          </Row>
        );
      case "@Notify":
        return (
          <Row className="g-0" style={{ flexWrap: "nowrap" }}>
            <Col className="m-1" xs="auto">
              <span className="taehui">{t("siteYellTaehui")}</span>{" "}
              <span className="date">{date}</span>
              <br />
              <span
                dangerouslySetInnerHTML={{
                  __html: doSiteYell(siteYell as string),
                }}
              />
            </Col>
          </Row>
        );
      case "@Invite": {
        const { siteID, siteName, avatarName } = siteYell as InviteSiteYell;
        return (
          <Row
            className="g-0"
            style={{ flexWrap: "nowrap" }}
            onContextMenu={(e) => {
              e.preventDefault();
              avatarID && onSiteYellInput && onSiteYellInput(e, avatarID);
            }}
          >
            {avatarID && (
              <Col className="m-1" xs="auto">
                <AvatarDrawing avatarID={avatarID} />
              </Col>
            )}
            <Col className="m-1" xs="auto">
              {avatarID && <AvatarTitle avatarID={avatarID} />}{" "}
              <span>{avatarName}</span> <span className="date">{date}</span>
              <br />
              <span
                className="route"
                onClick={() => {
                  SiteComponent.send({
                    eventID: EventPB.Event.EventID.ENTER_SITE,
                    text: JSON.stringify({
                      siteID,
                      siteCipher: "",
                    }),
                  });
                }}
              >
                {sprintf(t("siteYellInvite"), siteName)}
              </span>
            </Col>
          </Row>
        );
      }
      case "@TV":
        const { href, title, text } = siteYell as TVSiteYell;
        return (
          <Row className="g-0" style={{ flexWrap: "nowrap" }}>
            <Col className="m-1" xs="auto">
              <ReactComponent className={scss.tv} />
            </Col>
            <Col className="m-1" xs="auto">
              <span>{text}</span> <span className="date">{date}</span>
              <br />
              <span
                className="route"
                onClick={() => {
                  window.open(href);
                }}
              >
                {sprintf(t("siteYellTV"), title)}
              </span>
            </Col>
          </Row>
        );
      case "@Wiped":
        return (
          <Row className="g-0" style={{ flexWrap: "nowrap" }}>
            <Col
              className="m-1"
              xs="auto"
              onContextMenu={(e) => {
                e.preventDefault();
                avatarID && onSiteYellInput && onSiteYellInput(e, avatarID);
              }}
            >
              {avatarID && <AvatarDrawing avatarID={avatarID} />}
            </Col>
            <Col className="m-1" xs="auto">
              {avatarID && <AvatarTitle avatarID={avatarID} />}{" "}
              <span>{avatarName}</span> <span className="date">{date}</span>
              <br />
              <span>{t("wipedSiteYell")}</span>
            </Col>
          </Row>
        );
      case "@Comment": {
        const {
          avatarID,
          avatarName,
          title,
          artist,
          genre,
          level,
          levelText,
          stand,
          hitPointsMode,
        } = siteYell as CommentSiteYell;
        return (
          <Row
            className="g-0"
            style={{ flexWrap: "nowrap" }}
            onContextMenu={(e) => {
              e.preventDefault();
              avatarID && onSiteYellInput && onSiteYellInput(e, avatarID);
            }}
          >
            {avatarID && (
              <Col className="m-1" xs="auto">
                <AvatarDrawing avatarID={avatarID} />
              </Col>
            )}
            <Col className="m-1" xs="auto">
              {avatarID && <AvatarTitle avatarID={avatarID} />}{" "}
              <span>{avatarName}</span> <span className="date">{date}</span>
              <br />
              <span className={`level${level}`}>{levelText}</span>{" "}
              <span className="artist">{artist}</span>{" "}
              <span className="title">{title}</span>{" "}
              <span className="genre">{getGenreText(genre)}</span>
              <br />
              <span className={getHitPointsClass(hitPointsMode)}>
                {sprintf(t("textStand"), formatText(stand))}
              </span>
            </Col>
          </Row>
        );
      }
      case "@Ability": {
        const { avatarID, avatarName } = siteYell as AbilitySiteYell;
        return (
          <Row
            className="g-0"
            style={{ flexWrap: "nowrap" }}
            onContextMenu={(e) => {
              e.preventDefault();
              avatarID && onSiteYellInput && onSiteYellInput(e, avatarID);
            }}
          >
            {avatarID && (
              <Col className="m-1" xs="auto">
                <AvatarDrawing avatarID={avatarID} />
              </Col>
            )}
            <Col className="m-1" xs="auto">
              {avatarID && <AvatarTitle avatarID={avatarID} />}{" "}
              <span>{avatarName}</span> <span className="date">{date}</span>
              <br />
              <span>{getAbilityUpText(t, siteYell as AbilitySiteYell)}</span>
              <br />
            </Col>
          </Row>
        );
      }
      case "@Level": {
        const { avatarID, avatarName, title } = siteYell as LevelSiteYell;
        return (
          <Row
            className="g-0"
            style={{ flexWrap: "nowrap" }}
            onContextMenu={(e) => {
              e.preventDefault();
              avatarID && onSiteYellInput && onSiteYellInput(e, avatarID);
            }}
          >
            {avatarID && (
              <Col className="m-1" xs="auto">
                <AvatarDrawing avatarID={avatarID} />
              </Col>
            )}
            <Col className="m-1" xs="auto">
              {avatarID && <AvatarTitle avatarID={avatarID} />}{" "}
              <span>{avatarName}</span> <span className="date">{date}</span>
              <br />
              <span>{sprintf(t("wwwLevelClearText"), title)}</span>
              <br />
            </Col>
          </Row>
        );
      }
      case "":
        return (
          <>
            <span>{siteYell as string}</span>
            <br />
          </>
        );
      case null:
        return (
          <Row className="g-0" style={{ flexWrap: "nowrap" }}>
            <Col
              className="m-1"
              xs="auto"
              onContextMenu={(e) => {
                e.preventDefault();
                avatarID && onSiteYellInput && onSiteYellInput(e, avatarID);
              }}
            >
              {avatarID && <AvatarDrawing avatarID={avatarID} />}
            </Col>
            <Col className="m-1" xs="auto">
              {avatarID && <AvatarTitle avatarID={avatarID} />}{" "}
              <span>{avatarName}</span> <span className="date">{date}</span>
              <br />
              <span
                dangerouslySetInnerHTML={{
                  __html: doSiteYell(sanitize(siteYell as string)),
                }}
              />
            </Col>
          </Row>
        );
      default:
        return null;
    }
  },
);
