import React, { useContext, useState } from "react";
import Container from "react-bootstrap/Container";
import Image from "react-bootstrap/Image";
import ListGroup from "react-bootstrap/ListGroup";
import Button from "react-bootstrap/Button";
import Modal from "react-bootstrap/Modal";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import CopyToClipboard from "../CopyToClipboard";
import { Implementation } from "../../data/parseReportData";
import { Badge, badgesFor } from "../../data/Badge";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { ThemeContext } from "../../context/ThemeContext";
import {
  oneDark,
  oneLight,
} from "react-syntax-highlighter/dist/esm/styles/prism";
import "./EmbedBadges.css";

const EmbedBadges: React.FC<{
  implementation: Implementation;
}> = ({ implementation }) => {
  const allBadges = badgesFor(implementation);
  const { isDarkMode } = useContext(ThemeContext);

  const [activeFormat, setActiveFormat] = useState(supportedFormats[1]);
  const [activeBadge, setActiveBadge] = useState(allBadges.Metadata[0]);
  const [show, setShow] = useState(false);
  const badgeEmbed = activeFormat.generateEmbed(activeBadge);

  return (
    <>
      <Button variant="info" size="sm" onClick={() => setShow(true)}>
        Badges
      </Button>
      <Modal
        fullscreen="xl-down"
        contentClassName="px-4"
        dialogClassName="modal-width"
        show={show}
        onHide={() => setShow(false)}
      >
        <Modal.Header closeButton className="border-0 mt-4">
          <Modal.Title className="fs-5 ms-3">Badges</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          <Container className="px-5">
            <Row className="pb-3 gap-5 align-items-center">
              <Col sm={5} md={3} lg={2} className="order-2 order-md-1">
                <div>
                  {Object.entries(allBadges).map(([category, badges]) => (
                    <div key={category}>
                      <h6>{category}</h6>
                      <ListGroup variant="flush" className="pb-2">
                        {badges.map((badge) => (
                          <ListGroup.Item
                            key={badge.name}
                            action
                            active={badge.name === activeBadge.name}
                            onClick={() => setActiveBadge(badge)}
                          >
                            {badge.name}
                          </ListGroup.Item>
                        ))}
                      </ListGroup>
                    </div>
                  ))}
                </div>
              </Col>

              <Col
                sm={12}
                md={8}
                lg={6}
                xl
                className="overflow-auto order-1 order-md-2"
              >
                <div className="pb-3">
                  <p>
                    Bowtie regularly rebuilds a number of badges for
                    <code> {implementation.name}</code>.
                  </p>
                  <p>
                    If you are a maintainer, you may be interested in embedding
                    one or more of them in your documentation to show off! Here
                    are embeddable snippets for whatever documentation language
                    you are likely to be using. The badge will automatically
                    update as Bowtie re-runs its report, so no manual updating
                    should be necessary.
                  </p>
                </div>

                <hr className="mx-5 py-3" />
                <div className="font-monospace d-flex position-relative rounded mx-5">
                  <span className="m-2 position-absolute top-0 end-0">
                    <CopyToClipboard textToCopy={badgeEmbed} />
                  </span>
                  <SyntaxHighlighter
                    language={activeFormat.name.toLowerCase()}
                    style={isDarkMode ? oneDark : oneLight}
                    className="code-block"
                    wrapLongLines
                  >
                    {badgeEmbed}
                  </SyntaxHighlighter>
                </div>

                <Image
                  alt={activeBadge.name}
                  src={activeBadge.uri.href()}
                  className="d-block mx-auto my-5"
                />
                <hr className="mx-5 d-lg-none" />
              </Col>

              <div className="vr my-lg-5 px-0 order-3 d-none d-sm-block d-md-none d-lg-block"></div>
              <Col sm={4} md={5} lg xl={2} className="order-4 px-lg-0 pb-1">
                <hr className="hr d-block d-sm-none order-3 m-5 mt-0"></hr>
                <h5 className="ps-1">Format</h5>
                <ListGroup variant="flush">
                  {supportedFormats.map((format) => (
                    <ListGroup.Item
                      action
                      active={activeFormat === format}
                      onClick={() => setActiveFormat(format)}
                      key={format.name}
                    >
                      {format.name}
                    </ListGroup.Item>
                  ))}
                </ListGroup>
              </Col>
            </Row>
          </Container>
        </Modal.Body>
      </Modal>
    </>
  );
};

interface BadgeFormat {
  name: string;
  generateEmbed: (badge: Badge) => string;
}

const supportedFormats: BadgeFormat[] = [
  {
    name: "URL",
    generateEmbed: (badge) => `${badge.uri.href()}`,
  },
  {
    name: "Markdown",
    generateEmbed: (badge) => `![${badge.altText}](${badge.uri.href()})`,
  },
  {
    name: "reST",
    generateEmbed: (badge) =>
      `.. image:: ${badge.uri.href()}\n    :alt: ${badge.altText}`,
  },
  {
    name: "AsciiDoc",
    generateEmbed: (badge) => `image:${badge.uri.href()}[${badge.altText}]`,
  },
  {
    name: "HTML",
    generateEmbed: (badge) =>
      `<img alt="${badge.altText}" src="${badge.uri.href()}"/>`,
  },
];

export default EmbedBadges;
