import { useApolloClient, useQuery, useSubscription } from "@apollo/client";
import _ from "lodash";
import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import {
  QUERY_EXACT_JOBS_IN_PRODUCTION,
  QUERY_EXACT_JOB_IN_PRODUCTION,
  QUERY_JOBS_IN_PRODUCTION,
  SUBSCRIPTION_JOBS_IN_PRODUCTION,
} from "../../graphql/jobs.queries";
import { QUERY_KANBAN_SETTINGS } from "../../graphql/user.queries";
import {
  selectBodyshop,
  selectCurrentUser,
} from "../../redux/user/user.selectors";
import ProductionBoardKanbanComponent from "./production-board-kanban.component";

const mapStateToProps = createStructuredSelector({
  bodyshop: selectBodyshop,
  currentUser: selectCurrentUser,
});
export function ProductionBoardKanbanContainer({ bodyshop, currentUser }) {
  const { refetch, loading, data } = useQuery(QUERY_JOBS_IN_PRODUCTION, {
    pollInterval: 3600000,
    fetchPolicy: "network-only",
    nextFetchPolicy: "network-only",
  });
  const client = useApolloClient();
  const [joblist, setJoblist] = useState([]);
  const { data: updatedJobs } = useSubscription(
    SUBSCRIPTION_JOBS_IN_PRODUCTION
  );

  useEffect(() => {
    if (!(data && data.jobs)) return;
    setJoblist(
      data.jobs.map((j) => {
        return { id: j.id, updated_at: j.updated_at };
      })
    );
  }, [data]);

  useEffect(() => {
    if (!updatedJobs || joblist.length === 0) return;

    const jobDiff = _.differenceWith(
      joblist,
      updatedJobs.jobs,
      (a, b) => a.id === b.id && a.updated_at === b.updated_at
    );

    jobDiff.forEach((job) => {
      getUpdatedJobData(job.id);
    });
    if (jobDiff.length > 1) {
      getUpdatedJobsData(jobDiff.map((j) => j.id));
    } else if (jobDiff.length === 1) {
      jobDiff.forEach((job) => {
        getUpdatedJobData(job.id);
      });
    }

    setJoblist(updatedJobs.jobs);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [updatedJobs]);

  const getUpdatedJobData = async (jobId) => {
    client.query({
      query: QUERY_EXACT_JOB_IN_PRODUCTION,
      variables: { id: jobId },
    });
  };
  const getUpdatedJobsData = async (jobIds) => {
    client.query({
      query: QUERY_EXACT_JOBS_IN_PRODUCTION,
      variables: { ids: jobIds },
    });
  };

  const { loading: associationSettingsLoading, data: associationSettings } =
    useQuery(QUERY_KANBAN_SETTINGS, {
      variables: { email: currentUser.email },
    });

  return (
    <ProductionBoardKanbanComponent
      loading={loading || associationSettingsLoading}
      data={data ? data.jobs : []}
      refetch={refetch}
      associationSettings={
        associationSettings && associationSettings.associations[0]
          ? associationSettings.associations[0]
          : null
      }
    />
  );
}
export default connect(mapStateToProps, null)(ProductionBoardKanbanContainer);
