-- Global vendor partnumber mapping foundation with backward compatibility.

ALTER TABLE lot_partnumbers
    ADD COLUMN IF NOT EXISTS vendor VARCHAR(255) NOT NULL DEFAULT '' AFTER partnumber;

CREATE TABLE IF NOT EXISTS qt_lot_bundles (
    bundle_lot_name VARCHAR(255) NOT NULL,
    is_active TINYINT(1) NOT NULL DEFAULT 1,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (bundle_lot_name)
);

CREATE TABLE IF NOT EXISTS qt_lot_bundle_items (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    bundle_lot_name VARCHAR(255) NOT NULL,
    lot_name VARCHAR(255) NOT NULL,
    qty DECIMAL(14,6) NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uq_qt_lot_bundle_items_bundle_lot (bundle_lot_name, lot_name),
    INDEX idx_qt_lot_bundle_items_lot_name (lot_name)
);

CREATE TABLE IF NOT EXISTS qt_vendor_partnumber_seen (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    source_type VARCHAR(32) NOT NULL,
    vendor VARCHAR(255) NOT NULL DEFAULT '',
    partnumber VARCHAR(255) NOT NULL,
    description VARCHAR(10000) NULL,
    last_seen_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    is_ignored TINYINT(1) NOT NULL DEFAULT 0,
    ignored_at DATETIME NULL,
    ignored_by VARCHAR(100) NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uq_qt_vendor_partnumber_seen_source_key (source_type, vendor, partnumber),
    INDEX idx_qt_vendor_partnumber_seen_vendor_partnumber (vendor, partnumber),
    INDEX idx_qt_vendor_partnumber_seen_ignored (is_ignored)
);

CREATE TABLE IF NOT EXISTS qt_bom (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    external_bom_id VARCHAR(255) NOT NULL,
    source_system VARCHAR(100) NOT NULL,
    payload JSON NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uq_qt_bom_source_external (source_system, external_bom_id)
);

ALTER TABLE qt_configurations
    ADD COLUMN IF NOT EXISTS bom_id BIGINT UNSIGNED NULL AFTER competitor_pricelist_id;

-- Convert legacy many-to-one rows into bundle lots so (vendor,partnumber) can be unique.
CREATE TEMPORARY TABLE tmp_lp_dups AS
SELECT
    vendor,
    partnumber,
    CONCAT('BND_', UPPER(SUBSTRING(MD5(CONCAT(vendor, '|', partnumber)), 1, 20))) AS bundle_lot_name,
    MAX(description) AS description
FROM lot_partnumbers
GROUP BY vendor, partnumber
HAVING COUNT(*) > 1;

INSERT INTO lot (lot_name, lot_description, lot_category)
SELECT
    d.bundle_lot_name,
    CONCAT('Auto-generated bundle for ', d.partnumber, IF(d.vendor = '', '', CONCAT(' (', d.vendor, ')'))),
    'BUNDLE'
FROM tmp_lp_dups d
LEFT JOIN lot l ON l.lot_name = d.bundle_lot_name
WHERE l.lot_name IS NULL;

INSERT INTO qt_lot_bundles (bundle_lot_name, is_active)
SELECT d.bundle_lot_name, 1
FROM tmp_lp_dups d
LEFT JOIN qt_lot_bundles b ON b.bundle_lot_name = d.bundle_lot_name
WHERE b.bundle_lot_name IS NULL;

INSERT INTO qt_lot_bundle_items (bundle_lot_name, lot_name, qty)
SELECT
    d.bundle_lot_name,
    lp.lot_name,
    1
FROM tmp_lp_dups d
INNER JOIN lot_partnumbers lp
    ON lp.vendor = d.vendor AND lp.partnumber = d.partnumber
WHERE TRIM(lp.lot_name) <> ''
ON DUPLICATE KEY UPDATE qty = VALUES(qty), updated_at = CURRENT_TIMESTAMP;

DELETE lp
FROM lot_partnumbers lp
INNER JOIN tmp_lp_dups d
    ON lp.vendor = d.vendor AND lp.partnumber = d.partnumber;

INSERT INTO lot_partnumbers (vendor, partnumber, lot_name, description)
SELECT vendor, partnumber, bundle_lot_name, description
FROM tmp_lp_dups;

DROP TEMPORARY TABLE IF EXISTS tmp_lp_dups;

CREATE UNIQUE INDEX uq_lot_partnumbers_vendor_partnumber ON lot_partnumbers (vendor, partnumber);
CREATE INDEX idx_lot_partnumbers_vendor_partnumber ON lot_partnumbers (vendor, partnumber);

-- Add optional FKs if not present.
SET @fk_cfg_bom_exists := (
    SELECT COUNT(*)
    FROM information_schema.REFERENTIAL_CONSTRAINTS
    WHERE CONSTRAINT_SCHEMA = DATABASE()
      AND CONSTRAINT_NAME = 'fk_qt_configurations_bom'
);
SET @fk_cfg_bom_sql := IF(
    @fk_cfg_bom_exists > 0,
    'SELECT 1',
    'ALTER TABLE qt_configurations ADD CONSTRAINT fk_qt_configurations_bom FOREIGN KEY (bom_id) REFERENCES qt_bom(id) ON DELETE SET NULL'
);
PREPARE stmt_cfg_bom FROM @fk_cfg_bom_sql;
EXECUTE stmt_cfg_bom;
DEALLOCATE PREPARE stmt_cfg_bom;

SET @fk_bundle_exists := (
    SELECT COUNT(*)
    FROM information_schema.REFERENTIAL_CONSTRAINTS
    WHERE CONSTRAINT_SCHEMA = DATABASE()
      AND CONSTRAINT_NAME = 'fk_qt_lot_bundles_lot'
);
SET @fk_bundle_sql := IF(
    @fk_bundle_exists > 0,
    'SELECT 1',
    'ALTER TABLE qt_lot_bundles ADD CONSTRAINT fk_qt_lot_bundles_lot FOREIGN KEY (bundle_lot_name) REFERENCES lot(lot_name) ON DELETE CASCADE'
);
PREPARE stmt_bundle FROM @fk_bundle_sql;
EXECUTE stmt_bundle;
DEALLOCATE PREPARE stmt_bundle;

SET @fk_bundle_item_bundle_exists := (
    SELECT COUNT(*)
    FROM information_schema.REFERENTIAL_CONSTRAINTS
    WHERE CONSTRAINT_SCHEMA = DATABASE()
      AND CONSTRAINT_NAME = 'fk_qt_lot_bundle_items_bundle'
);
SET @fk_bundle_item_bundle_sql := IF(
    @fk_bundle_item_bundle_exists > 0,
    'SELECT 1',
    'ALTER TABLE qt_lot_bundle_items ADD CONSTRAINT fk_qt_lot_bundle_items_bundle FOREIGN KEY (bundle_lot_name) REFERENCES qt_lot_bundles(bundle_lot_name) ON DELETE CASCADE'
);
PREPARE stmt_bundle_item_bundle FROM @fk_bundle_item_bundle_sql;
EXECUTE stmt_bundle_item_bundle;
DEALLOCATE PREPARE stmt_bundle_item_bundle;

SET @fk_bundle_item_lot_exists := (
    SELECT COUNT(*)
    FROM information_schema.REFERENTIAL_CONSTRAINTS
    WHERE CONSTRAINT_SCHEMA = DATABASE()
      AND CONSTRAINT_NAME = 'fk_qt_lot_bundle_items_lot'
);
SET @fk_bundle_item_lot_sql := IF(
    @fk_bundle_item_lot_exists > 0,
    'SELECT 1',
    'ALTER TABLE qt_lot_bundle_items ADD CONSTRAINT fk_qt_lot_bundle_items_lot FOREIGN KEY (lot_name) REFERENCES lot(lot_name) ON DELETE RESTRICT'
);
PREPARE stmt_bundle_item_lot FROM @fk_bundle_item_lot_sql;
EXECUTE stmt_bundle_item_lot;
DEALLOCATE PREPARE stmt_bundle_item_lot;
