/**
 * Products Service
 * CRUD-Operationen für Products aus Appwrite
 * Filtert nach product_account_id für Account-Scoping
 */

import { databases, databaseId } from "../lib/appwrite";
import { Query, ID } from "appwrite";
import { getAccountById, deriveMarketFromAccount, deriveCurrencyFromMarket, updateAccountLastScanAt } from "./accountsService";
import { parseViaExtensionScanProducts } from "./ebayParserService";

const productsCollectionId = import.meta.env.VITE_APPWRITE_PRODUCTS_COLLECTION_ID || "products";

/**
 * Lädt alle Products für einen bestimmten Account
 * @param {string} accountId - ID des Accounts (product_account_id)
 * @param {Object} [options] - Optionale Parameter
 * @param {number} [options.limit] - Maximale Anzahl Ergebnisse (default: 25)
 * @param {number} [options.offset] - Offset für Pagination (default: 0)
 * @param {string} [options.orderBy] - Feld zum Sortieren (default: "$createdAt")
 * @param {string} [options.orderType] - Sortier-Richtung: "asc" oder "desc" (default: "desc")
 * @returns {Promise<Array>} Array von Product-Dokumenten
 */
export async function listProductsByAccount(accountId, options = {}) {
  if (!accountId) {
    console.warn("listProductsByAccount: accountId fehlt");
    return [];
  }

  const {
    limit = 25,
    offset = 0,
    orderBy = "$createdAt",
    orderType = "desc",
  } = options;

  try {
    const queries = [
      Query.equal("product_account_id", accountId),
      Query.orderDesc(orderBy), // orderType wird über Desc/Asc gehandhabt
      Query.limit(limit),
      Query.offset(offset),
    ];

    // Wenn orderType "asc" ist, verwende orderAsc statt orderDesc
    if (orderType === "asc") {
      queries[1] = Query.orderAsc(orderBy);
    }

    const response = await databases.listDocuments(
      databaseId,
      productsCollectionId,
      queries
    );

    return response.documents;
  } catch (e) {
    console.error("Fehler beim Laden der Products:", e);
    
    // Wenn Collection nicht existiert oder Berechtigungen fehlen
    if (e.code === 404 || e.code === 401 || e.type === 'collection_not_found') {
      // Placeholder: Collection existiert noch nicht
      console.warn("Products-Collection existiert noch nicht oder ist nicht verfügbar. Gebe leeres Array zurück.");
      return [];
    }
    
    throw e;
  }
}

/**
 * Lädt ein einzelnes Product nach ID
 * @param {string} productId - ID des Products
 * @returns {Promise<Object|null>} Product-Dokument oder null
 */
export async function getProductById(productId) {
  if (!productId) {
    console.warn("getProductById: productId fehlt");
    return null;
  }

  try {
    const document = await databases.getDocument(
      databaseId,
      productsCollectionId,
      productId
    );
    return document;
  } catch (e) {
    // 404 bedeutet, dass das Dokument nicht existiert
    if (e.code === 404 || e.type === 'document_not_found') {
      return null;
    }
    console.error("Fehler beim Laden des Products:", e);
    throw e;
  }
}

/**
 * Scannt Produkte für einen Account über die Extension (echte eBay-Daten)
 * @param {string} accountId - ID des Accounts
 * @returns {Promise<{ created: number, updated: number }>} Anzahl erstellter/aktualisierter Produkte
 */
export async function scanProductsForAccount(accountId) {
  if (!accountId) {
    throw new Error("accountId ist erforderlich");
  }

  try {
    // 1. Lade Account, um URL und andere Daten abzuleiten
    const account = await getAccountById(accountId);
    if (!account) {
      throw new Error("Account nicht gefunden");
    }

    if (!account.account_url) {
      throw new Error("Account-URL fehlt. Bitte Account refreshen.");
    }

    // 2. Extension aufrufen: scanne Produkte
    const items = await parseViaExtensionScanProducts(account.account_url, accountId);

    // 3. Response-Items zu Product-Schema mappen
    const mappedProducts = items.map(item => {
      // Validiere, dass platformProductId vorhanden ist
      if (!item.platformProductId) {
        console.warn("Item ohne platformProductId übersprungen:", item);
        return null;
      }

      return {
        product_platform_product_id: item.platformProductId,
        product_title: item.title || "",
        product_price: item.price ?? undefined, // undefined statt null für Appwrite
        product_currency: item.currency ?? undefined, // auto-fill from market if undefined
        product_url: item.url || "",
        product_status: item.status ?? "unknown",
        product_category: item.category ?? "unknown",
        product_condition: item.condition ?? "unknown"
      };
    }).filter(Boolean); // Entferne null-Einträge

    // 4. upsertProductsForAccount aufrufen
    const result = await upsertProductsForAccount(accountId, mappedProducts);

    // 5. account_last_scan_at aktualisieren
    await updateAccountLastScanAt(accountId, new Date().toISOString());

    // 6. Return { created, updated }
    return result;
  } catch (e) {
    console.error("Fehler beim Scannen der Produkte:", e);
    throw e;
  }
}

/**
 * Erstellt oder aktualisiert Produkte für einen Account (vorbereitet für Extension-Scans)
 * @param {string} accountId - ID des Accounts
 * @param {Array<Object>} products - Array von Produkt-Daten (kann partiell sein)
 * @returns {Promise<{ created: number, updated: number }>} Anzahl erstellter/aktualisierter Produkte
 */
export async function upsertProductsForAccount(accountId, products) {
  if (!accountId) {
    throw new Error("accountId ist erforderlich");
  }
  if (!Array.isArray(products) || products.length === 0) {
    return { created: 0, updated: 0 };
  }

  try {
    // Lade Account, um Market und andere Daten abzuleiten
    const account = await getAccountById(accountId);
    if (!account) {
      throw new Error("Account nicht gefunden");
    }

    // Leite Market und Currency aus Account ab
    const market = deriveMarketFromAccount(account);
    if (market === "UNKNOWN") {
      throw new Error(
        "Market konnte nicht erkannt werden. Bitte Account refreshen."
      );
    }

      const currency = deriveCurrencyFromMarket(market);
      const platform = "ebay"; // Enum-Werte sind lowercase gemäß Fehlermeldung: [amazon], [ebay]

    // Lade bestehende Produkte für Duplikat-Prüfung
    const existingProducts = await listProductsByAccount(accountId, {
      limit: 1000,
      offset: 0,
    });

    // Erstelle Map von platform_product_id -> bestehendes Produkt
    const existingProductsMap = new Map();
    existingProducts.forEach((p) => {
      if (p.product_platform_product_id) {
        existingProductsMap.set(p.product_platform_product_id, p);
      }
    });

    let created = 0;
    let updated = 0;

    // Verarbeite jedes Produkt
    for (const productData of products) {
      // Validiere, dass platform_product_id vorhanden ist
      if (!productData.product_platform_product_id) {
        console.warn("Produkt ohne product_platform_product_id übersprungen:", productData);
        continue;
      }

      const platformProductId = productData.product_platform_product_id;
      const existingProduct = existingProductsMap.get(platformProductId);

      // Ergänze fehlende erforderliche Felder aus Account
      const fullProductData = {
        product_account_id: accountId,
        product_platform: platform,
        product_platform_market: market,
        product_currency: currency,
        ...productData, // Produkt-Daten überschreiben Account-Daten wo vorhanden
      };

      try {
        if (existingProduct) {
          // Aktualisiere bestehendes Produkt
          await databases.updateDocument(
            databaseId,
            productsCollectionId,
            existingProduct.$id,
            fullProductData
          );
          updated++;
        } else {
          // Erstelle neues Produkt
          await databases.createDocument(
            databaseId,
            productsCollectionId,
            ID.unique(),
            fullProductData
          );
          created++;
        }
      } catch (e) {
        console.error(`Fehler beim Upsert des Produkts "${platformProductId}":`, e);
        // Weiter mit nächstem Produkt
        continue;
      }
    }

    return { created, updated };
  } catch (e) {
    console.error("Fehler beim Upsert der Produkte:", e);
    throw e;
  }
}
