/**
 * Monitor: Status Checker
 * Checks brand and campaign status via Twilio API
 */

import twilio from 'twilio';
import pino from 'pino';
import type { SubmissionStatus } from '../types';

const logger = pino({ name: 'status-checker' });

export interface BrandStatusResult {
  status: SubmissionStatus;
  failureReason?: string;
  identityStatus?: string;
  rawStatus: string;
}

export interface CampaignStatusResult {
  status: SubmissionStatus;
  failureReason?: string;
  rawStatus: string;
}

/**
 * Check brand registration status
 */
export async function checkBrandStatus(
  brandRegistrationSid: string
): Promise<BrandStatusResult> {
  const accountSid = process.env.TWILIO_ACCOUNT_SID!;
  const authToken = process.env.TWILIO_AUTH_TOKEN!;
  const client = twilio(accountSid, authToken);

  try {
    const brand = await client.messaging.v1.brandRegistrations(brandRegistrationSid).fetch();

    logger.debug({
      brandSid: brandRegistrationSid,
      status: brand.status,
      identityStatus: brand.identityStatus,
      failureReason: brand.failureReason,
    }, 'Brand status fetched');

    // Map Twilio status to our internal status
    let status: SubmissionStatus;
    switch (brand.status) {
      case 'PENDING':
      case 'IN_REVIEW':
        status = 'brand_pending';
        break;
      case 'APPROVED':
        status = 'brand_approved';
        break;
      case 'FAILED':
      case 'REJECTED':
        status = 'brand_failed';
        break;
      case 'SUSPENDED':
        status = 'manual_review';
        break;
      default:
        logger.warn({ status: brand.status }, 'Unknown brand status');
        status = 'brand_pending';
    }

    return {
      status,
      failureReason: brand.failureReason || undefined,
      identityStatus: brand.identityStatus,
      rawStatus: brand.status,
    };
  } catch (error) {
    logger.error({ error, brandSid: brandRegistrationSid }, 'Error checking brand status');
    throw error;
  }
}

/**
 * Check campaign (UsAppToPerson) status
 */
export async function checkCampaignStatus(
  campaignSid: string
): Promise<CampaignStatusResult> {
  const accountSid = process.env.TWILIO_ACCOUNT_SID!;
  const authToken = process.env.TWILIO_AUTH_TOKEN!;
  const client = twilio(accountSid, authToken);

  try {
    // Fetch campaign using the UsAppToPerson resource
    // Note: The campaignSid here is actually the UsAppToPerson SID (starts with QE)
    const campaigns = await client.messaging.v1.a2pUsAppToPerson.list({ limit: 1000 });
    const a2pCampaign = campaigns.find(c => c.sid === campaignSid);

    if (!a2pCampaign) {
      throw new Error(`Campaign not found: ${campaignSid}`);
    }

    logger.debug({
      campaignSid,
      status: a2pCampaign.campaignStatus,
      failureReason: a2pCampaign.failureReason,
    }, 'Campaign status fetched');

    // Map Twilio campaign status to our internal status
    let status: SubmissionStatus;
    switch (a2pCampaign.campaignStatus) {
      case 'PENDING':
      case 'IN_REVIEW':
        status = 'campaign_pending';
        break;
      case 'VERIFIED':
      case 'APPROVED':
        status = 'campaign_approved';
        break;
      case 'FAILED':
      case 'REJECTED':
        status = 'campaign_failed';
        break;
      case 'SUSPENDED':
        status = 'manual_review';
        break;
      default:
        logger.warn({ status: a2pCampaign.campaignStatus }, 'Unknown campaign status');
        status = 'campaign_pending';
    }

    return {
      status,
      failureReason: a2pCampaign.failureReason || undefined,
      rawStatus: a2pCampaign.campaignStatus,
    };
  } catch (error) {
    logger.error({ error, campaignSid }, 'Error checking campaign status');
    throw error;
  }
}
