import { useQuery } from '@tanstack/react-query';
import { GraphQLClient, gql } from 'graphql-request';
import { jsonrepair } from 'jsonrepair';

const endpoint = 'https://graphql.datocms.com/';

export const datoClient = new GraphQLClient(endpoint, {
  headers: {
    authorization: `Bearer ${process.env.NEXT_PUBLIC_DATO_CMS_API_KEY || ''}`,
  },
  fetch: async (url, params) =>
    fetch(url, { ...params, next: { revalidate: 120, tags: ['dato'] } }),
});

const gqlQuery = gql`
  {
    allChangelogItems(orderBy: datetime_DESC) {
      title
      datetime
      description
      tags
      linkUrl
      linkText
    }
  }
`;

export interface ChangelogItem {
  title: string;
  imageUrl?: string;
  description: string;
  tags?: string[];
  datetime: string;
  linkUrl: string;
  linkText?: string;
}

export interface CMSResponse {
  allChangelogItems: ChangelogItem[];
}

export const getCMSData = async () => {
  return await datoClient.request<CMSResponse>(gqlQuery, {});
};

const MAX_RETRY_COUNT = 5;

const emptyResponse: CMSResponse = {
  allChangelogItems: [],
};

export const useCMSData = () => {
  const query = useQuery<CMSResponse>({
    queryKey: ['cms'],
    queryFn: async () => {
      const cmsRequest = await fetch('/api/cms');

      if (!cmsRequest.ok) {
        throw new Error(`HTTP error! status: ${cmsRequest.status}`);
      }

      const responseText = await cmsRequest.text();

      const parsedResponse = JSON.parse(
        jsonrepair(responseText)
      ) as CMSResponse;

      if (!parsedResponse) {
        throw new Error('Empty response from CMS');
      }

      return parsedResponse;
    },
    placeholderData: emptyResponse,
    staleTime: 5 * 60 * 1000,
    retry: MAX_RETRY_COUNT,
    retryDelay: (attemptIndex) => 1000 * 2 ** attemptIndex,
  });

  return query;
};
