import { gql, GraphQLClient } from "graphql-request";

//
// Fetch configuration from environment variables.
//
const gqlURL = process.env.GQL_URL;
if (!gqlURL) {
  throw new Error(
    "GQL_URL environment variable was empty. Set GQL_URL to the address of the GraphQL server, e.g. GQL_URL=\"https://dev-graphql.twitch.a2z.com/wanjocel/VXCHAN-486/gql\"");
}

const userID = process.env.USER_ID;
if (!userID) {
  throw new Error("USER_ID environment variable was empty. The tests manipulate this user's autohost list and settings.");
}

const authHeader = process.env.OAUTH_TOKEN;
if (!authHeader) {
  throw new Error(
    "OAUTH_TOKEN environment variable was empty. This should be the OAuth token of the test user. E.g. OAUTH_TOKEN=\"OAuth jidjdgjdjdgjdfijdfj\"");
}

// Always live test channels.
const qaVodAutomation = "423168062";
const qaModeration = "419651782"
const qaBBTwilight1 = "436064831";

describe('Tests', () => {  
  const client = new GraphQLClient(gqlURL, {
    headers: {
      "Authorization": authHeader,
      "Client-ID": "kimne78kx3ncx6brgo4mv6wki5h1ko",
      "Accept-Language": "en-US",
      "X-Device-Id": "test-device-id",
    }
  });

  it("Set an autohost list", async () => {
    let query = gql`
      mutation($userID: ID!, $list: [ID!]!) {
        setAutohostChannels(input: {
          userID: $userID,
          channelIDs: $list
        }) {
          user {
            autohostChannels {
              nodes {
                id
              }
            }
          }
        }
      }
    `;
    let response = await client.request(query, {
      userID,
      list: [qaVodAutomation, qaModeration],
    });
    
    let nodes = response?.setAutohostChannels?.user?.autohostChannels.nodes;
    expect(nodes).toEqual([
      { id: qaVodAutomation },
      { id: qaModeration },
    ]);
  });


  it("Add a channel to the autohost list", async () => {
    const query = gql`
      mutation($userID: ID!, $channelsToBeAdded: [ID!]!) {
        addAutohostChannels(input: {
          userID: $userID,
          channelIDs: $channelsToBeAdded
        }) {
          user {
            autohostChannels {
              nodes {
                id
              }
            }
          }
        }
      }
    `;
    const response = await client.request(query, {
      userID,
      channelsToBeAdded: [qaBBTwilight1],
    });
    
    const nodes = response?.addAutohostChannels?.user?.autohostChannels.nodes;
    expect(nodes).toEqual([
      { id: qaVodAutomation },
      { id: qaModeration },
      { id: qaBBTwilight1 },
    ]);
  });


  it("Remove a channel to the autohost list", async () => {
    const query = gql`
      mutation($userID: ID!, $channelsToBeRemoved: [ID!]!) {
        removeAutohostChannels(input: {
          userID: $userID,
          channelIDs: $channelsToBeRemoved
        }) {
          user {
            autohostChannels {
              nodes {
                id
              }
            }
          }
        }
      }
    `;
    const response = await client.request(query, {
      userID: userID,
      channelsToBeRemoved: [qaModeration],
    });
    
    const nodes = response?.removeAutohostChannels?.user?.autohostChannels.nodes;
    expect(nodes).toEqual([
      { id: qaVodAutomation },
      { id: qaBBTwilight1 },
    ]);
  });


  it("Can fetch a channel's autohost list", async () => {
    const query = gql`
      query($userID: ID!) {
        user(id: $userID) {
          autohostChannels {
            nodes {
              id
            }
          }
        }
      }
    `;
    const response = await client.request(query, {
      userID,
    });
    
    const nodes = response?.user?.autohostChannels.nodes;
    expect(nodes).toEqual([
      { id: qaVodAutomation },
      { id: qaBBTwilight1 },
    ]);
  });


  it("Set all a channel's autohost settings", async () => {
    const query = gql`
      mutation($userID: ID!) {
        updateAutohostSettings(input: {
          userID: $userID,
          isEnabled: true,
          strategy: RANDOM,          
          willAutohostTeam: false,
          willPrioritizeAutohost: false,
        }) {
          user {
            autohostSettings {
              enabled
              strategy
              teamHost
              deprioritizeVodcast
            }
          }
        }
      }
    `;
    const response = await client.request(query, {
      userID,
    });
    
    const settings = response?.updateAutohostSettings?.user?.autohostSettings;
    expect(settings).toEqual({
      enabled: true,
      strategy: "RANDOM",
      teamHost: false,
      deprioritizeVodcast: false,
    });
  });


  it("Update one of the channel's autohost settings", async () => {
    const query = gql`
      mutation($userID: ID!) {
        updateAutohostSettings(input: {
          userID: $userID,
          strategy: ORDERED,          
        }) {
          user {
            autohostSettings {
              enabled
              strategy
              teamHost
              deprioritizeVodcast
            }
          }
        }
      }
    `;
    const response = await client.request(query, { userID });
    
    const settings = response?.updateAutohostSettings?.user?.autohostSettings;
    expect(settings).toEqual({
      enabled: true,
      strategy: "ORDERED",
      teamHost: false,
      deprioritizeVodcast: false,
    });
  });


  it("Can fetch a channel's endorsements", async () => {
    const query = gql`
      query($userID: ID!) {
        user(id: $userID) {
          endorsedChannels(recommendationsContext: {
            platform: "web",
          }) {
            edges {
              node {
                id
              }
            }
          }
        }
      }
    `;
    const response = await client.request(query, { userID });
    
    const edges = response?.user?.endorsedChannels.edges;
    expect(edges).toEqual([
      {
        node: { id: qaVodAutomation },
      },
      {
        node: { id: qaBBTwilight1 }, 
      },
    ]);
  });


  // This test assumes that all the channels on the Autohost list are live.
  // We use always-live test channels for this test, but sometimes they fall offline.
  it("Can fetch a channel's Autohost carousel card", async () => {
    const query = gql`
      query($userID: ID!) {
        channel(id: $userID) {
          home {
            autohostCarouselCard(recommendationsContext: {
              platform: "web",
            }) {
              channel {
                id
              }
              trackingID
            }
          }
        }
      }
    `;
    const response = await client.request(query, { userID });
    
    const cardChannelID = response?.channel?.home?.autohostCarouselCard?.channel?.id;
    expect(cardChannelID).toBe(qaVodAutomation);

    const trackingID = response?.channel?.home?.autohostCarouselCard?.trackingID;
    expect(trackingID).toBeTruthy();
  });
});
