/**
 * Dashboard Service
 * Stellt aggregierte Dashboard-Daten bereit, gescoped nach activeAccountId
 * Nutzt productsService und accountsService für Datenabfragen
 */

import { listProductsByAccount, getProductById } from "./productsService";
import { databases, databaseId } from "../lib/appwrite";
import { Query } from "appwrite";

const productDetailsCollectionId =
  import.meta.env.VITE_APPWRITE_PRODUCT_DETAILS_COLLECTION_ID || "product_details";

/**
 * Lädt Overview KPIs für einen aktiven Account
 * @param {string} activeAccountId - ID des aktiven Accounts
 * @returns {Promise<{ totalProducts: number, activeProducts: number, endedProducts: number, avgPrice: number | null, newestProducts: Array }>}
 */
export async function getOverviewKPIs(activeAccountId) {
  if (!activeAccountId) {
    return {
      totalProducts: 0,
      activeProducts: 0,
      endedProducts: 0,
      avgPrice: null,
      newestProducts: [],
    };
  }

  try {
    // Lade bis zu 200 Products für KPI-Berechnung
    const products = await listProductsByAccount(activeAccountId, {
      limit: 200,
      offset: 0,
      orderBy: "$createdAt",
      orderType: "desc",
    });

    const totalProducts = products.length;

    // Filtere nach Status
    const activeProducts = products.filter(
      (p) => p.product_status === "active" || p.product_status === "Active"
    );
    const endedProducts = products.filter(
      (p) => p.product_status === "ended" || p.product_status === "Ended"
    );

    // Berechne Durchschnittspreis für aktive Products
    const activeWithPrice = activeProducts.filter(
      (p) => p.product_price != null && !isNaN(parseFloat(p.product_price))
    );
    const avgPrice =
      activeWithPrice.length > 0
        ? activeWithPrice.reduce((sum, p) => sum + parseFloat(p.product_price), 0) /
          activeWithPrice.length
        : null;

    // Neueste 5 Products (bereits nach $createdAt desc sortiert)
    const newestProducts = products.slice(0, 5);

    return {
      totalProducts,
      activeProducts: activeProducts.length,
      endedProducts: endedProducts.length,
      avgPrice: avgPrice ? Math.round(avgPrice * 100) / 100 : null,
      newestProducts,
    };
  } catch (e) {
    console.error("Fehler beim Laden der Overview KPIs:", e);
    throw e;
  }
}

/**
 * Lädt eine paginierte Seite von Products für einen aktiven Account
 * @param {string} activeAccountId - ID des aktiven Accounts
 * @param {Object} options - Pagination und Filter-Optionen
 * @param {number} options.page - Seitennummer (1-basiert)
 * @param {number} options.pageSize - Anzahl Items pro Seite
 * @param {Object} [options.filters] - Filter-Optionen
 * @param {string} [options.filters.status] - Status-Filter ("active", "ended", etc.)
 * @param {string} [options.filters.search] - Suchbegriff für Titel (client-side)
 * @returns {Promise<{ items: Array, total: number, page: number, pageSize: number }>}
 */
export async function getProductsPage(activeAccountId, options = {}) {
  if (!activeAccountId) {
    return {
      items: [],
      total: 0,
      page: 1,
      pageSize: options.pageSize || 25,
    };
  }

  const { page = 1, pageSize = 25, filters = {} } = options;
  const offset = (page - 1) * pageSize;

  try {
    // Lade Products mit Pagination
    // Für MVP: Lade mehr als nötig (z.B. pageSize * 3) um client-side Filter zu unterstützen
    const fetchLimit = Math.max(pageSize * 3, 100); // Mindestens 100, aber mehr wenn pageSize größer
    let products = await listProductsByAccount(activeAccountId, {
      limit: fetchLimit,
      offset: 0,
      orderBy: "$createdAt",
      orderType: "desc",
    });

    // Client-side Filter anwenden (falls Appwrite Query-Filter nicht unterstützt)
    if (filters.status && filters.status !== "all") {
      products = products.filter(
        (p) =>
          p.product_status?.toLowerCase() === filters.status.toLowerCase()
      );
    }

    if (filters.search && filters.search.trim()) {
      const searchLower = filters.search.trim().toLowerCase();
      products = products.filter((p) =>
        p.product_title?.toLowerCase().includes(searchLower)
      );
    }

    const total = products.length;

    // Pagination auf gefilterten Ergebnissen anwenden
    const startIndex = offset;
    const endIndex = startIndex + pageSize;
    const items = products.slice(startIndex, endIndex);

    return {
      items,
      total,
      page,
      pageSize,
    };
  } catch (e) {
    console.error("Fehler beim Laden der Products Page:", e);
    throw e;
  }
}

/**
 * Lädt ein Product mit optionalen Details aus product_details Collection
 * @param {string} productId - ID des Products
 * @returns {Promise<Object>} Product-Objekt mit optionalen Details
 */
export async function getProductPreview(productId) {
  if (!productId) {
    throw new Error("productId ist erforderlich");
  }

  try {
    // Lade Product
    const product = await getProductById(productId);
    if (!product) {
      return null;
    }

    // Versuche product_details zu laden (optional, falls vorhanden)
    let details = null;
    try {
      const detailsResponse = await databases.listDocuments(
        databaseId,
        productDetailsCollectionId,
        [Query.equal("product_detail_product_id", productId), Query.limit(1)]
      );

      if (detailsResponse.documents && detailsResponse.documents.length > 0) {
        details = detailsResponse.documents[0];
      }
    } catch (detailsError) {
      // product_details Collection existiert möglicherweise nicht oder hat keine Permissions
      // Das ist OK, Details sind optional
      console.debug("product_details konnten nicht geladen werden:", detailsError);
    }

    // Kombiniere Product mit Details
    return {
      ...product,
      details,
    };
  } catch (e) {
    console.error("Fehler beim Laden des Product Previews:", e);
    throw e;
  }
}

/**
 * Lädt Insights für einen aktiven Account (regelbasiert, MVP)
 * @param {string} activeAccountId - ID des aktiven Accounts
 * @returns {Promise<{ trending: Array, priceSpread: Array, categoryShare: Array }>}
 */
export async function getInsights(activeAccountId) {
  if (!activeAccountId) {
    return {
      trending: [],
      priceSpread: [],
      categoryShare: [],
    };
  }

  try {
    // Lade bis zu 500 Products für Insights-Berechnung
    const products = await listProductsByAccount(activeAccountId, {
      limit: 500,
      offset: 0,
      orderBy: "$createdAt",
      orderType: "desc",
    });

    // 1. Trending: Neueste 20 Products als "recent"
    const trending = products.slice(0, 20).map((p) => ({
      product: p,
      label: p.product_title || p.$id,
      value: p.product_price ? `EUR ${p.product_price}` : "N/A",
    }));

    // 2. Price Spread: Gruppiere nach normalisiertem Titel (lowercase, remove digits)
    // Berechne max-min Spread pro Gruppe, Top 5
    const titleGroups = new Map();

    products.forEach((p) => {
      if (!p.product_title || !p.product_price) return;

      // Normalisiere Titel: lowercase, entferne Zahlen
      const normalizedTitle = p.product_title
        .toLowerCase()
        .replace(/\d+/g, "")
        .trim();

      if (!normalizedTitle) return;

      const price = parseFloat(p.product_price);
      if (isNaN(price)) return;

      if (!titleGroups.has(normalizedTitle)) {
        titleGroups.set(normalizedTitle, {
          title: normalizedTitle,
          prices: [],
          originalTitles: new Set(),
        });
      }

      const group = titleGroups.get(normalizedTitle);
      group.prices.push(price);
      group.originalTitles.add(p.product_title);
    });

    // Berechne Spread für jede Gruppe
    const spreads = Array.from(titleGroups.values())
      .map((group) => {
        if (group.prices.length < 2) return null; // Mindestens 2 Preise für Spread

        const minPrice = Math.min(...group.prices);
        const maxPrice = Math.max(...group.prices);
        const spread = maxPrice - minPrice;

        return {
          title: Array.from(group.originalTitles)[0], // Erstes Original-Titel als Label
          minPrice,
          maxPrice,
          spread,
          count: group.prices.length,
          label: `${Array.from(group.originalTitles)[0]} (${group.prices.length}x)`,
          value: `EUR ${minPrice.toFixed(2)} - ${maxPrice.toFixed(2)} (Spread: ${spread.toFixed(2)})`,
        };
      })
      .filter((s) => s !== null)
      .sort((a, b) => b.spread - a.spread) // Sortiere nach Spread (höchster zuerst)
      .slice(0, 5); // Top 5

    // 3. Category Share: Zähle nach product_category, Top 5
    const categoryCounts = new Map();

    products.forEach((p) => {
      const category = p.product_category || "Uncategorized";
      categoryCounts.set(category, (categoryCounts.get(category) || 0) + 1);
    });

    const categoryShare = Array.from(categoryCounts.entries())
      .map(([category, count]) => ({
        category,
        count,
        label: category,
        value: `${count} items`,
      }))
      .sort((a, b) => b.count - a.count) // Sortiere nach Count (höchster zuerst)
      .slice(0, 5); // Top 5

    return {
      trending,
      priceSpread: spreads,
      categoryShare,
    };
  } catch (e) {
    console.error("Fehler beim Laden der Insights:", e);
    throw e;
  }
}