/**
 * Utility to test the Shopify API connection
 */

import axios from "axios";
import { createLogger } from "../logger.js";
import { ShopifyCredentials } from "./theme-manager.js";

const logger = createLogger("connection-test");

/**
 * Tests the connection to the Shopify Admin API
 * @param credentials Shopify API credentials
 * @returns Object containing test result and message
 */
export async function testShopifyConnection(
  credentials: ShopifyCredentials
): Promise<{
  success: boolean;
  message: string;
  statusCode?: number;
  themes?: any[];
}> {
  try {
    // Test all possible authentication methods
    logger.info(`Testing connection to ${credentials.storeName}.myshopify.com`);

    const apiUrl = `https://${credentials.storeName}.myshopify.com/admin/api/2023-04/themes.json`;

    // Method 1: Access token in header (if it looks like one)
    const isAccessToken = credentials.password.startsWith("shpat_");
    let result;

    if (isAccessToken) {
      logger.info("Method 1: Trying with access token in header");
      try {
        const response = await axios.get(apiUrl, {
          headers: {
            "X-Shopify-Access-Token": credentials.password,
            "Content-Type": "application/json",
          },
        });

        if (response.status === 200 && response.data && response.data.themes) {
          const themes = response.data.themes;
          return {
            success: true,
            message: `Successfully connected using access token in header. Found ${themes.length} themes.`,
            statusCode: 200,
            themes,
          };
        }
      } catch (err: any) {
        logger.error(`Access token auth failed: ${err.message}`);
      }
    }

    // Method 2: API key + password basic auth
    logger.info("Method 2: Trying with API key + secret (basic auth)");
    try {
      const response = await axios.get(apiUrl, {
        auth: {
          username: credentials.apiKey,
          password: credentials.password,
        },
      });

      if (response.status === 200 && response.data && response.data.themes) {
        const themes = response.data.themes;
        return {
          success: true,
          message: `Successfully connected using API key + secret (basic auth). Found ${themes.length} themes.`,
          statusCode: 200,
          themes,
        };
      }
    } catch (err: any) {
      logger.error(`Basic auth failed: ${err.message}`);
    }

    // Method 3: Try using both API key and password together as the password
    logger.info("Method 3: Trying with API key:password as token");
    try {
      const combinedToken = `${credentials.apiKey}:${credentials.password}`;

      const response = await axios.get(apiUrl, {
        headers: {
          "X-Shopify-Access-Token": combinedToken,
          "Content-Type": "application/json",
        },
      });

      if (response.status === 200 && response.data && response.data.themes) {
        const themes = response.data.themes;
        return {
          success: true,
          message: `Successfully connected using combined token method. Found ${themes.length} themes.`,
          statusCode: 200,
          themes,
        };
      }
    } catch (err: any) {
      logger.error(`Combined token auth failed: ${err.message}`);
    }

    // Method 4: Try using just the API key as the access token (some legacy apps)
    logger.info("Method 4: Trying with just API key as token");
    try {
      const response = await axios.get(apiUrl, {
        headers: {
          "X-Shopify-Access-Token": credentials.apiKey,
          "Content-Type": "application/json",
        },
      });

      if (response.status === 200 && response.data && response.data.themes) {
        const themes = response.data.themes;
        return {
          success: true,
          message: `Successfully connected using API key as token. Found ${themes.length} themes.`,
          statusCode: 200,
          themes,
        };
      }
    } catch (err: any) {
      logger.error(`API key as token failed: ${err.message}`);
    }

    // Method 5: Try using private app password (legacy)
    logger.info("Method 5: Trying legacy private app auth");
    try {
      const response = await axios.get(apiUrl, {
        headers: {
          Authorization: `Basic ${Buffer.from(
            `${credentials.apiKey}:${credentials.password}`
          ).toString("base64")}`,
          "Content-Type": "application/json",
        },
      });

      if (response.status === 200 && response.data && response.data.themes) {
        const themes = response.data.themes;
        return {
          success: true,
          message: `Successfully connected using legacy private app auth. Found ${themes.length} themes.`,
          statusCode: 200,
          themes,
        };
      }
    } catch (err: any) {
      logger.error(`Legacy private app auth failed: ${err.message}`);
    }

    // If we got here, we tried all methods and none worked
    // Provide a detailed error message
    let message =
      "Failed to authenticate with Shopify using any authentication method. Please verify your credentials.";
    message += "\n\nFor API key + secret authentication, ensure:";
    message += "\n- Your API key is correct";
    message += "\n- Your shared secret/password is correct";
    message += "\n- Your app has sufficient permissions (themes read/write)";

    message += "\n\nFor access token authentication, ensure:";
    message += "\n- Your access token starts with 'shpat_'";
    message += "\n- The token is not expired";
    message += "\n- The token has sufficient permissions";

    return {
      success: false,
      message,
      statusCode: 401,
    };
  } catch (error: any) {
    // Handle any unexpected errors
    return {
      success: false,
      message: `Unexpected error: ${error.message}`,
      statusCode: 500,
    };
  }
}
