#pragma once
#include "../db/pool.hpp"

static const char* CATEGORY_COUNT_SQL =
    "WITH CategoryTree AS ("
    "  SELECT kKategorie FROM dbo.tKategorie WHERE kKategorie = ?"
    "  UNION ALL"
    "  SELECT t.kKategorie FROM dbo.tKategorie t"
    "  INNER JOIN CategoryTree ct ON t.kOberKategorie = ct.kKategorie"
    ") SELECT COUNT(*) AS cnt FROM dbo.tKategorie k "
    "WHERE k.kKategorie IN (SELECT kKategorie FROM CategoryTree) "
    "AND (? = 0 OR EXISTS (SELECT 1 FROM dbo.tKategorieShop ks "
    "WHERE ks.kKategorie = k.kKategorie AND ks.kShop = ?)) "
    "AND CONVERT(BIGINT, k.bRowversion) > ?";

static const char* PRODUCT_COUNT_SQL =
    "WITH CategoryTree AS ("
    "  SELECT kKategorie FROM dbo.tKategorie WHERE kKategorie = ?"
    "  UNION ALL"
    "  SELECT t.kKategorie FROM dbo.tKategorie t"
    "  INNER JOIN CategoryTree ct ON t.kOberKategorie = ct.kKategorie"
    ") SELECT COUNT(DISTINCT a.kArtikel) AS cnt FROM dbo.tArtikel a "
    "INNER JOIN dbo.tKategorieArtikel ka ON ka.kArtikel = a.kArtikel "
    "WHERE a.cAktiv = 'Y' "
    "AND ka.kKategorie IN (SELECT kKategorie FROM CategoryTree) "
    "AND (? = 0 OR EXISTS (SELECT 1 FROM dbo.tKategorieShop ks "
    "WHERE ks.kKategorie = ka.kKategorie AND ks.kShop = ?)) "
    "AND (CONVERT(BIGINT, a.bRowversion) > ? "
    "OR EXISTS (SELECT 1 FROM dbo.tArtikelbildPlattform abp "
    "WHERE abp.kArtikel = a.kArtikel AND abp.kShop = ? "
    "AND CONVERT(BIGINT, abp.bRowversion) > ?))";

static const char* COMPOSITE_PRODUCT_COUNT_SQL =
    "SELECT COUNT(DISTINCT a.kArtikel) AS cnt FROM dbo.tArtikel a "
    "INNER JOIN dbo.tStueckliste s ON s.kStueckliste = a.kStueckliste "
    "WHERE a.kStueckliste <> 0 "
    "AND (? = 0 OR EXISTS (SELECT 1 FROM dbo.tKategorieArtikel ka "
    "INNER JOIN dbo.tKategorieShop ks ON ks.kKategorie = ka.kKategorie "
    "AND ks.kShop = ? WHERE ka.kArtikel = a.kArtikel)) "
    "AND CONVERT(BIGINT, a.bRowversion) > ?";

static const char* DELETED_ENTITY_COUNT_SQL =
    "SELECT COUNT(*) AS cnt FROM Pos.vDeletedEntity "
    "WHERE CONVERT(BIGINT, vDeletedEntity.bLastChanged) > ?";

static const char* MAX_ORDER_ID_SQL =
    "SELECT ISNULL(MAX(kPosAuftrag), 0) AS cnt FROM Pos.tAuftragMapping "
    "WHERE kShopSubShop = ?";

inline int64_t get_category_count(int64_t root_cat, int k_shop, int64_t cursor) {
    return get_pool().execute_scalar(CATEGORY_COUNT_SQL,
        {{ParamType::BigInt,"",root_cat},{ParamType::Int,"",k_shop},
         {ParamType::Int,"",k_shop},{ParamType::BigInt,"",cursor}});
}
inline int64_t get_product_count(int64_t root_cat, int k_shop, int64_t cursor) {
    return get_pool().execute_scalar(PRODUCT_COUNT_SQL,
        {{ParamType::BigInt,"",root_cat},{ParamType::Int,"",k_shop},
         {ParamType::Int,"",k_shop},{ParamType::BigInt,"",cursor},
         {ParamType::Int,"",k_shop},{ParamType::BigInt,"",cursor}});
}
inline int64_t get_composite_count(int k_shop, int64_t cursor) {
    return get_pool().execute_scalar(COMPOSITE_PRODUCT_COUNT_SQL,
        {{ParamType::Int,"",k_shop},{ParamType::Int,"",k_shop},
         {ParamType::BigInt,"",cursor}});
}
inline int64_t get_deleted_count(int64_t cursor) {
    return get_pool().execute_scalar(DELETED_ENTITY_COUNT_SQL,
        {{ParamType::BigInt,"",cursor}});
}
inline int64_t get_max_order_id_count(int k_shop_subshop) {
    if (k_shop_subshop <= 0) return 0;
    return get_pool().execute_scalar(MAX_ORDER_ID_SQL,
        {{ParamType::Int,"",k_shop_subshop}});
}
