import Shopify from "shopify-api-node";
import path from "path";
import fs from "fs/promises";
import { ThemeManager } from "./theme-manager.js";
import { createLogger } from "../logger.js";

const logger = createLogger("theme-api");

export interface ThemePage {
  path: string;
  template: string;
  type:
    | "static"
    | "collections"
    | "pages"
    | "blogs"
    | "products"
    | "collections";
  title: string;
}

export interface ThemeMetadata {
  pages: ThemePage[];
  templates: {
    [key: string]: {
      path: string;
      sections: string[];
      snippets: string[];
    };
  };
  assets: string[];
  config: {
    settings_schema: any;
    settings_data: any;
  };
}

export class ThemeAPI {
  private shopify: Shopify;
  private themeManager: ThemeManager;
  private themeDir: string;
  private metadata: ThemeMetadata | null = null;

  constructor(shopify: Shopify, themeManager: ThemeManager, themeDir: string) {
    this.shopify = shopify;
    this.themeManager = themeManager;
    this.themeDir = themeDir;
    logger.info(`ThemeAPI initialized with theme directory: ${themeDir}`);
    logger.info(
      `Using Shopify client with shop: ${(shopify as any).options.shopName}`
    );
  }

  async getPages(): Promise<ThemePage[]> {
    const templates = await this.getStaticTemplates();
    const pages: ThemePage[] = [];

    // Add static pages
    pages.push({
      path: "/",
      template: "index",
      type: "static",
      title: "Home",
    });

    // Add product pages if template exists
    if (templates.includes("product")) {
      pages.push({
        path: "/products/example-product",
        template: "product",
        type: "products",
        title: "Example Product",
      });
    }

    // Add collection pages if template exists
    if (templates.includes("collection")) {
      pages.push({
        path: "/collections/example-collection",
        template: "collection",
        type: "collections",
        title: "Example Collection",
      });
    }

    // Add cart page if template exists
    if (templates.includes("cart")) {
      pages.push({
        path: "/cart",
        template: "cart",
        type: "static",
        title: "Cart",
      });
    }

    // Add search page if template exists
    if (templates.includes("search")) {
      pages.push({
        path: "/search",
        template: "search",
        type: "static",
        title: "Search",
      });
    }

    // Add contact page if it exists
    if (templates.includes("page.contact")) {
      pages.push({
        path: "/pages/contact",
        template: "page.contact",
        type: "pages",
        title: "Contact",
      });
    }

    // Add blog page if it exists
    if (templates.includes("blog")) {
      pages.push({
        path: "/blogs/news",
        template: "blog",
        type: "blogs",
        title: "Blog",
      });
    }

    return pages;
  }

  private async getStaticTemplates(): Promise<string[]> {
    try {
      const templateDir = path.join(this.themeDir, "templates");
      logger.info(`Reading template directory: ${templateDir}`);
      const files = await fs.readdir(templateDir);
      const templates = files
        .filter((file) => file.endsWith(".json"))
        .map((file) => file.replace(".json", ""));
      logger.info(`Found templates: ${templates.join(", ")}`);
      return templates;
    } catch (error) {
      logger.error(`Failed to read templates: ${(error as Error).message}`);
      throw error;
    }
  }

  async getMetadata(): Promise<ThemeMetadata> {
    if (this.metadata) {
      logger.info("Returning cached metadata");
      return this.metadata;
    }

    try {
      const pages = await this.getPages();
      this.metadata = {
        pages,
        templates: {},
        assets: [],
        config: {
          settings_schema: [],
          settings_data: {},
        },
      };
      return this.metadata;
    } catch (error) {
      logger.error("Failed to fetch metadata:");
      logger.error(error);
      throw error;
    }
  }

  async getPageMetadata(path: string): Promise<ThemePage | null> {
    logger.info(`Getting metadata for page: ${path}`);
    const pages = await this.getPages();
    const page = pages.find((p) => p.path === path);
    if (page) {
      logger.info(`Found metadata for page: ${JSON.stringify(page, null, 2)}`);
    } else {
      logger.warn(`No metadata found for page: ${path}`);
    }
    return page || null;
  }

  invalidateCache() {
    logger.info("Invalidating metadata cache");
    this.metadata = null;
  }
}
