import { isEmpty, isNil, isUndefined, map, partialRight, pick } from "lodash";
import React, { ReactElement, useState, useCallback } from "react";
import { useParams } from "react-router";
import { analyzeLibrary } from "../../actions/comicinfo.actions";
import { useQuery, useMutation, QueryClient } from "@tanstack/react-query";
import PotentialLibraryMatches from "./PotentialLibraryMatches";
import { Card } from "../shared/Carda";
import SlidingPane from "react-sliding-pane";
import { convert } from "html-to-text";
import ellipsize from "ellipsize";
import {
  COMICVINE_SERVICE_URI,
  LIBRARY_SERVICE_BASE_URI,
} from "../../constants/endpoints";
import axios from "axios";

const VolumeDetails = (props): ReactElement => {
  // sliding panel config
  const [visible, setVisible] = useState(false);
  const [slidingPanelContentId, setSlidingPanelContentId] = useState("");
  const [matches, setMatches] = useState([]);
  const [storyArcsData, setStoryArcsData] = useState([]);
  const [active, setActive] = useState(1);

  // sliding panel init
  const contentForSlidingPanel = {
    potentialMatchesInLibrary: {
      content: () => {
        const ids = map(matches, partialRight(pick, "_id"));
        const matchIds = ids.map((id: any) => id._id);
        {
          /* return <PotentialLibraryMatches matches={matchIds} />; */
        }
      },
    },
  };

  // sliding panel handlers
  const openPotentialLibraryMatchesPanel = useCallback((potentialMatches) => {
    setSlidingPanelContentId("potentialMatchesInLibrary");
    setMatches(potentialMatches);
    setVisible(true);
  }, []);

  //   const analyzeIssues = useCallback((issues) => {
  //     dispatch(analyzeLibrary(issues));
  //   }, []);
  //

  const { comicObjectId } = useParams<{ comicObjectId: string }>();

  const { data: comicObject, isSuccess: isComicObjectFetchedSuccessfully } =
    useQuery({
      queryFn: async () =>
        axios({
          url: `${LIBRARY_SERVICE_BASE_URI}/getComicBookById`,
          method: "POST",
          data: {
            id: comicObjectId,
          },
        }),
      queryKey: ["comicObject"],
    });

  // get issues for a series
  const {
    data: issuesForSeries,
    isSuccess,
    isFetching,
  } = useQuery({
    queryFn: async () =>
      await axios({
        url: `${COMICVINE_SERVICE_URI}/getIssuesForVolume`,
        method: "POST",
        data: {
          volumeId:
            comicObject?.data?.sourcedMetadata.comicvine.volumeInformation.id,
        },
      }),
    queryKey: ["issuesForSeries", comicObject?.data],
    enabled: !isUndefined(comicObject?.data),
  });
  // get story arcs
  const useGetStoryArcs = () => {
    return useMutation({
      mutationFn: async (comicObject) =>
        axios({
          url: `${COMICVINE_SERVICE_URI}/getResource`,
          method: "POST",
          data: {
            comicObject,
            resource: "issue",
            filter: `id:${comicObject?.sourcedMetadata.comicvine.id}`,
          },
        }),
      onSuccess: (data) => {
        setStoryArcsData(data?.data.results);
      },
    });
  };

  const {
    mutate: getStoryArcs,
    isIdle,
    isError,
    data,
    error,
    status,
  } = useGetStoryArcs();

  const IssuesInVolume = () => (
    <>
      {!isUndefined(issuesForSeries) ? (
        <div className="button" onClick={() => analyzeIssues(issuesForSeries)}>
          Analyze Library
        </div>
      ) : null}
      <>
        {isSuccess &&
          issuesForSeries.data.map((issue) => {
            return (
              <>
                <Card
                  key={issue.id}
                  imageUrl={issue.image.small_url}
                  orientation={"cover-only"}
                  hasDetails={false}
                />
                <span className="tag is-warning mr-1">
                  {issue.issue_number}
                </span>
                {!isEmpty(issue.matches) ? (
                  <>
                    <span className="icon has-text-success">
                      <i className="fa-regular fa-asterisk"></i>
                    </span>
                  </>
                ) : null}
              </>
            );
          })}
      </>
    </>
  );

  const Issues = () => (
    <>
      <article
        role="alert"
        className="mt-4 rounded-lg text-sm max-w-screen-md border-s-4 border-blue-500 bg-blue-50 p-4 dark:border-s-4 dark:border-blue-600 dark:bg-blue-300 dark:text-slate-600"
      >
        <div>
          You can add a single issue or the whole volume, and it will be added
          to the list of `Wanted` items.
        </div>
      </article>
      <div className="flex flex-wrap">
        {isSuccess &&
          issuesForSeries?.data.map((issue) => {
            return (
              <div className="my-3 dark:bg-slate-400 bg-slate-300 p-4 rounded-lg w-3/4">
                <div className="flex flex-row gap-4 mb-2">
                  <div className="w-fit">
                    <img
                      src={issue.image.thumb_url}
                      className="w-full rounded-md"
                    />
                  </div>
                  <div className="w-3/4">
                    <p className="text-xl">{issue.name}</p>
                    <p className="text-sm">
                      {convert(issue.description, {
                        baseElements: {
                          selectors: ["p"],
                        },
                      })}
                    </p>
                  </div>
                </div>
              </div>
            );
          })}
      </div>
    </>
  );

  // Tab content and header details
  const tabGroup = [
    {
      id: 1,
      name: "Issues in Volume",
      icon: <i className="icon-[solar--documents-bold-duotone] w-6 h-6"></i>,
      content: <Issues />,
    },
    {
      id: 2,
      icon: (
        <i className="icon-[solar--users-group-rounded-bold-duotone] w-6 h-6"></i>
      ),
      name: "Characters",
      content: <div key={2}>Characters</div>,
    },
    {
      id: 3,
      icon: (
        <i className="icon-[solar--book-bookmark-bold-duotone] w-6 h-6"></i>
      ),
      name: "Story Arcs",
      content: (
        <div key={3}>
          <button className="" onClick={() => getStoryArcs(comicObject?.data)}>
            Get story arcs
          </button>
          {status === "pending" && <>{status}</>}
          {!isEmpty(storyArcsData) && status === "success" && (
            <>
              <ul>
                {storyArcsData.map((storyArc) => {
                  return (
                    <li>
                      <span className="text-lg">{storyArc?.name}</span>
                    </li>
                  );
                })}
              </ul>
            </>
          )}
        </div>
      ),
    },
  ];

  // Tabs
  const MetadataTabGroup = () => {
    return (
      <>
        <div className="hidden sm:block mt-7 mb-3 w-fit">
          <div className="border-b border-gray-200">
            <nav className="flex gap-4" aria-label="Tabs">
              {tabGroup.map(({ id, name, icon }) => (
                <a
                  key={id}
                  className={`inline-flex shrink-0 items-center gap-2 px-1 py-1 text-md font-medium text-gray-500 dark:text-gray-400 hover:border-gray-300 hover:border-b hover:dark:text-slate-200 ${
                    active === id
                      ? "border-b border-cyan-50 dark:text-slate-200"
                      : "border-b border-transparent"
                  }`}
                  aria-current="page"
                  onClick={() => setActive(id)}
                >
                  <span className="pt-1">{icon}</span>
                  {name}
                </a>
              ))}
            </nav>
          </div>
        </div>
        {tabGroup.map(({ id, content }) => {
          return active === id ? content : null;
        })}
      </>
    );
  };
  if (isComicObjectFetchedSuccessfully && !isUndefined(comicObject.data)) {
    const { sourcedMetadata } = comicObject.data;
    return (
      <>
        <header className="bg-slate-200 dark:bg-slate-500">
          <div className="mx-auto max-w-screen-xl px-4 py-2 sm:px-6 sm:py-8 lg:px-8 lg:py-4">
            <div className="sm:flex sm:items-center sm:justify-between">
              <div className="text-center sm:text-left">
                <h1 className="text-2xl font-bold text-gray-900 dark:text-white sm:text-3xl">
                  Volumes
                </h1>

                <p className="mt-1.5 text-sm text-gray-500 dark:text-white">
                  Browse your collection of volumes.
                </p>
              </div>
            </div>
          </div>
        </header>
        <div className="container mx-auto px-4 sm:px-6 lg:px-8 mt-4">
          <div>
            <div className="flex flex-row gap-4">
              {/* Volume cover */}
              <Card
                imageUrl={
                  sourcedMetadata.comicvine.volumeInformation.image.small_url
                }
                orientation={"cover-only"}
                hasDetails={false}
              />

              <div>
                <div className="field is-grouped">
                  {/* Title */}
                  <span className="text-2xl">
                    {sourcedMetadata.comicvine.volumeInformation.name}
                  </span>
                  {/* Comicvine Id */}
                  <div className="control">
                    <div className="tags has-addons">
                      <span className="tag">ComicVine Id</span>
                      <span className="tag is-info is-light">
                        {sourcedMetadata.comicvine.volumeInformation.id}
                      </span>
                    </div>
                  </div>
                  {/* Publisher */}
                  <div className="control">
                    <div className="tags has-addons">
                      <span className="tag is-warning is-light">Publisher</span>
                      <span className="tag is-volume-related">
                        {
                          sourcedMetadata.comicvine.volumeInformation.publisher
                            .name
                        }
                      </span>
                    </div>
                  </div>
                </div>

                {/* Deck */}
                <div>
                  {!isEmpty(
                    sourcedMetadata.comicvine.volumeInformation.description,
                  )
                    ? ellipsize(
                        convert(
                          sourcedMetadata.comicvine.volumeInformation
                            .description,
                          {
                            baseElements: {
                              selectors: ["p"],
                            },
                          },
                        ),
                        300,
                      )
                    : null}
                </div>
              </div>

              {/* <pre>{JSON.stringify(issuesForVolume, undefined, 2)}</pre> */}
            </div>
            <MetadataTabGroup />
          </div>

          <SlidingPane
            isOpen={visible}
            onRequestClose={() => setVisible(false)}
            title={"Potential Matches in Library"}
            width={"600px"}
          >
            {slidingPanelContentId !== "" &&
              contentForSlidingPanel[slidingPanelContentId].content()}
          </SlidingPane>
        </div>
      </>
    );
  } else {
    return <></>;
  }
};

export default VolumeDetails;
