import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import RootLayout from '../component/layout/Layout';
import { useRouter } from 'next/router';
import {
  deleteShortVideo,
  getFilmListVideo,
  updateEpisodePosition,
} from '../store/filmListSlice';
import Table from '../extra/Table';
import moment from 'moment';
import { openDialog } from '../store/dialogueSlice';
import VideoDialogue from '../component/filmVideo/VideoDialogue';
import { CiLock, CiUnlock } from 'react-icons/ci';
import Button from '../extra/Button';
import TrashIcon from '../assets/icons/trashIcon.svg';
import EditIcon from '../assets/icons/EditBtn.svg';
import { warning } from '../util/Alert';
import EpisodeListDialogue from '../component/episodeList/EpisodeListDialogue';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
import { getSetting } from '../store/settingSlice';
import { setToast } from '../util/toastServices';
import { IconEdit, IconEye, IconLockFilled, IconLockOpen, IconTrash } from '@tabler/icons-react';
import ViewEpisodeVideoDialogue from '../component/episodeList/ViewEpisodeVideoDialogue'

const ViewShortVideo = () => {
  const { dialogueType } = useSelector((state) => state.dialogue);
  const dispatch = useDispatch();
  const { query } = useRouter();

  const [page, setPage] = useState(1);
  const [size] = useState(20);
  const [data, setData] = useState([]);
  const [hasMore, setHasMore] = useState(true);
  const [viewVideo, setViewVideo] = useState(null);
  const [isDragging, setIsDragging] = useState(false);
  const observer = useRef();

  const { filmListVideo, totalUser } = useSelector((state) => state.filmsList);

  

  const userId = query.movieSeriesId;

  // Initialize data when filmListVideo changes
  useEffect(() => {
    if (page === 1) {
      setData(filmListVideo);
    } else {
      setData((prevData) => {
        const newVideos = filmListVideo.filter(
          (video) => !prevData.some((prevVideo) => prevVideo._id === video._id)
        );
        return [...prevData, ...newVideos];
      });
    }

    // Check if we have more data to load
    setHasMore(data.length + filmListVideo.length < totalUser);
  }, [filmListVideo, totalUser]);

  // Load initial data
  useEffect(() => {
    if (userId) {
      setPage(1);
      setData([]);
      dispatch(
        getFilmListVideo({
          start: 1,
          limit: size,
          movieSeriesId: userId,
        })
      );
       dispatch(getSetting());
    }
  }, [userId]);

  // Infinite scroll implementation
  const lastVideoElementRef = useCallback(
    (node) => {
      if (observer.current) observer.current.disconnect();
      observer.current = new IntersectionObserver((entries) => {
        if (entries[0].isIntersecting && hasMore) {
          setPage((prevPage) => {
            const nextPage = prevPage + 1;
            dispatch(
              getFilmListVideo({
                start: nextPage,
                limit: size,
                movieSeriesId: userId,
              })
            );
            return nextPage;
          });
        }
      });
      if (node) observer.current.observe(node);
    },
    [hasMore, userId, size]
  );

  const handleDeleteFilmCategory = (video) => {
    
    const data = warning();
    data
      .then((res) => {
        if (res) {
          dispatch(
            deleteShortVideo({
              shortVideoId: video?._id,
              movieSeriesId: userId,
              start: 1,
              limit: size,
            })
          ).then((res) => {
            // Refresh the entire list after deletion
            setPage(1);
            setData([]);
            dispatch(
              getFilmListVideo({
                start: 1,
                limit: size,
                movieSeriesId: userId,
              })
            );
          });
        }
      })
      .catch((err) => console.log(err));
  };

  const handleOnDragStart = () => {
    setIsDragging(true);
  };

  const handleOnDragEnd = (result) => {
    setIsDragging(false);

    
    if (!result.destination) return;

    const sourceIndex = result.source.index;
    const destinationIndex = result.destination.index;

    if (sourceIndex === destinationIndex) return;

    const draggedEpisode = data[sourceIndex];
    if (draggedEpisode.episodeNumber === 0) {
      return setToast('error', 'Trailer cannot be moved');
    }

    const updatedItems = Array.from(data);
    const [reorderedItem] = updatedItems.splice(sourceIndex, 1);
    updatedItems.splice(destinationIndex, 0, reorderedItem);

    const finalData = updatedItems.map((item, index) => ({
      ...item,
      episodeNumber: item.episodeNumber === 0 ? 0 : index,
    }));

    setData(finalData);

    const movedEpisode = finalData[destinationIndex];

    dispatch(
      updateEpisodePosition({
        movieSeriesId: userId,
        shortVideoId: movedEpisode._id,
        newEpisodePosition: destinationIndex,
      })
    )
      .then((result) => {
        if (result.error) {
          setData(data);
          setToast('error', 'Failed to update episode position');
        } else {
          setToast('success', 'Episode position updated successfully');
          setTimeout(() => {
            dispatch(
              getFilmListVideo({
                start: 1,
                limit: size * page,
                movieSeriesId: userId,
              })
            );
          }, 500);
        }
      })
      .catch(() => {
        setData(data);
        setToast('error', 'Failed to update episode position');
      });
  };

  const ManageVideoTable = useMemo(
    () => [
      {
        Header: 'Drag',
        body: 'drag',
        Cell: ({ index }) => (
          <div
            className="drag-handle"
            style={{
              cursor: isDragging ? 'grabbing' : 'grab',
              fontSize: '18px',
              color: '#666',
              textAlign: 'center',
              userSelect: 'none',
              padding: '5px',
              transition: 'all 0.2s ease',
            }}
          >
            ⋮⋮
          </div>
        ),
      },
      {
        Header: 'No',
        body: 'no',
        Cell: ({ index }) => <span className="text-nowrap">{index + 1}</span>,
      },
      {
        Header: 'Video Image',
        body: 'image',
        Cell: ({ row }) => {
          return (
            <div className="userTableImage">
              <img
                src={row?.videoImage || '/images/default-movie-poster.jpg'}
                width={75}
                height={100}
                alt="Thumbnail"
                onError={(e) => {
                  e.target.onerror = null;
                  e.target.src = '/images/default-movie-poster.jpg';
                }}
              />
            </div>
          );
        },
      },
      {
        Header: 'Episode Number',
        body: 'episode number',
        Cell: ({ row, index }) => (
          <div className="userTableImage">
            <span>
              {row?.episodeNumber === 0 ? 'Trailer' : row?.episodeNumber}
            </span>
          </div>
        ),
      },
      {
        Header: 'Locked Status',
        body: 'isLocked',
        Cell: ({ row }) => (
          <div className="userTableImage">
            <span>
              {row?.isLocked ? (
                <IconLockFilled className='text-danger' />
              ) : (
                <IconLockOpen className='text-success' />
              )}
            </span>
          </div>
        ),
      },
      {
        Header: 'Coins',
        body: 'coins',
        Cell: ({ row }) => (
          <div className="userTableImage">
            <span>{row?.coin || 0}</span>
          </div>
        ),
      },
      {
        Header: 'Date',
        body: 'date',
        Cell: ({ row }) => (
          <span className="text-capitalize cursorPointer">
            {moment(row?.releaseDate).format('DD/MM/YYYY') || '-'}
          </span>
        ),
      },
      {
        Header: "View Video",
        body: "video",
        Cell: ({ row }) => (
          <div className="action-button">
            <Button
              btnIcon={<IconEye className="text-secondary" />}
              onClick={() => setViewVideo(row)}
            />
          </div>
        ),
      },
      {
        Header: 'Action',
        body: 'action',
        Cell: ({ row }) => (
          <div className="action-button">
            <Button
              btnIcon={
                <IconEdit className='text-secondary' />
              }
              onClick={() => {
                
                dispatch(
                  openDialog({
                    type: 'episodeList',
                    data: row,
                  })
                );
              }}
            />
            <Button
              btnIcon={
                <IconTrash className='text-secondary' />
              }
              onClick={() => handleDeleteFilmCategory(row)}
            />
          </div>
        ),
      },
    ],
    [data, isDragging]
  );

  return (
    <>
      {dialogueType == 'viewVideo' && <VideoDialogue />}
      {dialogueType == 'episodeList' && (
        <EpisodeListDialogue page={page} size={size} />
      )}

      <div className='userPage'>
        <div className="user-table real-user mb-3">
          <div className="user-table-top">
            <h5
              style={{
                fontWeight: '500',
                fontSize: '20px',
                marginBottom: '5px',
                marginTop: '5px',
              }}
            >
              Short Videos - Drag & Drop to Reorder
            </h5>
            <small className="text-muted">
              Total Episodes: {data.length}{' '}
              {hasMore ? '(Loading more...)' : '(All loaded)'}
            </small>
          </div>
          <DragDropContext onDragEnd={handleOnDragEnd} onDragStart={handleOnDragStart}>
            <Droppable droppableId="videos">
              {(provided) => (
                <div
                  className="primeMain table-custom"
                  {...provided.droppableProps}
                  ref={provided.innerRef}
                >
                  <table width="100%" className="primeTable text-center">
                    {/* Table Head */}
                    <thead style={{ zIndex: "1", position: "sticky", top: "0" }}>
                      <tr className="text-black">
                        {ManageVideoTable.map((res) => (
                          <th className="text-nowrap" key={res.Header}>
                            <div className="table-head">{res.Header}</div>
                          </th>
                        ))}
                      </tr>
                    </thead>

                    {/* Table Body */}
                    <tbody>
                      {data?.length > 0 ? (
                        data.map((row, index) => (
                          <Draggable
                            key={row._id || index}
                            draggableId={row._id?.toString() || index.toString()}
                            index={index}
                          >
                            {(provided, snapshot) => (
                              <tr
                                ref={(el) => {
                                  provided.innerRef(el);
                                  if (index === data.length - 1 && lastVideoElementRef) {
                                    lastVideoElementRef(el);
                                  }
                                }}
                                {...provided.draggableProps}
                                className={snapshot.isDragging ? "dragging-row" : ""}
                                style={{
                                  ...provided.draggableProps.style,
                                  backgroundColor: snapshot.isDragging
                                    ? "#f5f5f5"
                                    : "inherit",
                                  boxShadow: snapshot.isDragging
                                    ? "0 5px 15px rgba(0,0,0,0.3)"
                                    : "none",
                                  transition: "all 0.2s ease",
                                }}
                              >
                                {ManageVideoTable.map((res, colIndex) => (
                                  <td
                                    key={res.body}
                                    {...(colIndex === 0 ? provided.dragHandleProps : {})}
                                  >
                                    {res.Cell ? (
                                      <res.Cell row={row} index={index} />
                                    ) : (
                                      <span className={res.class}>
                                        {row[res.body]}
                                      </span>
                                    )}
                                  </td>
                                ))}
                              </tr>
                            )}
                          </Draggable>
                        ))
                      ) : (
                        <tr>
                          <td
                            colSpan={ManageVideoTable.length}
                            className="text-center"
                            style={{ borderBottom: "none", padding: "20px" }}
                          >
                            No Data Found!
                          </td>
                        </tr>
                      )}
                      {provided.placeholder}
                    </tbody>
                  </table>
                </div>
              )}
            </Droppable>
          </DragDropContext>


          {/* No more data indicator */}
          {!hasMore && data?.length > 0 && (
            <div className="text-center my-3">
              <p className="text-muted">No more episodes to load</p>
            </div>
          )}
        </div>

        <ViewEpisodeVideoDialogue
          viewVideo={viewVideo}
          setViewVideo={setViewVideo}
        />
      </div>
    </>
  );
};

export default ViewShortVideo;
ViewShortVideo.getLayout = function getLayout(page) {
  return <RootLayout>{page}</RootLayout>;
};
