import gql from "gql-tag";
import { Request } from "../types";
import { useQuery } from "urql";
import { Spinner } from "./Spinner";
import moment from "moment";
import { useNavigate, useParams } from "react-router-dom";
import { useEffect, useState } from "react";
import { REQUESTS_COMPONENT } from "../testing";

const requestsQuery = gql`
  query RequestsByApiKey($apiKeyId: ID, $skip: Int) {
    requests(where: { apiKeyId: $apiKeyId }, options: { skip: $skip }) {
      requests {
        id
        callType
        url
        method
        timestamp
        response {
          id
          statusCode
          timestamp
        }
      }
    }
  }
`;

const tableStyles = {
  sticky: "sticky top-0 z-10",
  headerCell:
    "border-b border-gray-300 bg-opacity-75 py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900",
};

function TableHeader() {
  return (
    <thead>
      <tr className={tableStyles.sticky}>
        <th scope="col" className={`${tableStyles.headerCell} sm:pl-6 lg:pl-8`}>
          URL
        </th>
        <th scope="col" className={`${tableStyles.headerCell} sm:pl-6 lg:pl-8`}>
          When
        </th>
        <th scope="col" className={`${tableStyles.headerCell} sm:pr-6 lg:pr-8`}>
          Duration
        </th>
        <th scope="col" className={`${tableStyles.headerCell} sm:pr-6 lg:pr-8`}>
          Status Code
        </th>
      </tr>
    </thead>
  );
}

const rowStyles = {
  cell: "border-b border-gray-200 whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900",
  lastCell:
    "border-b border-gray-200 relative whitespace-nowrap py-4 pr-4 pl-3 text-right text-sm font-medium sm:pr-8 lg:pr-8",
  link: "text-indigo-600 hover:text-indigo-900",
};

function TableRow({ request }: { request: Request }) {
  const navigate = useNavigate();
  const params = useParams();

  return (
    <tr
      data-id={request.id}
      key={request.id}
      onClick={() =>
        navigate(
          `/company/${params.companyId}/project/${params.projectId}/api-key/${params.apiKeyId}/request/${request.id}`,
        )
      }
      className={`bg-white hover:bg-sky-200 hover:cursor-pointer border-t border-gql-vis-grey-2`}
    >
      <td className={`${rowStyles.cell} sm:pl-6 lg:pl-8`}> {request.url}</td>
      <td className={`${rowStyles.cell} sm:pl-6 lg:pl-8`}>
        {moment(request?.timestamp).fromNow()}
      </td>
      <td className={`${rowStyles.cell} sm:pl-6 lg:pl-8`}>
        {moment
          .duration(
            moment(request.response?.timestamp).diff(
              moment(request?.timestamp),
            ),
          )
          .asMilliseconds()}{" "}
        ms
      </td>
      <td className={`${rowStyles.cell} sm:pl-6 lg:pl-8`}>
        {request.response?.statusCode}
      </td>
    </tr>
  );
}

export function Requests() {
  const params = useParams();
  const [skip, setSkip] = useState(0);
  const [prevRequests, setPrevRequests] = useState<Request[]>([]);

  const [result, reexecuteQuery] = useQuery({
    query: requestsQuery,
    variables: {
      apiKeyId: params.apiKeyId,
      skip,
    },
  });

  useEffect(() => {
    reexecuteQuery();
  }, [skip]);

  const newRequests = (result?.data?.requests?.requests || []) as Request[];
  const requests = [...(skip === 0 ? [] : prevRequests), ...newRequests];

  const handleLoadMore = () => {
    setSkip((s) => s + 5);
  };

  useEffect(() => {
    setPrevRequests(requests);
  }, [newRequests]);

  return (
    <div className="flex flex-col w-full h-full align-top content-start gap-5">
      <div className="inline-block align-middle border border-gray-300 rounded-xl overflow-scroll">
        <table className="bg-white border-spacing-0 rounded-xl min-w-full">
          <TableHeader />
          <tbody
            id={REQUESTS_COMPONENT}
            data-requests={JSON.stringify(requests)}
          >
            {requests.map((request: Request) => (
              <TableRow key={request.id} request={request} />
            ))}
          </tbody>
        </table>
      </div>
      <button
        className="mt-4 bg-white border border-gray-300 rounded-md shadow-sm py-2 px-4 text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 mx-auto text-center"
        onClick={handleLoadMore}
      >
        Load More
      </button>
      {result.fetching ? (
        <div className="flex justify-center align-center mx-auto pt-20">
          <Spinner></Spinner>
        </div>
      ) : (
        <></>
      )}
    </div>
  );
}
