import Dialog from '@mui/material/Dialog';
import DialogContent from '@mui/material/DialogContent';
import IconButton from '@mui/material/IconButton';
import Toolbar from '@mui/material/Toolbar';
import CloseIcon from '@mui/icons-material/Close';
import CommentTable, { Comment } from '~t/share/Comments';
import React, { useEffect, useMemo, useState } from 'react';
import axios from 'B/axios';
import { grey } from '@mui/material/colors';
import styled from 'styled-components/macro';
import ImagePreviewDialog, {
  PreviewImage,
} from '~t/share/dialogs/ImagePreviewDialog';
import {
  extractPreviewImagesFromHtml,
  findPreviewIndexByHref,
  getFileExtension,
  isPreviewableImageFileName,
  mapPreviewImagesFromItems,
  setPreviewHoverCursor,
} from '~t/share/dialogs/imagePreviewUtils';

interface Picture {
  id: number;
  picture: string;
}

interface JsonInterface {
  items: any;
  [key: string]: any;
}

const LocalDialog = styled(Dialog)`
  .MuiPaper-root {
    min-width: 22rem;
  }
`;

const FixTableLayout = styled.div`
  table {
    table-layout: auto !important;
  }
`;

declare var kiosk: any;
const InfoDialog = ({ open, close, ergID, erglngID, name }) => {
  const [json, setJson] = useState<JsonInterface>();
  const [mainComment, setMainComment] = useState('');
  const [pictuers, setPictures] = useState<Picture[]>([]);
  const [comments, setComments] = useState<Comment[]>([]);
  const [pointsTable, setPointsTable] = useState('');
  const [previewOpen, setPreviewOpen] = useState(false);
  const [previewIndex, setPreviewIndex] = useState(0);
  const [activePreviewImages, setActivePreviewImages] = useState<PreviewImage[]>([]);

  useEffect(() => {
    async function getInfo() {
      const r = await axios.get(`/api/erg/${ergID}/json`);
      try {
        const js = r.data;
        const commentItem = js.items.splice(0, 2)[1];
        const commentStr = commentItem?.d?.inp;
        setMainComment(commentStr);
        setJson(js);
      } catch (e) {
        setJson(null);
        setMainComment('');
        // eslint-disable-next-line no-console
        console.error(e);
      }
      const p = await axios.get(`/api/erg/${ergID}/pictures`);
      setPictures(p.data);

      const c = await axios.get(`/api/erg/${ergID}/comments`);
      setComments(c.data);

      const t = await axios.get(`/api/erg/${erglngID}/pointsTable`);
      setPointsTable(t.data);
    }

    if (ergID != null && open) {
      getInfo();
    }
  }, [ergID, erglngID, open]);

  useEffect(() => {
    const toggleCloseInterval = setInterval(() => {
      if (typeof kiosk !== 'undefined' && open) {
        close();
      }
    }, 60000);

    return () => {
      clearInterval(toggleCloseInterval);
    };
  });

  useEffect(() => {
    if (!open) {
      setPreviewOpen(false);
      setActivePreviewImages([]);
    }
  }, [open]);

  let c = [];
  if (json != null) {
    try {
      c = [...json.items];
    } catch (e) {
      c = [];
    }
  }

  let mainCommenView = null;
  if (mainComment !== '') {
    mainCommenView = <h4>{mainComment}</h4>;
  }

  let commentView = null;
  if (comments.length > 0) {
    commentView = <CommentTable comments={comments} />;
  }

  const pointsTableImages = useMemo(
    () => extractPreviewImagesFromHtml(pointsTable),
    [pointsTable],
  );

  const previewImages = useMemo<PreviewImage[]>(
    () =>
      mapPreviewImagesFromItems(pictuers, {
        getId: (picture) => picture.id,
        getSrc: (picture) => `/api/image/${picture.id}`,
        getFileName: (picture) => picture.picture,
      }),
    [pictuers],
  );

  const openPicturePreview = (pictureID: number) => {
    const imageIndex = previewImages.findIndex((image) => image.id === pictureID);
    if (imageIndex < 0) {
      return;
    }

    setActivePreviewImages(previewImages);
    setPreviewIndex(imageIndex);
    setPreviewOpen(true);
  };

  const openPointsTablePreview = (event: React.MouseEvent<HTMLDivElement>) => {
    const target = event.target as HTMLElement | null;
    const link = target?.closest('a');
    const href = link?.getAttribute('href');
    if (!link || !href) {
      return;
    }

    const imageIndex = findPreviewIndexByHref(pointsTableImages, href);
    if (imageIndex < 0) {
      return;
    }

    event.preventDefault();
    setActivePreviewImages(pointsTableImages);
    setPreviewIndex(imageIndex);
    setPreviewOpen(true);
  };

  const updatePointsTableHoverCursor = (
    event: React.MouseEvent<HTMLDivElement>,
  ) => {
    setPreviewHoverCursor(event.target as HTMLElement | null, pointsTableImages);
  };

  let pointsView = null;
  if (pointsTable !== '') {
    pointsView = (
      <FixTableLayout>
        <div
          onClick={openPointsTablePreview}
          onMouseOver={updatePointsTableHoverCursor}
          dangerouslySetInnerHTML={{ __html: pointsTable }}
        />
      </FixTableLayout>
    );
  }

  const FileViewer = ({ fileName, ID }: { fileName: string; ID: number }) => {
    const extension = getFileExtension(fileName);
    let view = null;

    switch (extension) {
      case 'pdf':
        {
          const openWindow = (e) => {
            e.preventDefault();
            const pdfWindow = window.open(
              `/api/image/${ID}`,
              '_blank',
              'scrollbars=yes,resizable=yes,top=500,left=500,width=800,height=800'
            );
            setTimeout(() => {
              pdfWindow.close();
            }, 1000 * 60 * 5);
          };

          view = (
            <div style={{ width: '25%', margin: '0 1em' }}>
              <a href='#' onClick={openWindow}>
                <img src='/imgtasko/pdf.png' width='100' alt='PDF preview' />
                <br />
                {fileName}
              </a>
            </div>
          );
        }

        break;

      default:
        {
          const previewableImage = isPreviewableImageFileName(fileName);
          view = (
            <div style={{ width: '25%', margin: '0 1em' }}>
                <img
                  src={`/api/image/${ID}`}
                  alt={fileName}
                  style={{
                    width: '100%',
                    cursor: previewableImage ? 'zoom-in' : 'default',
                  }}
                  onClick={previewableImage ? () => openPicturePreview(ID) : undefined}
                />
            </div>
          );
        }
        break;
    }

    return view;
  };

  return (
    <>
      <LocalDialog open={open} onClose={close} fullWidth maxWidth='md'>
        <Toolbar style={{ backgroundColor: grey[500] }}>
          <h4 style={{ marginBottom: 0 }}>{name}</h4>
          <IconButton style={{ marginLeft: 'auto' }} onClick={close} size='large'>
            <CloseIcon />
          </IconButton>
        </Toolbar>
        <DialogContent>
          {mainCommenView}
          {pointsView}
          {commentView}
          <div style={{ display: 'flex' }}>
            {pictuers.map((p) => (
              <FileViewer key={p.id} ID={p.id} fileName={p.picture} />
            ))}
          </div>
        </DialogContent>
      </LocalDialog>

      <ImagePreviewDialog
        open={previewOpen}
        images={activePreviewImages}
        initialIndex={previewIndex}
        onClose={() => setPreviewOpen(false)}
      />
    </>
  );
};

export default InfoDialog;
