-- +goose Up
DELIMITER // 
DROP PROCEDURE IF EXISTS get_full_product
//
CREATE PROCEDURE get_full_product(
  IN p_id_product INT UNSIGNED,
  IN p_id_shop INT UNSIGNED,
  IN p_id_lang INT UNSIGNED,
  IN p_id_customer INT UNSIGNED,
  IN b2b_id_country INT UNSIGNED,
  IN p_quantity INT UNSIGNED
) 
BEGIN 
DECLARE v_tax_rate DECIMAL(10, 4) DEFAULT 0;
DECLARE p_id_currency DECIMAL(10, 4) DEFAULT 0;
SELECT
  COALESCE(t.rate, 0.0000) INTO v_tax_rate
FROM
  ps_tax_rule tr
  INNER JOIN ps_tax t ON t.id_tax = tr.id_tax
  LEFT JOIN b2b_countries ON b2b_countries.id = b2b_id_country
WHERE
  tr.id_tax_rules_group = (
    SELECT
      ps.id_tax_rules_group
    FROM
      ps_product_shop ps
    WHERE
      ps.id_product = p_id_product
      AND ps.id_shop = p_id_shop
    LIMIT
      1
  )
  AND tr.id_country = b2b_countries.ps_id_country
ORDER BY
  tr.id_state DESC,
  tr.zipcode_from != '' DESC,
  tr.id_tax_rule DESC
LIMIT
  1;
  
SELECT
  b2b_currencies.ps_id_currency INTO p_id_currency
FROM
  b2b_currencies
 LEFT JOIN b2b_countries ON b2b_countries.b2b_id_currency = b2b_currencies.id
WHERE
    b2b_countries.id = b2b_id_country
LIMIT 1;
 
/* FINAL JSON */
SELECT
  JSON_OBJECT(
    /* ================= PRODUCT ================= */
    'id_product',
    p.id_product,
    'reference',
    p.reference,
    'name',
    pl.name,
    'description',
    pl.description,
    'short_description',
    pl.description_short,    
    /* ================= PRICE ================= */
'price',
JSON_OBJECT(
  'base',
  COALESCE(ps.price * r.conversion_rate, p.price * r.conversion_rate),

  'final_tax_excl',
  (
    CASE
      WHEN bsp.id IS NOT NULL THEN
        CASE
          /* FIXED PRICE */
          WHEN bsp.reduction_type = 'amount' THEN
            (
              CASE
                WHEN bsp.b2b_id_currency IS NULL THEN bsp.price
                ELSE bsp.price * br_bsp.conversion_rate
              END
            )

          /* PERCENTAGE */
          WHEN bsp.reduction_type = 'percentage' THEN
            COALESCE(ps.price * r.conversion_rate, p.price * r.conversion_rate)
            * (1 - bsp.percentage_reduction / 100)

          ELSE
            COALESCE(ps.price * r.conversion_rate, p.price * r.conversion_rate)
        END

      ELSE
        COALESCE(ps.price * r.conversion_rate, p.price * r.conversion_rate)
    END
  ),

  'final_tax_incl',
  (
    (
      CASE
        WHEN bsp.id IS NOT NULL THEN
          CASE
            WHEN bsp.reduction_type = 'amount' THEN
              (
                CASE
                  WHEN bsp.b2b_id_currency IS NULL THEN bsp.price
                  ELSE bsp.price * br_bsp.conversion_rate
                END
              )

            WHEN bsp.reduction_type = 'percentage' THEN
              COALESCE(ps.price * r.conversion_rate, p.price * r.conversion_rate)
              * (1 - bsp.percentage_reduction / 100)

            ELSE
              COALESCE(ps.price * r.conversion_rate, p.price * r.conversion_rate)
          END
        ELSE
          COALESCE(ps.price * r.conversion_rate, p.price * r.conversion_rate)
      END
    ) * (1 + v_tax_rate / 100)
  )
),
    /* ================= META ================= */
    'active',
    COALESCE(ps.active, p.active),
    'visibility',
    COALESCE(ps.visibility, p.visibility),
    'manufacturer',
    m.name,
    'category',
    cl.name,
    /* ================= IMAGE ================= */
    'cover_image',
    JSON_OBJECT(
      'id',
      i.id_image,
      'legend',
      il.legend
    ),
    /* ================= FEATURES ================= */
    'features',
    (
      SELECT
        JSON_ARRAYAGG(
          JSON_OBJECT(
            'name',
            fl.name,
            'value',
            fvl.value
          )
        )
      FROM
        ps_feature_product fp
        JOIN ps_feature_lang fl ON fl.id_feature = fp.id_feature
        AND fl.id_lang = p_id_lang
        JOIN ps_feature_value_lang fvl ON fvl.id_feature_value = fp.id_feature_value
        AND fvl.id_lang = p_id_lang
      WHERE
        fp.id_product = p.id_product
    ),
    /* ================= COMBINATIONS ================= */
    'combinations',
    (
      SELECT
        JSON_ARRAYAGG(
          JSON_OBJECT(
            'id_product_attribute',
            pa.id_product_attribute,
            'reference',
            pa.reference,
            'price',
            JSON_OBJECT(
              'impact',
              COALESCE(pas.price, pa.price),
              'final_tax_excl',
              (
                COALESCE(ps.price, p.price) + COALESCE(pas.price, pa.price)
              ),
              'final_tax_incl',
              (
                (
                  COALESCE(ps.price, p.price) + COALESCE(pas.price, pa.price)
                ) * (1 + v_tax_rate / 100)
              )
            ),
            'stock',
            IFNULL(sa.quantity, 0),
            'default_on',
            pas.default_on,
            /* ATTRIBUTES JSON */
            'attributes',
            (
              SELECT
                JSON_ARRAYAGG(
                  JSON_OBJECT(
                    'group',
                    agl.name,
                    'attribute',
                    al.name
                  )
                )
              FROM
                ps_product_attribute_combination pac
                JOIN ps_attribute a ON a.id_attribute = pac.id_attribute
                JOIN ps_attribute_lang al ON al.id_attribute = a.id_attribute
                AND al.id_lang = p_id_lang
                JOIN ps_attribute_group_lang agl ON agl.id_attribute_group = a.id_attribute_group
                AND agl.id_lang = p_id_lang
              WHERE
                pac.id_product_attribute = pa.id_product_attribute
            ),
            /* IMAGES */
            'images',
            (
              SELECT
                JSON_ARRAYAGG(img.id_image)
              FROM
                ps_product_attribute_image pai
                JOIN ps_image img ON img.id_image = pai.id_image
              WHERE
                pai.id_product_attribute = pa.id_product_attribute
            )
          )
        )
      FROM
        ps_product_attribute pa
        JOIN ps_product_attribute_shop pas ON pas.id_product_attribute = pa.id_product_attribute
        AND pas.id_shop = p_id_shop
        LEFT JOIN ps_stock_available sa ON sa.id_product = pa.id_product
        AND sa.id_product_attribute = pa.id_product_attribute
        AND sa.id_shop = p_id_shop
      WHERE
        pa.id_product = p.id_product
    )
  ) AS product_json
FROM
  ps_product p
  LEFT JOIN ps_product_shop ps ON ps.id_product = p.id_product
  AND ps.id_shop = p_id_shop
  LEFT JOIN ps_product_lang pl ON pl.id_product = p.id_product
  AND pl.id_lang = p_id_lang
  AND pl.id_shop = p_id_shop
  LEFT JOIN ps_category_lang cl ON cl.id_category = COALESCE(ps.id_category_default, p.id_category_default)
  AND cl.id_lang = p_id_lang
  AND cl.id_shop = p_id_shop
  LEFT JOIN ps_manufacturer m ON m.id_manufacturer = p.id_manufacturer
  LEFT JOIN ps_image i ON i.id_product = p.id_product
  AND i.cover = 1
  LEFT JOIN ps_image_lang il ON il.id_image = i.id_image
  AND il.id_lang = p_id_lang
  /* SPECIFIC PRICE */
LEFT JOIN (
  SELECT bsp.*
  FROM b2b_specific_price bsp

  /* RELATIONS */
  LEFT JOIN b2b_specific_price_product bsp_p 
    ON bsp_p.b2b_specific_price_id = bsp.id

  LEFT JOIN b2b_specific_price_category bsp_c 
    ON bsp_c.b2b_specific_price_id = bsp.id

  WHERE bsp.is_active = TRUE

    /* SCOPE MATCH */
    AND (
      /* PRODUCT */
      (bsp.scope = 'product' AND bsp_p.id_product = p_id_product)

      /* CATEGORY */
      OR (
        bsp.scope = 'category'
        AND bsp_c.id_category IN (
          SELECT cp.id_category
          FROM ps_category_product cp
          WHERE cp.id_product = p_id_product
        )
      )

      /* SHOP (GLOBAL) */
      OR (bsp.scope = 'shop')
    )

   /* CUSTOMER MATCH */
AND (
  NOT EXISTS (
    SELECT 1 FROM b2b_specific_price_customer c
    WHERE c.b2b_specific_price_id = bsp.id
  )
  OR EXISTS (
    SELECT 1 FROM b2b_specific_price_customer c
    WHERE c.b2b_specific_price_id = bsp.id
      AND c.b2b_id_customer = p_id_customer
  )
)

/* COUNTRY MATCH */
AND (
  NOT EXISTS (
    SELECT 1 FROM b2b_specific_price_country ctry
    WHERE ctry.b2b_specific_price_id = bsp.id
  )
  OR EXISTS (
    SELECT 1 FROM b2b_specific_price_country ctry
    WHERE ctry.b2b_specific_price_id = bsp.id
      AND ctry.b2b_id_country = b2b_id_country
  )
)

    /* QUANTITY */
    AND bsp.from_quantity <= p_quantity

    /* DATE */
    AND (
      bsp.has_expiration_date = FALSE OR (
        (bsp.valid_from IS NULL OR bsp.valid_from <= NOW())
        AND (bsp.valid_till IS NULL OR bsp.valid_till >= NOW())
      )
    )

    ORDER BY
    /* 🔥 SCOPE PRIORITY */
    bsp.scope = 'product' DESC,
    bsp.scope = 'category' DESC,
    bsp.scope = 'shop' DESC,

    /* 🔥 CUSTOMER PRIORITY */
    (
      EXISTS (
        SELECT 1 FROM b2b_specific_price_customer c
        WHERE c.b2b_specific_price_id = bsp.id
          AND c.b2b_id_customer = p_id_customer
      )
    ) DESC,

    /* 🔥 COUNTRY PRIORITY */
    (
      EXISTS (
        SELECT 1 FROM b2b_specific_price_country ctry
        WHERE ctry.b2b_specific_price_id = bsp.id
          AND ctry.b2b_id_country = b2b_id_country
      )
    ) DESC,

    /* GLOBAL fallback (no restrictions) naturally goes last */

    bsp.from_quantity DESC,
    bsp.id DESC

    LIMIT 1
) bsp ON 1=1
LEFT JOIN b2b_currency_rates br_bsp
  ON br_bsp.b2b_id_currency = bsp.b2b_id_currency
  AND br_bsp.created_at = (
    SELECT MAX(created_at)
    FROM b2b_currency_rates
    WHERE b2b_id_currency = bsp.b2b_id_currency
  )
  LEFT JOIN b2b_countries ON b2b_countries.id = b2b_id_country
  LEFT JOIN b2b_currencies ON b2b_currencies.id = p_id_currency
  LEFT JOIN b2b_currency_rates r ON r.b2b_id_currency = b2b_currencies.id
  AND r.created_at = (
    SELECT
      MAX(created_at)
    FROM
      b2b_currency_rates
    WHERE
      b2b_id_currency = b2b_currencies.id
  )
WHERE
  p.id_product = p_id_product
LIMIT
  1;
END //

DELIMITER ;


-----------------------------------


DELIMITER //

DROP PROCEDURE IF EXISTS get_product_attributes_with_price //
CREATE PROCEDURE get_product_attributes_with_price(
  IN p_id_lang INT UNSIGNED,
  IN p_id_product INT UNSIGNED,
  IN p_id_shop INT UNSIGNED,
  IN p_id_customer INT UNSIGNED,
  IN p_id_country INT UNSIGNED,
  IN p_quantity INT UNSIGNED
)
BEGIN

  DECLARE v_tax_rate DECIMAL(10,4) DEFAULT 0;
  DECLARE v_currency_rate DECIMAL(10,4) DEFAULT 1;

  -- =========================================================
  -- TAX
  -- =========================================================
  SELECT COALESCE(t.rate, 0)
  INTO v_tax_rate
  FROM ps_tax_rule tr
  INNER JOIN ps_tax t ON t.id_tax = tr.id_tax
  LEFT JOIN b2b_countries c ON c.id = p_id_country
  WHERE tr.id_tax_rules_group = (
    SELECT ps.id_tax_rules_group
    FROM ps_product_shop ps
    WHERE ps.id_product = p_id_product
      AND ps.id_shop = p_id_shop
    LIMIT 1
  )
  AND tr.id_country = c.ps_id_country
  LIMIT 1;

  -- =========================================================
  -- CURRENCY
  -- =========================================================
  SELECT COALESCE(r.conversion_rate, 1)
  INTO v_currency_rate
  FROM b2b_countries c
  LEFT JOIN b2b_currencies cur ON cur.id = c.b2b_id_currency
  LEFT JOIN b2b_currency_rates r ON r.b2b_id_currency = cur.id
  WHERE c.id = p_id_country
  ORDER BY r.created_at DESC
  LIMIT 1;

  -- =========================================================
  -- MAIN RESULT
  -- =========================================================
  SELECT
    pa.id_product_attribute,
    pa.reference,

    -- =====================================================
    -- BASE PRICE (product + attribute impact)
    -- =====================================================
    (
      (COALESCE(ps.price, p.price) + COALESCE(pas.price, 0))
      * v_currency_rate
    ) AS base_price,

    -- =====================================================
    -- FINAL PRICE EXCL (FULL RULE ENGINE)
    -- =====================================================
    COALESCE(sp.price_tax_excl,
      (COALESCE(ps.price, p.price) + COALESCE(pas.price, 0)) * v_currency_rate
    ) AS price_tax_excl,

    -- =====================================================
    -- FINAL PRICE INCL
    -- =====================================================
    (
      COALESCE(sp.price_tax_excl,
        (COALESCE(ps.price, p.price) + COALESCE(pas.price, 0)) * v_currency_rate
      )
    ) * (1 + v_tax_rate / 100) AS price_tax_incl,

    -- =====================================================
    -- STOCK
    -- =====================================================
    IFNULL(sa.quantity, 0) AS quantity,

    -- =====================================================
    -- ATTRIBUTES
    -- =====================================================
    (
      SELECT JSON_ARRAYAGG(
        JSON_OBJECT(
          'group', agl.name,
          'attribute', al.name
        )
      )
      FROM ps_product_attribute_combination pac
      JOIN ps_attribute a ON a.id_attribute = pac.id_attribute
      JOIN ps_attribute_lang al
        ON al.id_attribute = a.id_attribute AND al.id_lang = p_id_lang
      JOIN ps_attribute_group_lang agl
        ON agl.id_attribute_group = a.id_attribute_group AND agl.id_lang = p_id_lang
      WHERE pac.id_product_attribute = pa.id_product_attribute
    ) AS attributes

  FROM ps_product_attribute pa

  JOIN ps_product_attribute_shop pas
    ON pas.id_product_attribute = pa.id_product_attribute
    AND pas.id_shop = p_id_shop

  JOIN ps_product p
    ON p.id_product = pa.id_product

  LEFT JOIN ps_product_shop ps
    ON ps.id_product = p.id_product
    AND ps.id_shop = p_id_shop

  LEFT JOIN ps_stock_available sa
    ON sa.id_product = pa.id_product
    AND sa.id_product_attribute = pa.id_product_attribute
    AND sa.id_shop = p_id_shop

  -- =====================================================
  -- FULL SPECIFIC PRICE ENGINE (IDENTICAL RULES TO MAIN)
  -- =====================================================
LEFT JOIN (

  SELECT *
  FROM (

    SELECT
      pa.id_product_attribute,

      -- FINAL PRICE
      CASE
        WHEN bsp.reduction_type = 'amount' THEN
          CASE
            WHEN bsp.b2b_id_currency IS NULL THEN bsp.price
            ELSE bsp.price
          END

        WHEN bsp.reduction_type = 'percentage' THEN
          (
            (COALESCE(ps.price, p.price) + COALESCE(pas.price, 0))
            * v_currency_rate
          ) * (1 - bsp.percentage_reduction / 100)

        ELSE
          (
            (COALESCE(ps.price, p.price) + COALESCE(pas.price, 0))
            * v_currency_rate
          )
      END AS price_tax_excl,

      ROW_NUMBER() OVER (
        PARTITION BY pa.id_product_attribute
        ORDER BY
          bsp.scope = 'product' DESC,
          bsp.scope = 'category' DESC,
          bsp.scope = 'shop' DESC,
          bsp.from_quantity DESC,
          bsp.id DESC
      ) AS rn

    FROM ps_product_attribute pa

    JOIN ps_product p ON p.id_product = pa.id_product

    LEFT JOIN ps_product_shop ps
      ON ps.id_product = p.id_product
      AND ps.id_shop = p_id_shop

    LEFT JOIN ps_product_attribute_shop pas
      ON pas.id_product_attribute = pa.id_product_attribute

    JOIN b2b_specific_price bsp ON bsp.is_active = TRUE

    LEFT JOIN b2b_specific_price_product bsp_p
      ON bsp_p.b2b_specific_price_id = bsp.id

    LEFT JOIN b2b_specific_price_category bsp_c
      ON bsp_c.b2b_specific_price_id = bsp.id

    WHERE pa.id_product = p_id_product

    -- =========================
    -- SCOPE
    -- =========================
    AND (
      (bsp.scope = 'product' AND bsp_p.id_product = p_id_product)

      OR (
        bsp.scope = 'category'
        AND bsp_c.id_category IN (
          SELECT id_category
          FROM ps_category_product
          WHERE id_product = p_id_product
        )
      )

      OR (bsp.scope = 'shop')
    )

    -- =========================
    -- CUSTOMER
    -- =========================
    AND (
      NOT EXISTS (
        SELECT 1 FROM b2b_specific_price_customer c
        WHERE c.b2b_specific_price_id = bsp.id
      )
      OR EXISTS (
        SELECT 1 FROM b2b_specific_price_customer c
        WHERE c.b2b_specific_price_id = bsp.id
          AND c.b2b_id_customer = p_id_customer
      )
    )

    -- =========================
    -- COUNTRY
    -- =========================
    AND (
      NOT EXISTS (
        SELECT 1 FROM b2b_specific_price_country c
        WHERE c.b2b_specific_price_id = bsp.id
      )
      OR EXISTS (
        SELECT 1 FROM b2b_specific_price_country c
        WHERE c.b2b_specific_price_id = bsp.id
          AND c.b2b_id_country = p_id_country
      )
    )

    -- =========================
    -- ATTRIBUTE
    -- =========================
    AND (
      NOT EXISTS (
        SELECT 1 FROM b2b_specific_price_product_attribute a
        WHERE a.b2b_specific_price_id = bsp.id
      )
      OR EXISTS (
        SELECT 1 FROM b2b_specific_price_product_attribute a
        WHERE a.b2b_specific_price_id = bsp.id
          AND a.id_product_attribute = pa.id_product_attribute
      )
    )

    -- =========================
    -- QUANTITY
    -- =========================
    AND bsp.from_quantity <= p_quantity

    -- =========================
    -- DATE
    -- =========================
    AND (
      bsp.has_expiration_date = FALSE
      OR (
        (bsp.valid_from IS NULL OR bsp.valid_from <= NOW())
        AND (bsp.valid_till IS NULL OR bsp.valid_till >= NOW())
      )
    )

  ) ranked

  WHERE ranked.rn = 1

) sp ON sp.id_product_attribute = pa.id_product_attribute

  WHERE pa.id_product = p_id_product;

END //

DELIMITER ;

--------------------------------


DELIMITER //

DROP PROCEDURE IF EXISTS get_product_price //
CREATE PROCEDURE get_product_price(
  IN p_id_product INT UNSIGNED,
  IN p_id_shop INT UNSIGNED,
  IN p_id_customer INT UNSIGNED,
  IN p_id_country INT UNSIGNED,
  IN p_quantity INT UNSIGNED
)
BEGIN

  DECLARE v_tax_rate DECIMAL(10,4) DEFAULT 0;
  DECLARE v_currency_rate DECIMAL(10,4) DEFAULT 1;

  DECLARE v_base_price DECIMAL(20,6) DEFAULT 0;
  DECLARE v_final_excl DECIMAL(20,6) DEFAULT 0;
  DECLARE v_final_incl DECIMAL(20,6) DEFAULT 0;

  DECLARE v_has_specific INT DEFAULT 0;
  DECLARE v_reduction_type VARCHAR(20);
  DECLARE v_percentage DECIMAL(10,4);
  DECLARE v_fixed_price DECIMAL(20,6);
  DECLARE v_specific_currency_id INT;

  -- =========================
  -- 1. TAX RATE
  -- =========================
  SELECT COALESCE(t.rate, 0)
  INTO v_tax_rate
  FROM ps_tax_rule tr
  INNER JOIN ps_tax t ON t.id_tax = tr.id_tax
  LEFT JOIN b2b_countries c ON c.id = p_id_country
  WHERE tr.id_tax_rules_group = (
    SELECT ps.id_tax_rules_group
    FROM ps_product_shop ps
    WHERE ps.id_product = p_id_product
      AND ps.id_shop = p_id_shop
    LIMIT 1
  )
  AND tr.id_country = c.ps_id_country
  ORDER BY tr.id_state DESC, tr.zipcode_from DESC, tr.id_tax_rule DESC
  LIMIT 1;

  -- =========================
  -- 2. CURRENCY RATE
  -- =========================
  SELECT COALESCE(r.conversion_rate, 1)
  INTO v_currency_rate
  FROM b2b_countries c
  LEFT JOIN b2b_currencies cur ON cur.id = c.b2b_id_currency
  LEFT JOIN b2b_currency_rates r ON r.b2b_id_currency = cur.id
  WHERE c.id = p_id_country
  ORDER BY r.created_at DESC
  LIMIT 1;

  -- =========================
  -- 3. BASE PRICE
  -- =========================
  SELECT COALESCE(ps.price, p.price) * v_currency_rate
  INTO v_base_price
  FROM ps_product p
  LEFT JOIN ps_product_shop ps
    ON ps.id_product = p.id_product
    AND ps.id_shop = p_id_shop
  WHERE p.id_product = p_id_product
  LIMIT 1;

-- =========================
-- 4. SPECIFIC PRICE (correct wildcard-aware match)
-- =========================
SELECT
  1,
  bsp.reduction_type,
  bsp.percentage_reduction,
  bsp.price,
  bsp.b2b_id_currency
INTO
  v_has_specific,
  v_reduction_type,
  v_percentage,
  v_fixed_price,
  v_specific_currency_id
FROM b2b_specific_price bsp

LEFT JOIN b2b_specific_price_product bsp_p
  ON bsp_p.b2b_specific_price_id = bsp.id

LEFT JOIN b2b_specific_price_category bsp_c
  ON bsp_c.b2b_specific_price_id = bsp.id

LEFT JOIN b2b_specific_price_customer bsp_u
  ON bsp_u.b2b_specific_price_id = bsp.id

LEFT JOIN b2b_specific_price_country bsp_ct
  ON bsp_ct.b2b_specific_price_id = bsp.id

LEFT JOIN b2b_specific_price_product_attribute bsp_pa
  ON bsp_pa.b2b_specific_price_id = bsp.id

WHERE bsp.is_active = TRUE

-- =========================
-- PRODUCT / CATEGORY / SHOP SCOPE
-- =========================
AND (
  (bsp.scope = 'product' AND bsp_p.id_product = p_id_product)

  OR (
    bsp.scope = 'category'
    AND bsp_c.id_category IN (
      SELECT id_category
      FROM ps_category_product
      WHERE id_product = p_id_product
    )
  )

  OR (bsp.scope = 'shop')
)

-- =========================
-- CUSTOMER RULE (wildcard-aware)
-- =========================
AND (
  NOT EXISTS (
    SELECT 1
    FROM b2b_specific_price_customer c
    WHERE c.b2b_specific_price_id = bsp.id
  )
  OR EXISTS (
    SELECT 1
    FROM b2b_specific_price_customer c
    WHERE c.b2b_specific_price_id = bsp.id
      AND c.b2b_id_customer = p_id_customer
  )
)

-- =========================
-- COUNTRY RULE (wildcard-aware)
-- =========================
AND (
  NOT EXISTS (
    SELECT 1
    FROM b2b_specific_price_country c
    WHERE c.b2b_specific_price_id = bsp.id
  )
  OR EXISTS (
    SELECT 1
    FROM b2b_specific_price_country c
    WHERE c.b2b_specific_price_id = bsp.id
      AND c.b2b_id_country = p_id_country
  )
)

-- =========================
-- PRODUCT ATTRIBUTE RULE (wildcard-aware)
-- =========================
AND (
  NOT EXISTS (
    SELECT 1
    FROM b2b_specific_price_product_attribute a
    WHERE a.b2b_specific_price_id = bsp.id
  )
  OR EXISTS (
    SELECT 1
    FROM b2b_specific_price_product_attribute a
    WHERE a.b2b_specific_price_id = bsp.id
      AND a.id_product_attribute = 0
  )
)

-- =========================
-- QUANTITY RULE
-- =========================
AND bsp.from_quantity <= p_quantity

-- =========================
-- DATE RULE (FIXED precedence bug)
-- =========================
AND (
  bsp.has_expiration_date = FALSE
  OR (
    (bsp.valid_from IS NULL OR bsp.valid_from <= NOW())
    AND (bsp.valid_till IS NULL OR bsp.valid_till >= NOW())
  )
)

-- =========================
-- PRIORITY ORDERING (IMPROVED)
-- =========================
ORDER BY
  -- strongest match wins
  (EXISTS (
    SELECT 1 FROM b2b_specific_price_customer c
    WHERE c.b2b_specific_price_id = bsp.id
  )) DESC,

  (EXISTS (
    SELECT 1 FROM b2b_specific_price_country c
    WHERE c.b2b_specific_price_id = bsp.id
  )) DESC,

  bsp.scope = 'product' DESC,
  bsp.scope = 'category' DESC,
  bsp.scope = 'shop' DESC,

  bsp.from_quantity DESC,
  bsp.id DESC

LIMIT 1;

  -- =========================
  -- 5. APPLY SPECIFIC PRICE
  -- =========================
  SET v_final_excl = v_base_price;

  IF v_has_specific = 1 THEN

    IF v_reduction_type = 'amount' THEN

      IF v_specific_currency_id IS NULL THEN
        SET v_final_excl = v_fixed_price;
      ELSE
        SET v_final_excl = v_fixed_price; -- assume already converted or pre-handled
      END IF;

    ELSEIF v_reduction_type = 'percentage' THEN
      SET v_final_excl = v_base_price * (1 - v_percentage / 100);
    END IF;

  END IF;

  -- =========================
  -- 6. TAX
  -- =========================
  SET v_final_incl = v_final_excl * (1 + v_tax_rate / 100);

  -- =========================
  -- 7. RETURN RESULT
  -- =========================
  SELECT
    p_id_product AS id_product,
    v_base_price AS price_base,
    v_final_excl AS price_tax_excl,
    v_final_incl AS price_tax_incl,
    v_tax_rate AS tax_rate;

END //

DELIMITER ;


-- +goose Down
