BEGIN;

ALTER TABLE laying_transfers
    ADD COLUMN IF NOT EXISTS source_project_flock_kandang_id BIGINT,
    ADD COLUMN IF NOT EXISTS source_product_warehouse_id BIGINT,
    ADD COLUMN IF NOT EXISTS source_requested_qty NUMERIC(15,3) NOT NULL DEFAULT 0,
    ADD COLUMN IF NOT EXISTS source_usage_qty NUMERIC(15,3) NOT NULL DEFAULT 0,
    ADD COLUMN IF NOT EXISTS source_pending_usage_qty NUMERIC(15,3) NOT NULL DEFAULT 0;

DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'project_flock_kandangs')
        AND NOT EXISTS (
            SELECT 1 FROM pg_constraint WHERE conname = 'fk_laying_transfers_source_project_flock_kandang_id'
        ) THEN
        ALTER TABLE laying_transfers
            ADD CONSTRAINT fk_laying_transfers_source_project_flock_kandang_id
            FOREIGN KEY (source_project_flock_kandang_id)
            REFERENCES project_flock_kandangs(id)
            ON DELETE RESTRICT
            ON UPDATE CASCADE;
    END IF;

    IF EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'product_warehouses')
        AND NOT EXISTS (
            SELECT 1 FROM pg_constraint WHERE conname = 'fk_laying_transfers_source_product_warehouse_id'
        ) THEN
        ALTER TABLE laying_transfers
            ADD CONSTRAINT fk_laying_transfers_source_product_warehouse_id
            FOREIGN KEY (source_product_warehouse_id)
            REFERENCES product_warehouses(id)
            ON DELETE SET NULL
            ON UPDATE CASCADE;
    END IF;
END $$;

CREATE INDEX IF NOT EXISTS idx_laying_transfers_source_project_flock_kandang_id
    ON laying_transfers(source_project_flock_kandang_id);

CREATE INDEX IF NOT EXISTS idx_laying_transfers_source_product_warehouse_id
    ON laying_transfers(source_product_warehouse_id);

WITH single_source AS (
    SELECT
        lts.laying_transfer_id,
        MIN(lts.source_project_flock_kandang_id) AS source_project_flock_kandang_id,
        MIN(lts.product_warehouse_id) AS source_product_warehouse_id
    FROM laying_transfer_sources lts
    WHERE lts.deleted_at IS NULL
    GROUP BY lts.laying_transfer_id
    HAVING COUNT(*) = 1
)
UPDATE laying_transfers lt
SET
    source_project_flock_kandang_id = ss.source_project_flock_kandang_id,
    source_product_warehouse_id = ss.source_product_warehouse_id
FROM single_source ss
WHERE lt.id = ss.laying_transfer_id
  AND (lt.source_project_flock_kandang_id IS NULL OR lt.source_project_flock_kandang_id = 0);

WITH source_totals AS (
    SELECT
        laying_transfer_id,
        COALESCE(SUM(requested_qty), 0) AS requested_qty,
        COALESCE(SUM(usage_qty), 0) AS usage_qty,
        COALESCE(SUM(pending_usage_qty), 0) AS pending_qty
    FROM laying_transfer_sources
    WHERE deleted_at IS NULL
    GROUP BY laying_transfer_id
)
UPDATE laying_transfers lt
SET
    source_requested_qty = CASE
        WHEN lt.source_requested_qty = 0 THEN st.requested_qty
        ELSE lt.source_requested_qty
    END,
    source_usage_qty = CASE
        WHEN lt.source_usage_qty = 0 THEN st.usage_qty
        ELSE lt.source_usage_qty
    END,
    source_pending_usage_qty = CASE
        WHEN lt.source_pending_usage_qty = 0 THEN st.pending_qty
        ELSE lt.source_pending_usage_qty
    END
FROM source_totals st
WHERE lt.id = st.laying_transfer_id;

WITH target_totals AS (
    SELECT
        laying_transfer_id,
        COALESCE(SUM(total_qty), 0) AS total_qty
    FROM laying_transfer_targets
    WHERE deleted_at IS NULL
    GROUP BY laying_transfer_id
)
UPDATE laying_transfers lt
SET source_requested_qty = tt.total_qty
FROM target_totals tt
WHERE lt.id = tt.laying_transfer_id
  AND (lt.source_requested_qty IS NULL OR lt.source_requested_qty = 0);

INSERT INTO fifo_stock_v2_traits(
    source_table,
    lane,
    date_table,
    date_join_left_col,
    date_join_right_col,
    date_column,
    fallback_date_column,
    sort_priority,
    id_column
)
VALUES
    ('laying_transfers', 'USABLE', NULL, NULL, NULL, 'transfer_date', NULL, 25, 'id')
ON CONFLICT (source_table, lane) DO UPDATE
SET
    date_table = EXCLUDED.date_table,
    date_join_left_col = EXCLUDED.date_join_left_col,
    date_join_right_col = EXCLUDED.date_join_right_col,
    date_column = EXCLUDED.date_column,
    fallback_date_column = EXCLUDED.fallback_date_column,
    sort_priority = EXCLUDED.sort_priority,
    id_column = EXCLUDED.id_column,
    is_active = TRUE;

UPDATE fifo_stock_v2_traits
SET is_active = FALSE
WHERE source_table = 'laying_transfer_sources'
  AND lane = 'USABLE';

INSERT INTO fifo_stock_v2_route_rules(
    flag_group_code,
    lane,
    function_code,
    source_table,
    source_id_column,
    product_warehouse_col,
    quantity_col,
    used_quantity_col,
    pending_quantity_col,
    scope_sql,
    legacy_type_key,
    allow_pending_default,
    is_active
)
VALUES
    ('AYAM', 'USABLE', 'TRANSFER_TO_LAYING_OUT', 'laying_transfers', 'id', 'source_product_warehouse_id', 'source_usage_qty', NULL, 'source_pending_usage_qty', 'deleted_at IS NULL', 'TRANSFERTOLAYING_OUT', TRUE, TRUE)
ON CONFLICT (flag_group_code, lane, function_code, source_table) DO UPDATE
SET
    source_id_column = EXCLUDED.source_id_column,
    product_warehouse_col = EXCLUDED.product_warehouse_col,
    quantity_col = EXCLUDED.quantity_col,
    used_quantity_col = EXCLUDED.used_quantity_col,
    pending_quantity_col = EXCLUDED.pending_quantity_col,
    scope_sql = EXCLUDED.scope_sql,
    legacy_type_key = EXCLUDED.legacy_type_key,
    allow_pending_default = EXCLUDED.allow_pending_default,
    is_active = TRUE,
    updated_at = NOW();

UPDATE fifo_stock_v2_route_rules
SET
    is_active = FALSE,
    updated_at = NOW()
WHERE flag_group_code = 'AYAM'
  AND lane = 'USABLE'
  AND function_code = 'TRANSFER_TO_LAYING_OUT'
  AND source_table = 'laying_transfer_sources';

COMMIT;
