import {
  OAuthError,
  OAuthErrorType
} from "./types";
const PROVIDER_ENDPOINTS = {
  facebook: {
    userInfo: "https://graph.facebook.com/v18.0/me",
    pages: "https://graph.facebook.com/v18.0/me/accounts",
    pageInfo: (pageId) => `https://graph.facebook.com/v18.0/${pageId}`
  },
  instagram: {
    userInfo: "https://graph.facebook.com/v18.0/me",
    businessAccounts: "https://graph.facebook.com/v18.0/me/accounts",
    instagramAccount: (pageId) => `https://graph.facebook.com/v18.0/${pageId}?fields=instagram_business_account`,
    accountInfo: (igAccountId) => `https://graph.facebook.com/v18.0/${igAccountId}?fields=id,username,profile_picture_url,followers_count`
  },
  google: {
    userInfo: "https://www.googleapis.com/oauth2/v2/userinfo"
  }
};
class MetadataManager {
  /**
   * Fetch metadata from provider API
   *
   * @param provider - OAuth provider
   * @param accessToken - Valid access token with appropriate scopes
   * @returns Provider-specific metadata
   */
  static async fetchMetadata(provider, accessToken) {
    try {
      switch (provider) {
        case "facebook":
          return await this.fetchFacebookMetadata(accessToken);
        case "instagram":
          return await this.fetchInstagramMetadata(accessToken);
        case "google":
          return await this.fetchGoogleMetadata(accessToken);
        default:
          throw new OAuthError(
            OAuthErrorType.PROVIDER_ERROR,
            `Unsupported provider: ${provider}`,
            provider
          );
      }
    } catch (error) {
      if (error instanceof OAuthError) {
        throw error;
      }
      throw new OAuthError(
        OAuthErrorType.PROVIDER_ERROR,
        `Failed to fetch metadata from ${provider}`,
        provider,
        error instanceof Error ? error : void 0
      );
    }
  }
  /**
   * Fetch Facebook metadata (pages, page info)
   */
  static async fetchFacebookMetadata(accessToken) {
    var _a, _b, _c;
    try {
      const pagesResponse = await fetch(
        `${PROVIDER_ENDPOINTS.facebook.pages}?access_token=${accessToken}&fields=id,name,category,access_token,picture`,
        { method: "GET" }
      );
      if (!pagesResponse.ok) {
        throw new Error(`Facebook API error: ${pagesResponse.statusText}`);
      }
      const pagesData = await pagesResponse.json();
      const firstPage = (_a = pagesData.data) == null ? void 0 : _a[0];
      if (!firstPage) {
        throw new Error("No Facebook pages found for this account");
      }
      return {
        pageId: firstPage.id,
        pageName: firstPage.name,
        pageAccessToken: firstPage.access_token,
        pageCategory: firstPage.category,
        pageProfilePictureUrl: (_c = (_b = firstPage.picture) == null ? void 0 : _b.data) == null ? void 0 : _c.url
      };
    } catch (error) {
      throw new OAuthError(
        OAuthErrorType.PROVIDER_ERROR,
        "Failed to fetch Facebook metadata",
        "facebook",
        error instanceof Error ? error : void 0
      );
    }
  }
  /**
   * Fetch Instagram metadata (business account info)
   */
  static async fetchInstagramMetadata(accessToken) {
    var _a, _b;
    try {
      const pagesResponse = await fetch(
        `${PROVIDER_ENDPOINTS.instagram.businessAccounts}?access_token=${accessToken}`,
        { method: "GET" }
      );
      if (!pagesResponse.ok) {
        throw new Error(`Facebook API error: ${pagesResponse.statusText}`);
      }
      const pagesData = await pagesResponse.json();
      const firstPage = (_a = pagesData.data) == null ? void 0 : _a[0];
      if (!firstPage) {
        throw new Error("No Facebook pages found");
      }
      const igAccountResponse = await fetch(
        PROVIDER_ENDPOINTS.instagram.instagramAccount(firstPage.id) + `&access_token=${accessToken}`,
        { method: "GET" }
      );
      if (!igAccountResponse.ok) {
        throw new Error(`Instagram API error: ${igAccountResponse.statusText}`);
      }
      const igAccountData = await igAccountResponse.json();
      const igBusinessAccountId = (_b = igAccountData.instagram_business_account) == null ? void 0 : _b.id;
      if (!igBusinessAccountId) {
        throw new Error("No Instagram Business Account linked to this Facebook page");
      }
      const igInfoResponse = await fetch(
        PROVIDER_ENDPOINTS.instagram.accountInfo(igBusinessAccountId) + `&access_token=${accessToken}`,
        { method: "GET" }
      );
      if (!igInfoResponse.ok) {
        throw new Error(`Instagram API error: ${igInfoResponse.statusText}`);
      }
      const igInfo = await igInfoResponse.json();
      return {
        instagramBusinessId: igInfo.id,
        instagramUsername: igInfo.username,
        profilePictureUrl: igInfo.profile_picture_url,
        followersCount: igInfo.followers_count
      };
    } catch (error) {
      throw new OAuthError(
        OAuthErrorType.PROVIDER_ERROR,
        "Failed to fetch Instagram metadata",
        "instagram",
        error instanceof Error ? error : void 0
      );
    }
  }
  /**
   * Fetch Google metadata (basic profile info)
   */
  static async fetchGoogleMetadata(accessToken) {
    try {
      const response = await fetch(PROVIDER_ENDPOINTS.google.userInfo, {
        method: "GET",
        headers: {
          Authorization: `Bearer ${accessToken}`
        }
      });
      if (!response.ok) {
        throw new Error(`Google API error: ${response.statusText}`);
      }
      const data = await response.json();
      return {
        email: data.email,
        name: data.name,
        picture: data.picture
      };
    } catch (error) {
      throw new OAuthError(
        OAuthErrorType.PROVIDER_ERROR,
        "Failed to fetch Google metadata",
        "google",
        error instanceof Error ? error : void 0
      );
    }
  }
  /**
   * Validate metadata structure
   *
   * @param provider - OAuth provider
   * @param metadata - Metadata to validate
   * @returns true if valid
   */
  static validateMetadata(provider, metadata) {
    try {
      switch (provider) {
        case "facebook":
          const fbMeta = metadata;
          return !!(fbMeta.pageId && fbMeta.pageName);
        case "instagram":
          const igMeta = metadata;
          return !!(igMeta.instagramBusinessId && igMeta.instagramUsername);
        case "google":
          const googleMeta = metadata;
          return !!(googleMeta.email && googleMeta.name);
        default:
          return false;
      }
    } catch {
      return false;
    }
  }
  /**
   * Refresh metadata (re-fetch from provider)
   *
   * @param provider - OAuth provider
   * @param accessToken - Current access token
   * @returns Updated metadata
   */
  static async refreshMetadata(provider, accessToken) {
    console.log(`Refreshing metadata for provider: ${provider}`);
    return await this.fetchMetadata(provider, accessToken);
  }
  /**
   * Merge existing metadata with new metadata (for partial updates)
   *
   * @param existing - Existing metadata
   * @param updates - New metadata to merge
   * @returns Merged metadata
   */
  static mergeMetadata(existing, updates) {
    return {
      ...existing,
      ...updates
    };
  }
  /**
   * Extract display name from metadata (for UI)
   *
   * @param provider - OAuth provider
   * @param metadata - Provider metadata
   * @returns Display name
   */
  static getDisplayName(provider, metadata) {
    switch (provider) {
      case "facebook":
        return metadata.pageName || "Facebook Page";
      case "instagram":
        return `@${metadata.instagramUsername || "instagram"}`;
      case "google":
        return metadata.name || metadata.email;
      default:
        return provider;
    }
  }
  /**
   * Extract profile picture URL from metadata (for UI)
   *
   * @param provider - OAuth provider
   * @param metadata - Provider metadata
   * @returns Profile picture URL or undefined
   */
  static getProfilePicture(provider, metadata) {
    switch (provider) {
      case "facebook":
        return metadata.pageProfilePictureUrl;
      case "instagram":
        return metadata.profilePictureUrl;
      case "google":
        return metadata.picture;
      default:
        return void 0;
    }
  }
}
export {
  MetadataManager
};
