-- +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 ;
-- +goose Down
