// resources\assets\ts\share\aufgaben-shared\components\DataTable.tsx
// original path: resources\assets\ts\DataPage\DataTable.tsx
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import {
  Box,
  Button,
  Chip,
  CircularProgress,
  Paper,
  TablePagination,
  TextField,
} from '@mui/material';
import { RootState } from './rootReducer';
import { Trans } from '@lingui/macro';
import {
  clearTable,
  markAsRead,
  toggleRead,
  onDetailSearchResultLimit,
  selectGroupEntities,
  selectTable,
  setRowsPerPage,
  setDirection,
  resetPagination,
  setPaginationIndex,
  setIsDisableNext,
} from './tableSlice';
import { fetchAll, fetchSearch } from './dataSlice';
import { fetchComments } from '../share/aufgaben-shared/slices/commentsSlice';
import { fetchPictures } from '../share/aufgaben-shared/slices/picturesSlice';
import { openTaskList } from './newTaskListSlice';
import { setPaginationHeight, tableNegativeHeightSelector } from './styleSlice';
import {
  setSearchStr,
  setTagsFilter,
} from '../share/aufgaben-shared/slices/filterSlice'; // neu
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import { useEditAndDeletePermission } from './permissionHooks';
import Card from '../share/aufgaben-shared/components/Card';
import Comments from '../share/aufgaben-shared/components/Comments';
import Details from '../share/aufgaben-shared/components/Detail';
import DocumentationView from './DocumentView';
import Picture from '../share/aufgaben-shared/components/Picture';
import ScheduledCardContainer from './ScheduledCard';
import axios from 'B/axios';
import pointsSlice, {
  fetchPoints,
  fetchPointsTable,
} from '../share/aufgaben-shared/slices/pointsSlice';
import styled from 'styled-components';
import { I18nProvider } from '@lingui/react';
import { i18n } from '@lingui/core';
import { englishDefaults } from 'fullcalendar/src/options';

import { setupI18n } from 'B/i18nSetup';
import Autocomplete from '@mui/material/Autocomplete';
import { table } from 'console';
import { fetchAllTags } from '../share/aufgaben-shared/slices/tagsSlice';
import { FixTableLayout } from '../share/aufgaben-shared/components/FixTableLayout';
import ImagePreviewDialog, {
  PreviewImage,
} from '../share/dialogs/ImagePreviewDialog';
import {
  extractPreviewImagesFromHtml,
  findPreviewIndexByHref,
  mapPreviewImagesFromItems,
  setPreviewHoverCursor,
} from '../share/dialogs/imagePreviewUtils';

setupI18n();

function isReadHelper(readLogs, tableRowItem, isOpenFilter) {
  if (isOpenFilter === false) return true;

  if (readLogs[tableRowItem.id] === undefined) {
    return false;
  }

  const isCurrentTaskRead = (readLogs[tableRowItem.id] as number[]).includes(
    tableRowItem.a1_agb_id,
  );
  if (isCurrentTaskRead) return true;

  const isOriginalTaskRead = (readLogs[tableRowItem.id] as number[]).includes(
    tableRowItem.agb_id,
  );
  if (isOriginalTaskRead) return true;

  // default is unread
  return false;
}

//CMS prototype now import from shared, see above imports
// helper to fix table layout to auto
// if removed it affects all parents table if label is set to fixed
// export const FixTableLayout = styled.div`
//   table {
//     table-layout: auto !important;
//   }
// `;

export default function DataTable() {
  const { canEdit, canDelete } = useEditAndDeletePermission();
  const comments = useSelector((state: RootState) => state.comments);
  const points = useSelector((state: RootState) => state.points);
  const pictures = useSelector((state: RootState) => state.pictures);
  const rowsPerPage = useSelector((s: RootState) => s.table.rowsPerPage);
  const page = useSelector((s: RootState) => s.table.paginationIndex);
  const isDisableNext = useSelector((s: RootState) => s.table.isDisableNext);
  const tableData = useSelector(selectTable);
  const isLoading = useSelector((s: RootState) => s.data.isLoading);
  const groupEntities = useSelector(selectGroupEntities);
  const cardListHeight = useSelector(tableNegativeHeightSelector);
  const isUpcoming =
    useSelector((s: RootState) => s.filter.taskState, shallowEqual) ===
    'upcoming';
  const readLogs = useSelector((s: RootState) => s.table.readLogs);
  const isOpenFilter =
    useSelector((s: RootState) => s.filter.taskState, shallowEqual) === 'open';
  const isOnDetailSearch = useSelector(
    (s: RootState) => s.table.isOnDetailSearch,
  );

  const d = useDispatch();
  const dispatch = useDispatch();

  const availableTags = useSelector((state: RootState) => state.tags.allTags);
  const selectedTags = useSelector(
    (s: RootState) => s.filter.selectedTags,
    shallowEqual,
  );
  const tagsEntities = useSelector(
    (s: RootState) => s.tags.entities,
    shallowEqual,
  );

  const pagination = React.useCallback(
    (paginationRef) => {
      if (paginationRef === null) return;
      const height = paginationRef.clientHeight;
      d(setPaginationHeight(height));
    },
    [d],
  );
  useEffect(() => {
    dispatch(fetchAllTags());
  }, [dispatch]);

  function onChangePage(_e, newPage) {
    d(setPaginationIndex(newPage));
    if (newPage > page) {
      d(setDirection('next'));
    } else {
      d(setDirection('prev'));
    }
    d(fetchAll(true));
  }

  function onChangeRowsPerPage(e) {
    const p = e.target.value ?? 10;
    d(setRowsPerPage(p));
    d(resetPagination());
    d(setPaginationIndex(0));
    d(fetchAll(false));
  }
  const onTagsChange = useCallback(
    (_: any, value: string[]) => {
      d(setTagsFilter(value));
      d(fetchSearch());
    },
    [d],
  );
  const pathArr = (groupID) => groupEntities[groupID]?.path ?? [];
  const handleEdit = (index) => () => {
    const t = tableData[index];
    d(markAsRead(t.id));

    const w = window.open(
      `form?ergid=${t.id}&resid=${t.erg_lngid}`,
      `form?ergid=${t.id}&resid=${t.erg_lngid}`,
      'width=600, height=600',
    );
    w.onbeforeunload = () => {
      d(clearTable());
      d(fetchAll());
    };
  };

  const recButton = (ergID) => {
    // let img = document.getElementsByTagName('img');
    // for (let i = 0; i < img.length; i++) {
    //   if (img[i].src.includes('/api/file')) {
    //     img[i].classList.add('rotate');
    //   }
    // }
    // ////console.log('here');
    // handlePointToggle(ergID);
  };
  const handleCommentToggle = (ergID) => () => {
    return d(fetchComments(ergID)).then(() => {
      d(markAsRead(ergID));
    });
  };
  const handleMarkAsRead = (id: number) => () => {
    d(markAsRead(id));
  };
  const handleToggleRead = (id: number) => () => {
    d(toggleRead(id));
  };
  const handlePointToggle = (ergID) => () => {
    return d(fetchPoints(ergID))
      .then(() => d(fetchPointsTable(ergID)))
      .then(() => {
        d(markAsRead(ergID));

        const rotateClasses = document.getElementsByClassName('rotate');
        for (let rotateElement of rotateClasses) {
          // Erstellt das Rotate-Button-Image
          const rotateButton = document.createElement('img');
          rotateButton.src = './imgtasko/pic_rotate.png';
          rotateButton.width = 32;
          rotateButton.height = 32;
          rotateButton.style.cursor = 'pointer';

          const elementSRC = (rotateElement as HTMLImageElement).src;
          const paths = elementSRC.split('/');
          const filename = paths.pop();

          rotateButton.onclick = () => {
            const rotatePath = `/comment/pic/rotatebyname/file/public/${filename}`;
            axios.get(rotatePath).then((r) => {
              (rotateElement as HTMLImageElement).src = `${
                (rotateElement as HTMLImageElement).src
              }?${new Date().getTime()}`; // Cache-Busting durch Timestamp
            });
          };

          const tdElement = rotateElement.parentNode.parentNode;

          if (canDelete) {
            const svg = document.createElementNS(
              'http://www.w3.org/2000/svg',
              'svg',
            );
            svg.setAttribute('width', '40px');
            svg.setAttribute('height', '40px');
            svg.setAttribute('viewBox', '0 -8 32 32');
            svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
            svg.setAttribute('style', 'cursor: pointer');

            const svgPath = document.createElementNS(
              'http://www.w3.org/2000/svg',
              'path',
            );
            svgPath.setAttribute(
              'd',
              'M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z',
            );
            svgPath.setAttribute('stroke-linecap', 'round');
            svgPath.setAttribute('stroke-linejoin', 'round');
            svgPath.setAttribute('stroke-width', '2');
            svg.appendChild(svgPath);

            svg.onclick = () => {
              axios
                .get(`/comment/pic/deletebyname/file/public/${filename}`)
                .then((r) => {
                  window.location.reload();
                });
            };

            tdElement.appendChild(svg);
          }

          tdElement.appendChild(rotateButton);
        }
      });
  };
  const handlePictureToggle = (ergID) => () => {
    return d(fetchPictures(ergID)).then(() => {
      d(markAsRead(ergID));
    });
  };

  const handleIDClick = (ergID) => (e) => {
    e.stopPropagation();
    d(setSearchStr(`#${ergID}`));
    d(fetchSearch());
  };

  const CommentView = ({ ergID }) =>
    comments.ergs[ergID] === undefined ? null : (
      <Comments
        comments={comments.ergs[ergID].map((id) => comments.entities[id])}
        ergID={ergID}
        fetchComment={(id) => d(fetchComments(id))}
        canDelete={canDelete}
      />
    );

  const PointTableView = ({ ergID }) => {
    const [previewOpen, setPreviewOpen] = useState(false);
    const [previewIndex, setPreviewIndex] = useState(0);
    const html = points.tables[ergID] ?? '';

    const pointsTableImages = useMemo<PreviewImage[]>(
      () => extractPreviewImagesFromHtml(html),
      [html],
    );

    const handlePointsTableClick = (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();
      setPreviewIndex(imageIndex);
      setPreviewOpen(true);
    };

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

    if (points.tables[ergID] === undefined) {
      return null;
    }
    setTimeout(() => {
      recButton(ergID);
    }, 100);
    let result = (
      <>
        <Paper>
          <FixTableLayout>
            <div
              onClick={handlePointsTableClick}
              onMouseOver={handlePointsTableMouseOver}
              dangerouslySetInnerHTML={{ __html: html }}
            />
          </FixTableLayout>
        </Paper>
        <ImagePreviewDialog
          open={previewOpen}
          images={pointsTableImages}
          initialIndex={previewIndex}
          onClose={() => setPreviewOpen(false)}
        />
      </>
    );

    return result;
  };

  const PicView = ({ ergID }) => {
    const [previewOpen, setPreviewOpen] = useState(false);
    const [previewIndex, setPreviewIndex] = useState(0);
    const pictureIDs = pictures.ergs[ergID] ?? [];
    const pictureItems = pictureIDs
      .map((id) => pictures.entities[id])
      .filter((picture) => picture != null);

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

    const handleOpenPreview = (picID: number) => {
      const imageIndex = previewImages.findIndex((image) => image.id === picID);
      if (imageIndex < 0) {
        return;
      }
      setPreviewIndex(imageIndex);
      setPreviewOpen(true);
    };

    if (pictures.ergs[ergID] === undefined) return null;

    return (
      <>
        {pictureItems.map((p) => {
            return (
              <>
                <Picture
                  key={p.pic_id}
                  comment=''
                  path={p.pic_name}
                  id={p.pic_id}
                  ergID={ergID}
                  canDelete={canDelete}
                  onPreviewImage={handleOpenPreview}
                />
              </>
            );
          })}
        <ImagePreviewDialog
          open={previewOpen}
          images={previewImages}
          initialIndex={previewIndex}
          onClose={() => setPreviewOpen(false)}
        />
      </>
    );
  };

  const haveOriginal = (index) => tableData[index].erg_clone > 0;
  const handleSearchOriginal = (index) => (e) => {
    e.stopPropagation();
    d(setSearchStr(`#${tableData[index].erg_clone}`));
    d(fetchSearch());
  };

  const handleOpenTaskList = () => d(openTaskList());

  const exportSearchResultAsPdf = () => {
    axios
      .post(
        '/c/search/export-pdf',
        {
          agbIds: tableData.map((d) => d.id),
        },
        { responseType: 'blob' },
      )
      .then((response) => {
        const url = window.URL.createObjectURL(
          new Blob([response.data], { type: 'application/pdf' }),
        );
        window.open(url, '_blank');
        window.URL.revokeObjectURL(url);
      });
  };

  const onDetailSearchDescription = () => {
    const resultCount = tableData.length;
    return (
      <small>
        <Trans> {resultCount} results found. </Trans>
        <br />
        {resultCount >= onDetailSearchResultLimit && (
          <Trans>
            {' '}
            There might be more results, please refine your search detail.{' '}
          </Trans>
        )}
      </small>
    );
  };

  return (
    <div>
      <I18nProvider i18n={i18n}>
        <Box display='flex' alignItems='center' ml={5}>
          {/* <Autocomplete
            multiple
            size="small"
            options={availableTags}
            value={selectedTags}
            onChange={onTagsChange}
            disableCloseOnSelect
            renderTags={(value, getTagProps) =>
              value.map((option, index) => (
                <Chip
                  variant="outlined"
                  label={option}
                  {...getTagProps({ index })}
                  size="small"
                />
              ))
            }
            renderInput={(params) => (
              <TextField
                {...params}
                placeholder="Filter by Tags"
                variant="outlined"
                InputProps={{ ...params.InputProps, style: { padding: '4px 8px' } }}
              />
            )}
            style={{ width: 240 }}
          /> */}

          <Box mr='auto' />
          <Button
            color='inherit'
            startIcon={
              <img src='/icon8/svg/pdfexp24.svg' alt='pdf export icon' />
            }
            onClick={exportSearchResultAsPdf}
            style={{ textTransform: 'none' }}
          >
            <Trans>Export to PDF</Trans>
          </Button>
          {isOnDetailSearch ? (
            onDetailSearchDescription()
          ) : (
            <TablePagination
              ref={pagination}
              component='div'
              count={-1}
              page={page}
              rowsPerPage={rowsPerPage}
              onPageChange={onChangePage}
              onRowsPerPageChange={onChangeRowsPerPage}
              labelDisplayedRows={() => ''}
              labelRowsPerPage={<Trans>Rows per page:</Trans>}
              nextIconButtonProps={{ disabled: isDisableNext || isLoading }}
              backIconButtonProps={{ disabled: page === 0 || isLoading }}
            />
          )}
        </Box>
        <div
          style={{
            overflow: 'auto',
            height: `calc(98vh - ${cardListHeight}px)`,
          }}
        >
          <DocumentationView heightStyle={`calc(98vh - ${cardListHeight}px)`} />
          {isLoading && (
            <div
              style={{
                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center',
              }}
            >
              <CircularProgress />
            </div>
          )}
          {isUpcoming && <ScheduledCardContainer />}
          {isUpcoming === false &&
            tableData.map((d, index) => {
              const tagsForItem = tagsEntities[d.id] || [];
              return (
                <Card
                  key={d.id}
                  index={index}
                  comment={d.task_comment}
                  createdBy={d.erg_krzl}
                  aud_count={d.aud_count}
                  currentTaskName={d.task}
                  completeTime={d.erg_strdat}
                  startTime={d.done_at}
                  dueDate={d.dya_nextaufgabe}
                  taskID={d.id}
                  taskName={d.current_task}
                  taskPathArr={pathArr(d.group_ID)}
                  taskType={d.task_type}
                  taskColor={d.color}
                  handleEdit={handleEdit(index)}
                  canEdit={canEdit}
                  isPlanned={d.isPlanned}
                  isBlocked={d.isBlocked}
                  markAsRead={handleMarkAsRead(d.id)}
                  toggleRead={handleToggleRead(d.id)}
                  isComplete={d.erg_strerl > 0}
                  isUpcoming={new Date(d.dya_nextaufgabe) > new Date()}
                  controlView={
                    <Details
                      canDelete={canDelete}
                      rowData={d}
                      isOneRow
                      index={index}
                      handleEdit={handleEdit(index)}
                      canEdit={canEdit}
                      taskID={d.id}
                      taskType={d.task_type}
                      isComplete={d.erg_strerl > 0}
                      isUpcoming={ new Date(d.dya_nextaufgabe) > new Date() }
                      isBlocked={d.isBlocked}
                      tags={tagsForItem}
                    />
                  }
                  commentCount={tableData[index].comment_count}
                  pointCount={tableData[index].point_count}
                  pictureCount={tableData[index].picture_count}
                  handleIDClick={handleIDClick(tableData[index].id)}
                  handleCommentToggle={() =>
                    handleCommentToggle(tableData[index].id)
                  }
                  handlePointToggle={() =>
                    handlePointToggle(tableData[index].id)
                  }
                  handlePictureToggle={() =>
                    handlePictureToggle(tableData[index].id)
                  }
                  commentView={<CommentView ergID={tableData[index].id} />}
                  tableView={<PointTableView ergID={tableData[index].id} />}
                  picView={<PicView ergID={tableData[index].id} />}
                  isShowOriginal={haveOriginal(index)}
                  handleShowOriginalClick={handleSearchOriginal(index)}
                  // 32 is timetracker flag
                  isTimeTracker={(d.agb_activefunc & 32) > 0}
                  isRead={isReadHelper(
                    readLogs,
                    tableData[index],
                    isOpenFilter,
                  )}
                />
              );
            })}
        </div>
      </I18nProvider>
    </div>
  );
}
