import { exit } from 'process';
import query from '../server-utils/query.js';
import { sendDiscordErrorMessage, sendDiscordMonitoringMessage } from './notification.js';

// When any update is made to sendgrid, a JobID is returned.
// We need to check on the jobID to see if anything has changed.

// Docs for contact statuses:
// https://docs.sendgrid.com/api-reference/contacts/import-contacts-status

// Sendgrid job available statuses
// pending, completed, errored, or failed

/*
  Table DDL:
  CREATE TABLE sendgrid_sync_jobs (
    id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    job_id character varying(255) NOT NULL,
    status character varying(255) NOT NULL,
    response jsonb,
    created_at timestamp without time zone NOT NULL DEFAULT now(),
    updated_at timestamp without time zone NOT NULL DEFAULT now()
  );
*/

const checkSendgridJob = async (job_id: string): Promise<{ jobStatus: string; response: any }> => {
  const URL = `https://api.sendgrid.com/v3/marketing/contacts/imports/${job_id}`;
  const API_KEY = process.env.SENDGRID_API_KEY;
  // Use axios to get response from sendgrid using bearer token

  const response = await fetch(URL, {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${API_KEY}`,
    },
  });

  const responseData = await response.json();
  const { status } = responseData;

  return { jobStatus: status, response: responseData };
};

const checkSendgridJobs = async () => {
  console.log('Checking sendgrid jobs');
  const queryResult = await query(
    `
      SELECT id, job_id, created_at FROM sendgrid_sync_jobs
      WHERE status = 'pending'
    `,
    []
  );

  const pendingJobs = queryResult.rows;

  console.log(`Found ${pendingJobs.length} pending jobs`);
  const completedJobs: string[] = [];
  let errorCount = 0;
  let pendingCount = 0;
  for (const job of pendingJobs) {
    const { id, job_id, created_at } = job;

    console.log(`Checking job ${job_id}`);
    const { jobStatus, response } = await checkSendgridJob(job_id);
    console.log(`Job ${job_id} is ${jobStatus}`);

    if (jobStatus === 'completed') {
      completedJobs.push(`[${id}] ${job_id} (${created_at})`);
    } else if (jobStatus !== 'pending') {
      errorCount++;
      // Get errors urls
      let error_url = response?.results?.errors_url;
      const message = `Sendgrid job ${job_id} has ${jobStatus}! DB ID: [${id}] Job Creation Timestamp: ${created_at}\n${error_url}`;
      console.log(message);
      await sendDiscordErrorMessage(message);
    } else {
      pendingCount++;
    }
    await query(
      `
        UPDATE sendgrid_sync_jobs
        SET status = $1, response = $2::jsonb
        WHERE job_id = $3
      `,
      [jobStatus, JSON.stringify(response), job_id]
    );
  }

  const message = `Checked ${
    pendingJobs.length
  } sendgrid jobs. ${pendingCount} still pending. ${errorCount} errors.\nCompleted Jobs (${
    completedJobs.length
  })\n${completedJobs.join('\n')}`;
  await sendDiscordMonitoringMessage(message);
  console.log(message);
};

const main = async () => {
  await checkSendgridJobs();
  exit(0);
};

main();
