import axios from 'axios';
import { env } from '../../config/env.js';
import { META_GRAPH_API_BASE, IG_GRAPH_API_VERSION } from '../../config/constants.js';
import { logger } from '../../utils/logger.js';

const META_API = `${META_GRAPH_API_BASE}/${IG_GRAPH_API_VERSION}`;

export interface IgTokenResponse {
  access_token: string;
  token_type: string;
  expires_in?: number;
}

export interface IgUserProfile {
  id: string;
  username: string;
  name?: string;
  account_type?: string;
  profile_picture_url?: string;
}

/**
 * Build the Instagram OAuth authorization URL
 */
export function getInstagramAuthUrl(state: string): string {
  const params = new URLSearchParams({
    client_id: env.meta.appId,
    redirect_uri: env.meta.igRedirectUri,
    scope: 'instagram_basic,instagram_manage_comments,instagram_manage_insights,pages_show_list,pages_read_engagement',
    response_type: 'code',
    state,
  });

  return `https://www.facebook.com/${IG_GRAPH_API_VERSION}/dialog/oauth?${params.toString()}`;
}

/**
 * Exchange authorization code for short-lived access token
 */
export async function exchangeCodeForToken(code: string): Promise<IgTokenResponse> {
  const response = await axios.post(`${META_API}/oauth/access_token`, null, {
    params: {
      client_id: env.meta.appId,
      client_secret: env.meta.appSecret,
      grant_type: 'authorization_code',
      redirect_uri: env.meta.igRedirectUri,
      code,
    },
  });

  return response.data;
}

/**
 * Exchange short-lived token for long-lived token (60 days)
 */
export async function getLongLivedToken(shortToken: string): Promise<IgTokenResponse> {
  const response = await axios.get(`${META_API}/oauth/access_token`, {
    params: {
      grant_type: 'fb_exchange_token',
      client_id: env.meta.appId,
      client_secret: env.meta.appSecret,
      fb_exchange_token: shortToken,
    },
  });

  return response.data;
}

/**
 * Get Instagram Business/Creator account ID linked to a Facebook Page
 */
export async function getInstagramAccountId(
  pageAccessToken: string,
  pageId: string,
): Promise<string | null> {
  const response = await axios.get(`${META_API}/${pageId}`, {
    params: {
      fields: 'instagram_business_account',
      access_token: pageAccessToken,
    },
  });

  return response.data?.instagram_business_account?.id ?? null;
}

/**
 * Get all Facebook Pages the user manages
 */
export async function getUserPages(accessToken: string): Promise<Array<{ id: string; name: string; access_token: string }>> {
  const response = await axios.get(`${META_API}/me/accounts`, {
    params: { access_token: accessToken },
  });

  return response.data?.data ?? [];
}

/**
 * Get Instagram user profile
 */
export async function getIgProfile(igAccountId: string, accessToken: string): Promise<IgUserProfile> {
  const response = await axios.get(`${META_API}/${igAccountId}`, {
    params: {
      fields: 'id,username,name,account_type,profile_picture_url',
      access_token: accessToken,
    },
  });

  return response.data;
}

/**
 * Subscribe to Instagram webhooks (live_comments, comments)
 */
export async function subscribeToWebhooks(pageId: string, pageAccessToken: string): Promise<boolean> {
  try {
    const response = await axios.post(
      `${META_API}/${pageId}/subscribed_apps`,
      null,
      {
        params: {
          subscribed_fields: 'feed,live_comments',
          access_token: pageAccessToken,
        },
      },
    );
    logger.info({ pageId }, '[IG] Webhook subscription successful');
    return response.data?.success ?? false;
  } catch (err) {
    logger.error({ err, pageId }, '[IG] Failed to subscribe to webhooks');
    return false;
  }
}

/**
 * Reply to an Instagram comment
 */
export async function replyToComment(
  commentId: string,
  message: string,
  accessToken: string,
): Promise<boolean> {
  try {
    await axios.post(`${META_API}/${commentId}/replies`, null, {
      params: {
        message,
        access_token: accessToken,
      },
    });
    return true;
  } catch (err) {
    logger.error({ err, commentId }, '[IG] Failed to reply to comment');
    return false;
  }
}
