BEGIN;

-- Drop newly introduced egg tables
DROP TABLE IF EXISTS grading_eggs;
DROP TABLE IF EXISTS recording_eggs;

-- Revert recording_stocks structure
ALTER TABLE recording_stocks
    DROP CONSTRAINT IF EXISTS chk_recording_stocks_nonneg;

ALTER TABLE recording_stocks
    DROP COLUMN IF EXISTS usage_qty,
    DROP COLUMN IF EXISTS pending_qty;

ALTER TABLE recording_stocks
    ADD COLUMN increase NUMERIC(10,3),
    ADD COLUMN decrease NUMERIC(10,3),
    ADD COLUMN usage_amount BIGINT,
    ADD COLUMN notes VARCHAR;

ALTER TABLE recording_stocks
    ADD CONSTRAINT chk_recording_stocks_nonneg CHECK (
        (increase IS NULL OR increase >= 0) AND
        (decrease IS NULL OR decrease >= 0) AND
        (usage_amount IS NULL OR usage_amount >= 0)
    );

-- Revert recording_depletions structure
ALTER TABLE recording_depletions
    DROP CONSTRAINT IF EXISTS chk_recording_depl_qty;

ALTER TABLE recording_depletions
    ALTER COLUMN qty TYPE BIGINT USING COALESCE(qty, 0)::BIGINT;

ALTER TABLE recording_depletions
    RENAME COLUMN qty TO total;

ALTER TABLE recording_depletions
    ADD COLUMN notes VARCHAR;

ALTER TABLE recording_depletions
    ADD CONSTRAINT chk_recording_depl_total CHECK (total >= 0);

-- Revert recording_bws structure
ALTER TABLE recording_bws
    DROP CONSTRAINT IF EXISTS chk_recording_bws_nonneg;

ALTER TABLE recording_bws
    ALTER COLUMN qty TYPE INT USING COALESCE(qty, 0)::INT;

ALTER TABLE recording_bws
    DROP COLUMN IF EXISTS total_weight;

ALTER TABLE recording_bws
    ALTER COLUMN avg_weight TYPE NUMERIC(8,2) USING COALESCE(avg_weight, 0)::NUMERIC(8,2);

ALTER TABLE recording_bws
    RENAME COLUMN avg_weight TO weight;

ALTER TABLE recording_bws
    ADD COLUMN notes VARCHAR;

UPDATE recording_bws
SET qty = GREATEST(qty, 1);

ALTER TABLE recording_bws
    ADD CONSTRAINT chk_recording_bws_nonneg CHECK (weight >= 0 AND qty >= 1);

-- Revert recordings header
DROP INDEX IF EXISTS idx_recordings_flock_datetime;

ALTER TABLE recordings
    DROP CONSTRAINT IF EXISTS fk_recordings_project_flock_kandang,
    DROP CONSTRAINT IF EXISTS chk_recordings_nonnegatives_v2;

ALTER TABLE recordings
    ALTER COLUMN total_depletion_qty TYPE INT USING COALESCE(total_depletion_qty, 0)::INT,
    ALTER COLUMN total_chick_qty TYPE BIGINT USING COALESCE(total_chick_qty, 0)::BIGINT;

ALTER TABLE recordings
    RENAME COLUMN total_depletion_qty TO total_depletion;

ALTER TABLE recordings
    RENAME COLUMN total_chick_qty TO total_chick;

ALTER TABLE recordings
    ADD COLUMN record_date DATE,
    ADD COLUMN status INT NOT NULL DEFAULT 0,
    ADD COLUMN ontime INT NOT NULL DEFAULT 0,
    ADD COLUMN daily_depletion_rate NUMERIC(7,3),
    ADD COLUMN cum_depletion INT;

ALTER TABLE recordings
    RENAME COLUMN project_flock_kandangs_id TO project_flock_id;

ALTER TABLE recordings
    ADD CONSTRAINT fk_recordings_project_flock
        FOREIGN KEY (project_flock_id) REFERENCES project_flock_kandangs(id);

ALTER TABLE recordings
    ADD CONSTRAINT chk_recordings_status CHECK (status IN (0,1,2,3));

ALTER TABLE recordings
    ADD CONSTRAINT chk_recordings_ontime CHECK (ontime IN (0,1));

ALTER TABLE recordings
    ADD CONSTRAINT chk_recordings_nonnegatives CHECK (
        (total_depletion IS NULL OR total_depletion >= 0) AND
        (cum_depletion  IS NULL OR cum_depletion  >= 0) AND
        (total_chick    IS NULL OR total_chick    >= 0) AND
        (cum_intake     IS NULL OR cum_intake     >= 0) AND
        (daily_gain     IS NULL OR daily_gain     >= 0) AND
        (avg_daily_gain IS NULL OR avg_daily_gain >= 0) AND
        (fcr_value      IS NULL OR fcr_value      >  0) AND
        (daily_depletion_rate IS NULL OR daily_depletion_rate >= 0) AND
        (cum_depletion_rate  IS NULL OR cum_depletion_rate  >= 0)
    );

-- Ensure new columns carry derived data
UPDATE recordings
SET record_date = (record_datetime AT TIME ZONE 'Asia/Jakarta')::date
WHERE record_date IS NULL;

-- Restore helper trigger/function and indexes
CREATE OR REPLACE FUNCTION trg_set_record_date() RETURNS trigger AS $$
BEGIN
  NEW.record_date := (NEW.record_datetime AT TIME ZONE 'Asia/Jakarta')::date;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER recordings_set_record_date_trg
BEFORE INSERT OR UPDATE OF record_datetime ON recordings
FOR EACH ROW EXECUTE FUNCTION trg_set_record_date();

CREATE INDEX idx_recordings_flock_datetime
    ON recordings (project_flock_id, record_datetime);

CREATE UNIQUE INDEX uq_recordings_flock_record_date
    ON recordings (project_flock_id, record_date)
    WHERE deleted_at IS NULL;

COMMIT;
