BEGIN;

ALTER TABLE adjustment_stocks
    ADD COLUMN IF NOT EXISTS paired_adjustment_id BIGINT NULL;

DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint WHERE conname = 'fk_adjustment_stocks_paired_adjustment_id'
    ) THEN
        ALTER TABLE adjustment_stocks
            ADD CONSTRAINT fk_adjustment_stocks_paired_adjustment_id
            FOREIGN KEY (paired_adjustment_id)
            REFERENCES adjustment_stocks(id)
            ON DELETE SET NULL
            ON UPDATE CASCADE;
    END IF;
END $$;

ALTER TABLE adjustment_stocks
    DROP CONSTRAINT IF EXISTS chk_adjustment_stocks_paired_not_self;

ALTER TABLE adjustment_stocks
    ADD CONSTRAINT chk_adjustment_stocks_paired_not_self
    CHECK (paired_adjustment_id IS NULL OR paired_adjustment_id <> id);

CREATE INDEX IF NOT EXISTS idx_adjustment_stocks_paired_adjustment_id
    ON adjustment_stocks(paired_adjustment_id);

-- Backfill pairing untuk depletion-out <-> depletion-in existing records.
WITH candidates AS (
    SELECT
        src.id AS src_id,
        dst.id AS dst_id,
        ABS(EXTRACT(EPOCH FROM (dst.created_at - src.created_at))) AS ts_diff,
        ABS(dst.id - src.id) AS id_diff,
        ROW_NUMBER() OVER (
            PARTITION BY src.id
            ORDER BY ABS(EXTRACT(EPOCH FROM (dst.created_at - src.created_at))) ASC,
                     ABS(dst.id - src.id) ASC,
                     dst.id ASC
        ) AS rn_src,
        ROW_NUMBER() OVER (
            PARTITION BY dst.id
            ORDER BY ABS(EXTRACT(EPOCH FROM (dst.created_at - src.created_at))) ASC,
                     ABS(dst.id - src.id) ASC,
                     src.id ASC
        ) AS rn_dst
    FROM adjustment_stocks src
    JOIN adjustment_stocks dst
      ON dst.id <> src.id
     AND dst.transaction_type = src.transaction_type
     AND dst.function_code = 'RECORDING_DEPLETION_IN'
     AND src.function_code = 'RECORDING_DEPLETION_OUT'
     AND dst.paired_adjustment_id IS NULL
     AND src.paired_adjustment_id IS NULL
     AND ABS((COALESCE(src.usage_qty, 0) + COALESCE(src.pending_qty, 0)) - COALESCE(dst.total_qty, 0)) < 0.0001
     AND COALESCE(src.price, 0) = COALESCE(dst.price, 0)
     AND COALESCE(src.grand_total, 0) = COALESCE(dst.grand_total, 0)
     AND ABS(EXTRACT(EPOCH FROM (dst.created_at - src.created_at))) <= 120
),
chosen AS (
    SELECT src_id, dst_id
    FROM candidates
    WHERE rn_src = 1
      AND rn_dst = 1
)
UPDATE adjustment_stocks src
SET paired_adjustment_id = c.dst_id
FROM chosen c
WHERE src.id = c.src_id
  AND src.paired_adjustment_id IS NULL;

WITH chosen AS (
    SELECT a.id AS src_id, a.paired_adjustment_id AS dst_id
    FROM adjustment_stocks a
    WHERE a.function_code = 'RECORDING_DEPLETION_OUT'
      AND a.paired_adjustment_id IS NOT NULL
)
UPDATE adjustment_stocks dst
SET paired_adjustment_id = c.src_id
FROM chosen c
WHERE dst.id = c.dst_id
  AND dst.paired_adjustment_id IS NULL;

COMMIT;
