import type { APIRoute } from 'astro';

const SENDPULSE_ID = process?.env?.SENDPULSE_ID || '';
const SENDPULSE_SECRET = process?.env?.SENDPULSE_SECRET || '';
const MPLS_ADDRESS_BOOK_ID = process?.env?.MPLS_ADDRESS_BOOK_ID || '1'; // Will be updated after creating the MPLS list
interface SendPulseTokenResponse {
  access_token: string;
  token_type: string;
  expires_in: number;
}

interface SendPulseAddressBook {
  id: number;
  name: string;
  emails: number;
}

interface SendPulseSubscribeResponse {
  result: boolean;
  error?: string;
}

async function verifyAltchaToken(token: string): Promise<boolean> {
  if (!token || token.length < 10) return false;
  try {
    const decoded = JSON.parse(atob(token));
    return decoded.challenge && decoded.salt && decoded.signature && typeof decoded.number === 'number';
  } catch {
    return false;
  }
}

async function getSendPulseToken(): Promise<string> {
  const response = await fetch('https://api.sendpulse.com/oauth/access_token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      grant_type: 'client_credentials',
      client_id: SENDPULSE_ID,
      client_secret: SENDPULSE_SECRET,
    }),
  });

  if (!response.ok) {
    const errorText = await response.text();
    console.error('SendPulse token error:', errorText);
    throw new Error('Failed to get SendPulse access token');
  }

  const data: SendPulseTokenResponse = await response.json();
  return data.access_token;
}

async function getAddressBooks(token: string): Promise<SendPulseAddressBook[]> {
  const response = await fetch('https://api.sendpulse.com/addressbooks', {
    method: 'GET',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
  });

  if (!response.ok) {
    throw new Error('Failed to get address books');
  }

  return response.json();
}

async function subscribeToSendPulse(email: string, token: string): Promise<void> {
  // Try to use the MPLS address book, or get the first available one
  let addressBookId = MPLS_ADDRESS_BOOK_ID;
  
  try {
    const addressBooks = await getAddressBooks(token);
    
    // Look for MPLS-specific address book first
    const mplsBook = addressBooks.find(book => 
      book.name.toLowerCase().includes('mpls') || 
      book.name.toLowerCase().includes('website')
    );
    
    if (mplsBook) {
      addressBookId = mplsBook.id.toString();
      console.log(`Using MPLS address book: ${mplsBook.name} (ID: ${addressBookId})`);
    } else if (!addressBooks.find(book => book.id.toString() === addressBookId) && addressBooks.length > 0) {
      // If the specified ID doesn't exist, use the first available address book
      addressBookId = addressBooks[0].id.toString();
      console.log(`Using default address book: ${addressBooks[0].name} (ID: ${addressBookId})`);
    }
  } catch (error) {
    console.warn('Could not fetch address books, using default ID');
  }

  const response = await fetch(`https://api.sendpulse.com/addressbooks/${addressBookId}/emails`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      emails: [
        {
          email: email,
          variables: {
            source: 'mpls-website',
            subscribed_date: new Date().toISOString()
          }
        }
      ]
    }),
  });

  if (!response.ok) {
    const errorData = await response.json().catch(() => ({}));
    const errorMessage = errorData.error || errorData.message || 'Failed to subscribe to newsletter';
    throw new Error(errorMessage);
  }

  const data: SendPulseSubscribeResponse = await response.json();
  if (!data.result) {
    throw new Error(data.error || 'Subscription failed');
  }
}

export const POST: APIRoute = async ({ request }) => {
  try {
    if (!SENDPULSE_ID || !SENDPULSE_SECRET) {
      return new Response(
        JSON.stringify({ error: 'Server is not configured for newsletter signup' }),
        { status: 500, headers: { 'Content-Type': 'application/json' } }
      );
    }

    const { email, altchaToken } = await request.json();

    // Validate email
    if (!email || typeof email !== 'string' || !email.includes('@')) {
      return new Response(
        JSON.stringify({ error: 'Invalid email address' }),
        { status: 400, headers: { 'Content-Type': 'application/json' } }
      );
    }

    // Validate ALTCHA token
    if (!altchaToken || typeof altchaToken !== 'string') {
      return new Response(
        JSON.stringify({ error: 'Security verification required' }),
        { status: 400, headers: { 'Content-Type': 'application/json' } }
      );
    }

    // Verify ALTCHA token
    const isValid = await verifyAltchaToken(altchaToken);
    if (!isValid) {
      return new Response(
        JSON.stringify({ error: 'Security verification failed. Please try again.' }),
        { status: 400, headers: { 'Content-Type': 'application/json' } }
      );
    }

    // Get SendPulse token
    const token = await getSendPulseToken();

    // Subscribe to newsletter
    await subscribeToSendPulse(email.toLowerCase().trim(), token);

    return new Response(
      JSON.stringify({ success: true, message: 'Successfully subscribed to newsletter' }),
      { status: 200, headers: { 'Content-Type': 'application/json' } }
    );

  } catch (error) {
    console.error('Newsletter subscription error:', error);
    
    // Don't expose detailed error messages to the client
    const userMessage = error instanceof Error && error.message.includes('already exists') 
      ? 'This email is already subscribed to our newsletter.'
      : 'Failed to subscribe. Please try again later.';
    
    return new Response(
      JSON.stringify({ error: userMessage }),
      { status: 500, headers: { 'Content-Type': 'application/json' } }
    );
  }
};

export const GET: APIRoute = () => {
  return new Response(
    JSON.stringify({ error: 'Method not allowed' }),
    { status: 405, headers: { 'Content-Type': 'application/json' } }
  );
};
