// Runs once every 8 hours. To update the activities that the users have done over the past 30 days.

import { exit } from 'process';
import { sendDiscordErrorMessage, sendDiscordMonitoringMessage } from './notification.js';
import { UserActivity, convertToRFC3339Date, getPast30DaysActivities, insertJob } from './sendgridSyncFunctions.js';

type SendgridContact = {
  email: string;
  custom_fields: {
    last_activity_date: string;
    past_30d_active_days: number;
    past_30d_activity_count: number;
    past_30d_composer_count: number;
    past_30d_conductor_count: number;
  };
};

const GROUP_SIZE = 10000;
const mainActivity = async () => {
  // Perform activity query
  console.log('Running Activity Update v2');

  const userActivities: UserActivity[] = await getPast30DaysActivities();
  console.log(
    `Found ${userActivities.length} users, splitting into ${Math.ceil(userActivities.length / GROUP_SIZE)} jobs.`
  );

  // Break into groups of GROUP_SIZE
  const userActivitiesGroups = [];
  let userActivitiesGroup = [];
  for (const userActivity of userActivities) {
    userActivitiesGroup.push(userActivity);
    if (userActivitiesGroup.length >= GROUP_SIZE) {
      userActivitiesGroups.push(userActivitiesGroup);
      userActivitiesGroup = [];
    }
  }
  userActivitiesGroups.push(userActivitiesGroup);
  console.log('Split into groups:', userActivitiesGroups.length);

  // Perform update queries
  const URL = `https://api.sendgrid.com/v3/marketing/contacts`;
  const API_KEY = process.env.SENDGRID_API_KEY;

  let groupsProcessed = 0;
  for (const userActivitiesGroup of userActivitiesGroups) {
    console.log(`Processing ${groupsProcessed + 1} of ${userActivitiesGroups.length} groups`);
    const contacts: SendgridContact[] = userActivitiesGroup.map((userActivity) => {
      try {
        let customFields: any = {
          past_30d_active_days: parseInt(userActivity.past_30d_active_days),
          past_30d_activity_count: parseInt(userActivity.past_30d_activity_count),
          past_30d_composer_count: parseInt(userActivity.past_30d_composer_count),
          past_30d_conductor_count: parseInt(userActivity.past_30d_total_count),
        };
        if (userActivity.last_activity_date !== null) {
          customFields.last_activity_date = convertToRFC3339Date(userActivity.last_activity_date);
        }
        return {
          email: userActivity.email,
          custom_fields: customFields,
        };
      } catch (error) {
        console.error(error);
        console.log(userActivity);
        sendDiscordErrorMessage(
          `\`activityUpdate\` error.\nError:${error}\nUserActivity:${JSON.stringify(userActivity)}`
        );
      }
    });
    console.log(`Found ${contacts.length} contacts.`);
    const payload = {
      contacts,
    };
    try {
      const response = await fetch(URL, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${API_KEY}`,
        },
        body: JSON.stringify(payload),
      });

      const responseData = await response.json();
      const { job_id } = responseData;
      if (!job_id) {
        await sendDiscordErrorMessage(
          `\`activityUpdate\` error.\nSendgrid job could not be created.\nResponse:${JSON.stringify(responseData)}`
        );
        console.error('Error creating sendgrid job.');
        console.error(responseData);
      }
      await insertJob(job_id, 'activityUpdate');

      await sendDiscordMonitoringMessage(
        `\`activityUpdate.ts\` run (${groupsProcessed + 1}/${
          userActivitiesGroups.length + 1
        }).\nSendgrid jobs created. Job ID:\n${job_id}`
      );
      console.log(`Sendgrid job created. Job ID: ${job_id}`);
    } catch (error) {
      console.error(error);
      await sendDiscordErrorMessage(`\`activityUpdate\` error.\nSendgrid job could not be created.\nError:${error}`);
    }
    groupsProcessed += 1;
  }
  await sendDiscordMonitoringMessage(
    `\`activityUpdate.ts\` complete (${groupsProcessed} groups processed)\n${userActivities.length} users updated.`
  );

  exit(0);
};

mainActivity();
