// Runs ad-hoc, whenever we need to do a full update of all the user information.
import { exit } from 'process';
import { sendDiscordErrorMessage, sendDiscordMonitoringMessage } from './notification.js';
import {
  SendgridUserProperties,
  convertToRFC3339Date,
  getUserPropertiesFromSignups,
  insertJob,
} from './sendgridSyncFunctions.js';

// Note: Sendgrid does not support boolean custom fields, so we use yes/no instead.
type SendgridContact = {
  email: string;
  custom_fields: {
    is_employee: string; // yes or no
    is_beta: string; // yes or no
    signup_date: string; // RFC3339 date
    last_activity_date: string; // RFC3339 date
    trial_end_date: string; // RFC3339 date
    modulo2: number;
    modulo3: number;
    modulo4: number;
    is_pro: string; // yes or no
    current_tier: string;
    previous_tier: string;
    past_30d_active_days: number;
    past_30d_activity_count: number;
    past_30d_composer_count: number;
    past_30d_conductor_count: number;
  };
};

const GROUP_SIZE = 9000;

const main = async () => {
  // Perform user queries
  const userProperties = await getUserPropertiesFromSignups(2000);
  console.log(
    `Found ${userProperties.length} users, splitting into ${Math.ceil(userProperties.length / GROUP_SIZE)} jobs.`
  );

  // Break into groups of 5000
  const userPropertiesGroups: SendgridUserProperties[][] = [];
  let userPropertiesGroup: SendgridUserProperties[] = [];
  for (const userProperty of userProperties) {
    userPropertiesGroup.push(userProperty);
    if (userPropertiesGroup.length >= GROUP_SIZE) {
      userPropertiesGroups.push(userPropertiesGroup);
      userPropertiesGroup = [];
    }
  }
  userPropertiesGroups.push(userPropertiesGroup);

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

  let groupsProcessed = 0;
  const jobIds: any = [];
  for (const userPropertiesGroup of userPropertiesGroups) {
    console.log(`Processing ${groupsProcessed} of ${userPropertiesGroups.length} groups`);
    const contacts: SendgridContact[] = userPropertiesGroup.map((userProperties) => {
      return {
        email: userProperties.email,
        custom_fields: {
          is_employee: userProperties.is_employee ? 'yes' : 'no',
          is_beta: userProperties.is_beta ? 'yes' : 'no',
          signup_date: convertToRFC3339Date(userProperties.signup_date),
          last_activity_date: convertToRFC3339Date(userProperties.last_activity_date),
          trial_end_date: convertToRFC3339Date(userProperties.trial_end_date),
          modulo2: userProperties.modulo2,
          modulo3: userProperties.modulo3,
          modulo4: userProperties.modulo4,
          // Set defaults for new fields, these will be updated later on by other scripts.
          is_pro: 'no',
          current_tier: '',
          previous_tier: '',
          past_30d_active_days: 0,
          past_30d_activity_count: 0,
          past_30d_composer_count: 0,
          past_30d_conductor_count: 0,
        },
      };
    });
    const payload = {
      contacts,
    };
    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(
        `\`updateAllUsers\` error.\nSendgrid job could not be created.\nResponse:${JSON.stringify(responseData)}`
      );
      console.error('No job_id returned from sendgrid');
      console.error(responseData);
      continue;
    }
    console.log(`Sendgrid job created. Job ID: ${job_id}`);
    await insertJob(job_id, 'updateAllUsers');

    jobIds.push(job_id);
    groupsProcessed += 1;
  }
  await sendDiscordMonitoringMessage(
    `\`updateAllUsers.ts\` run.\nSendgrid jobs created. Job IDs:\n${jobIds.join('\n')}`
  );
  exit(0);
};

main();
