// Run once every day. To update the proness of users.

import { exit } from 'process';
import { sendDiscordErrorMessage, sendDiscordMonitoringMessage } from './notification.js';
import { convertToRFC3339Date, getUserSubscriptionInfoPast35Days, insertJob } from './sendgridSyncFunctions.js';
import { logger } from '../server-utils/logger.js';
import { syncUserSubscriptionInfoToZoho } from '../controllers/zohoSync.js';

interface SendgridContact {
  email: string;
  custom_fields: {
    pro_start_date: string;
    pro_until_date: string;
    is_pro: 'yes' | 'no';
    trial_end_date: string;
    current_tier: string;
    previous_tier: string;
  };
}

const main = async () => {
  // Perform subscription query
  logger.info('Running Subscription Update');
  const userSubscriptionInfo = await getUserSubscriptionInfoPast35Days();

  logger.info(`Found ${userSubscriptionInfo.length} users`);
  // Count pro users
  let proCount = 0;
  let indieCount = 0;

  for (const userProObject of userSubscriptionInfo) {
    if (userProObject.current_tier == 'Pro') {
      proCount++;
    } else if (userProObject.current_tier == 'Indie') {
      indieCount++;
    }
  }

  let basicCount = userSubscriptionInfo.length - proCount - indieCount;

  logger.info(
    `Found ${proCount} Pro users, ${indieCount} Indie users, and ${basicCount} Basic users in the past 31 days.`
  );

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

  const contacts: SendgridContact[] = [];
  for (const userProObject of userSubscriptionInfo) {
    contacts.push({
      email: userProObject.email,
      custom_fields: {
        pro_start_date: convertToRFC3339Date(userProObject.pro_start_date),
        pro_until_date: convertToRFC3339Date(userProObject.pro_until_date),
        is_pro: userProObject.is_pro ? 'yes' : 'no',
        trial_end_date: convertToRFC3339Date(userProObject.trial_end_date), // to use this field on SendGrid to check if the user has ever had a free trial
        current_tier: userProObject.current_tier,
        previous_tier: userProObject.previous_tier || '', // SendGrid fields cannot be null
      },
    });
  }
  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(
        `\`subscriptionUpdate\` error.\nSendgrid job could not be created.\nResponse:${JSON.stringify(responseData)}`
      );
      console.error('Error creating sendgrid job.');
      console.error(responseData);
    }
    await insertJob(job_id, 'subscriptionUpdate');

    logger.info('Sendgrid job created. Job ID: ' + job_id);
    await sendDiscordMonitoringMessage(
      `\`subscriptionUpdate.ts\` run.\nFound ${proCount} pro users, and ${
        userSubscriptionInfo.length - proCount
      } non-pro users in the past 31 days.\nSendgrid jobs created.\nJob ID: ${job_id}`
    );
  } catch (error) {
    console.error(error);
    await sendDiscordErrorMessage(`\`subscriptionUpdate\` error.\nSendgrid job could not be created.\nError:${error}`);
  }

  logger.info('Starting Zoho sync...');
  // Split into groups of 100
  const userSubscriptionInfoChunks = [];
  const chunkSize = 100;
  for (let i = 0; i < userSubscriptionInfo.length; i += chunkSize) {
    userSubscriptionInfoChunks.push(userSubscriptionInfo.slice(i, i + chunkSize));
  }

  logger.info(`Split into ${userSubscriptionInfoChunks.length} chunks`);

  let passed = true;
  // Sync the users with Zoho
  for (const userChunk of userSubscriptionInfoChunks) {
    if (!(await syncUserSubscriptionInfoToZoho(userChunk))) passed = false;
  }

  if (passed) {
    logger.info('Zoho sync completed successfully');
    await sendDiscordMonitoringMessage(`\`subscriptionUpdate.ts\` run.\n.Zoho sync completed successfully.`);
  } else {
    logger.error('Zoho sync failed');
    await sendDiscordErrorMessage(`\`subscriptionUpdate.ts\` error.\nZoho sync failed (check database for more info).`);
  }

  exit();
};

main();
