import { google } from 'googleapis';
import dotenv from 'dotenv';

export interface GmailMessage {
  id?: string;
  raw?: string;
  headers?: Array<{
    name: string;
    value: string;
  }>;
  labelIds?: string[];
  snippet?: string;
  body?: string;
  subject?: string;
  from?: string;
  to?: string;
}

dotenv.config();

export class GmailAPI {
  private static GMAIL_REDIRECT_URI = 'http://localhost';

  private constructor() {}

  private static async getOAuth2Client(clientId: string, clientSecret: string, refreshToken: string) {
    const oAuth2Client = new google.auth.OAuth2(
      clientId,
      clientSecret,
      this.GMAIL_REDIRECT_URI
    );
    oAuth2Client.setCredentials({ refresh_token: refreshToken });
    return oAuth2Client;
  }

  private static async getGmail(clientId: string, clientSecret: string, refreshToken: string) {
    const auth = await this.getOAuth2Client(clientId, clientSecret, refreshToken);
    return google.gmail({ version: 'v1', auth });
  }

  static async getAccessToken(clientId: string, clientSecret: string, refreshToken: string): Promise<string> {
    const oAuth2Client = await this.getOAuth2Client(clientId, clientSecret, refreshToken);
    const { token } = await oAuth2Client.getAccessToken();
    return token || '';
  }

  static async listMessages(clientId: string, clientSecret: string, refreshToken: string, query: string): Promise<GmailMessage[]> {
    const gmail = await this.getGmail(clientId, clientSecret, refreshToken);
    const res = await gmail.users.messages.list({
      userId: 'me',
      q: query,
    });
    return (res.data.messages || []).map(msg => ({
      id: msg.id || undefined,
      labelIds: msg.labelIds || undefined
    }));
  }

  static async getMessage(clientId: string, clientSecret: string, refreshToken: string, msgId: string): Promise<GmailMessage> {
    const gmail = await this.getGmail(clientId, clientSecret, refreshToken);
    const res = await gmail.users.messages.get({
      userId: 'me',
      id: msgId,
      format: 'full',
    });
    
    // Extract headers
    const headers = res.data.payload?.headers?.map(h => ({
      name: h.name || '',
      value: h.value || ''
    })) || [];

    // Find email metadata
    const subject = headers.find(h => h.name.toLowerCase() === 'subject')?.value;
    const from = headers.find(h => h.name.toLowerCase() === 'from')?.value;
    const to = headers.find(h => h.name.toLowerCase() === 'to')?.value;

    // Decode email body
    let body = '';
    if (res.data.payload?.body?.data) {
      body = Buffer.from(res.data.payload.body.data, 'base64').toString('utf8');
    } else if (res.data.payload?.parts) {
      const textPart = res.data.payload.parts.find(part => part.mimeType === 'text/plain');
      if (textPart?.body?.data) {
        body = Buffer.from(textPart.body.data, 'base64').toString('utf8');
      }
    }

    return {
      id: res.data.id || undefined,
      headers,
      labelIds: res.data.labelIds || undefined,
      snippet: res.data.snippet || undefined,
      body,
      subject,
      from,
      to
    };
  }
}
