/**
 * Accounts Service
 * CRUD-Operationen für Accounts aus Appwrite
 * Verwaltet nur "Managed Accounts" (account_owner_user_id == authUserId)
 */

import { databases, databaseId, accountsCollectionId } from "../lib/appwrite";
import { ID, Query } from "appwrite";

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

  try {
    const document = await databases.getDocument(
      databaseId,
      accountsCollectionId,
      accountId
    );
    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 Accounts:", e);
    throw e;
  }
}

/**
 * Leitet den Market-Code aus einem Account ab
 * @param {Object} account - Account-Dokument
 * @returns {string} Market-Code (z.B. "DE", "US", "UNKNOWN")
 */
export function deriveMarketFromAccount(account) {
  if (!account) {
    return "UNKNOWN";
  }

  // Priority 1: account_platform_market Feld vorhanden
  if (account.account_platform_market && account.account_platform_market.trim()) {
    return account.account_platform_market.trim().toUpperCase();
  }

  // Priority 2: Ableitung aus account_url Hostname
  if (account.account_url) {
    try {
      const url = new URL(account.account_url);
      const hostname = url.hostname.toLowerCase();

      // Mapping von Hostname zu Market-Code
      const hostnameToMarket = {
        "ebay.de": "DE",
        "www.ebay.de": "DE",
        "ebay.com": "US",
        "www.ebay.com": "US",
        "ebay.co.uk": "UK",
        "www.ebay.co.uk": "UK",
        "ebay.fr": "FR",
        "www.ebay.fr": "FR",
        "ebay.it": "IT",
        "www.ebay.it": "IT",
        "ebay.es": "ES",
        "www.ebay.es": "ES",
        "ebay.ca": "CA",
        "www.ebay.ca": "CA",
        "ebay.com.au": "AU",
        "www.ebay.com.au": "AU",
      };

      if (hostnameToMarket[hostname]) {
        return hostnameToMarket[hostname];
      }

      // Fallback: Prüfe ob hostname ein bekanntes Pattern enthält
      if (hostname.includes("ebay.de")) return "DE";
      if (hostname.includes("ebay.com") && !hostname.includes("ebay.com.au")) return "US";
      if (hostname.includes("ebay.co.uk")) return "UK";
      if (hostname.includes("ebay.fr")) return "FR";
      if (hostname.includes("ebay.it")) return "IT";
      if (hostname.includes("ebay.es")) return "ES";
      if (hostname.includes("ebay.ca")) return "CA";
      if (hostname.includes("ebay.com.au")) return "AU";
    } catch (e) {
      // URL parsing fehlgeschlagen
      console.debug("Fehler beim Parsen der Account-URL:", e);
    }
  }

  return "UNKNOWN";
}

/**
 * Leitet die Währung aus einem Market-Code ab
 * @param {string} market - Market-Code (z.B. "DE", "US", "UK")
 * @returns {string} Währungscode (z.B. "EUR", "USD", "GBP")
 */
export function deriveCurrencyFromMarket(market) {
  if (!market || market === "UNKNOWN") {
    return "EUR"; // Fallback
  }

  const marketUpper = market.toUpperCase();

  // Mapping Market -> Currency
  const marketToCurrency = {
    // EUR Länder
    "DE": "EUR",
    "FR": "EUR",
    "IT": "EUR",
    "ES": "EUR",
    "NL": "EUR",
    "AT": "EUR",
    "BE": "EUR",
    "IE": "EUR",
    // Andere Währungen
    "US": "USD",
    "UK": "GBP",
    "CA": "CAD",
    "AU": "AUD",
  };

  return marketToCurrency[marketUpper] || "EUR"; // Fallback zu EUR
}

/**
 * Lädt alle Managed Accounts für einen User
 * @param {string} authUserId - ID des eingeloggten Users
 * @returns {Promise<Array>} Array von Account-Dokumenten
 */
export async function fetchManagedAccounts(authUserId) {
  if (!authUserId) {
    console.warn("fetchManagedAccounts: authUserId fehlt");
    return [];
  }

  try {
    const response = await databases.listDocuments(
      databaseId,
      accountsCollectionId,
      [
        Query.equal("account_owner_user_id", authUserId),
        Query.orderDesc("$createdAt"),
      ]
    );

    return response.documents;
  } catch (e) {
    console.error("Fehler beim Laden der Accounts:", e);
    
    // Wenn Collection nicht existiert oder Berechtigungen fehlen
    if (e.code === 404 || e.code === 401) {
      return [];
    }
    
    throw e;
  }
}

/**
 * Erstellt ein neues Managed Account
 * @param {string} authUserId - ID des eingeloggten Users
 * @param {Object} accountData - Account-Daten
 * @param {string} accountData.account_platform_market - Required: Market (z.B. "DE", "US")
 * @param {string} accountData.account_platform_account_id - Required: Platform Account ID
 * @param {string} [accountData.account_shop_name] - Optional: Shop-Name
 * @param {string} [accountData.account_url] - Optional: Account URL
 * @param {string} [accountData.account_status] - Optional: Status (z.B. "active", "unknown", "disabled")
 * @returns {Promise<Object>} Erstelltes Account-Dokument
 */
export async function createManagedAccount(authUserId, accountData) {
  if (!authUserId) {
    throw new Error("authUserId ist erforderlich");
  }

  // Validierung der Required-Felder
  const { account_platform_market, account_platform_account_id } = accountData;

  // account_platform wird IMMER "ebay" gesetzt (eBay-only Tool)
  if (!account_platform_market) {
    throw new Error("account_platform_market ist erforderlich");
  }
  if (!account_platform_account_id) {
    throw new Error("account_platform_account_id ist erforderlich");
  }

  // Payload zusammenstellen
  const payload = {
    account_owner_user_id: authUserId,
    account_platform: "ebay", // IMMER "ebay" für über UI erstellte Accounts
    account_platform_market,
    account_platform_account_id,
    account_shop_name: accountData.account_shop_name || null,
    account_url: accountData.account_url || null,
    account_sells: accountData.account_sells ?? null, // Setze account_sells wenn verfügbar
  };

  // account_status ist optional - aufgrund Schema-Konflikt vorerst weglassen
  // TODO: Schema in Appwrite prüfen und korrigieren (Enum-Feld sollte String akzeptieren, nicht Array)
  // Das Feld wird erst wieder hinzugefügt, wenn das Schema korrekt konfiguriert ist

  // Document-Level Permissions für den User setzen
  const permissions = [
    `read("user:${authUserId}")`,
    `update("user:${authUserId}")`,
    `delete("user:${authUserId}")`,
  ];

  try {
    const document = await databases.createDocument(
      databaseId,
      accountsCollectionId,
      ID.unique(),
      payload,
      permissions
    );

    return document;
  } catch (e) {
    // Duplicate-Conflict behandeln (falls Unique-Index auf platform+market+platform_account_id existiert)
    if (e.code === 409 || e.message?.includes("duplicate") || e.message?.includes("unique")) {
      throw new Error(
        "Dieser Account ist bereits verbunden."
      );
    }
    
    console.error("Fehler beim Erstellen des Accounts:", e);
    throw e;
  }
}

/**
 * Aktualisiert ein Managed Account (optional für v1)
 * @param {string} accountId - ID des Accounts
 * @param {Object} accountData - Zu aktualisierende Account-Daten
 * @returns {Promise<Object>} Aktualisiertes Account-Dokument
 */
export async function updateManagedAccount(accountId, accountData) {
  if (!accountId) {
    throw new Error("accountId ist erforderlich");
  }

  try {
    // Entferne undefined/null Werte aus accountData (behalte nur geänderte Felder)
    const payload = {};
    Object.keys(accountData).forEach((key) => {
      if (accountData[key] !== undefined && accountData[key] !== null) {
        payload[key] = accountData[key];
      }
    });

    const document = await databases.updateDocument(
      databaseId,
      accountsCollectionId,
      accountId,
      payload
    );

    return document;
  } catch (e) {
    console.error("Fehler beim Aktualisieren des Accounts:", e);
    throw e;
  }
}

/**
 * Aktualisiert das account_last_scan_at Feld eines Accounts
 * @param {string} accountId - ID des Accounts
 * @param {string} isoString - ISO 8601 Datum-String (z.B. "2026-01-18T12:34:56.000Z")
 * @returns {Promise<Object>} Aktualisiertes Account-Dokument
 */
export async function updateAccountLastScanAt(accountId, isoString) {
  if (!accountId) {
    throw new Error("accountId ist erforderlich");
  }
  if (!isoString) {
    throw new Error("isoString ist erforderlich");
  }

  try {
    const document = await databases.updateDocument(
      databaseId,
      accountsCollectionId,
      accountId,
      {
        account_last_scan_at: isoString,
      }
    );

    return document;
  } catch (e) {
    console.error("Fehler beim Aktualisieren des account_last_scan_at:", e);
    throw e;
  }
}

/**
 * Löscht ein Managed Account (optional für v1)
 * @param {string} accountId - ID des Accounts
 * @returns {Promise<void>}
 */
export async function deleteManagedAccount(accountId) {
  if (!accountId) {
    throw new Error("accountId ist erforderlich");
  }

  try {
    await databases.deleteDocument(
      databaseId,
      accountsCollectionId,
      accountId
    );
  } catch (e) {
    console.error("Fehler beim Löschen des Accounts:", e);
    throw e;
  }
}
