BEGIN;

--? RECORDINGS (tabel induk recording harian)
CREATE TABLE IF NOT EXISTS recordings (
    id                   BIGSERIAL PRIMARY KEY,
    project_flock_id     BIGINT NOT NULL,                         
    record_datetime      TIMESTAMPTZ NOT NULL,
    record_date          DATE, 
    status               INT NOT NULL DEFAULT 0,                  --? 0=draft,1=submitted,2=approved,3=rejected
    ontime               INT NOT NULL DEFAULT 0,                  --? 1=ontime,0=late (pakai INT/BOOLEAN sesuai preferensi)
    day                  INT,
    total_depletion      INT,
    cum_depletion_rate   NUMERIC(7,3),
    daily_gain           NUMERIC(7,3),
    avg_daily_gain       NUMERIC(7,3),
    cum_intake           INT,
    fcr_value            NUMERIC(7,3),
    total_chick          BIGINT,
    daily_depletion_rate NUMERIC(7,3),
    cum_depletion        INT,
    created_at           TIMESTAMPTZ DEFAULT NOW(),
    updated_at           TIMESTAMPTZ DEFAULT NOW(),
    deleted_at           TIMESTAMPTZ,
    created_by           BIGINT,

    CONSTRAINT fk_recordings_project_flock
        FOREIGN KEY (project_flock_id) REFERENCES project_flock_kandangs(id),

    CONSTRAINT fk_recordings_created_by
        FOREIGN KEY (created_by) REFERENCES users(id),

    
    CONSTRAINT chk_recordings_status
        CHECK (status IN (0,1,2,3)),

    CONSTRAINT chk_recordings_ontime
        CHECK (ontime IN (0,1)),

    CONSTRAINT chk_recordings_day
        CHECK (day IS NULL OR day >= 1),

    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)
        )
);

--? Set record_date otomatis berdasarkan record_datetime (pakai zona Asia/Jakarta)
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;

DROP TRIGGER IF EXISTS recordings_set_record_date_trg ON recordings;
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 IF NOT EXISTS idx_recordings_flock_datetime
    ON recordings (project_flock_id, record_datetime);

--? Unique harian (1 recording per hari dan per flock)
CREATE UNIQUE INDEX IF NOT EXISTS uq_recordings_flock_record_date
    ON recordings (project_flock_id, record_date)
    WHERE deleted_at IS NULL;


--? RECORDING_BWS (BW per recording)
CREATE TABLE IF NOT EXISTS recording_bws (
    id            BIGSERIAL PRIMARY KEY,
    recording_id  BIGINT NOT NULL,        
    weight        NUMERIC(8,2) NOT NULL,  --? bobot per ekor/kelompok
    qty           INT NOT NULL DEFAULT 1, --? jumlah ekor pada bobot ini
    notes         VARCHAR,
    created_at    TIMESTAMPTZ DEFAULT NOW(),
    updated_at    TIMESTAMPTZ DEFAULT NOW(),

    CONSTRAINT fk_recording_bws_recording
        FOREIGN KEY (recording_id) REFERENCES recordings(id) ON DELETE CASCADE,

    CONSTRAINT chk_recording_bws_nonneg
        CHECK (weight >= 0 AND qty >= 1)
);

CREATE INDEX IF NOT EXISTS idx_recording_bws_recording
    ON recording_bws (recording_id);

--? RECORDING_DEPLETIONS 
CREATE TABLE IF NOT EXISTS recording_depletions (
    id                    BIGSERIAL PRIMARY KEY,
    recording_id          BIGINT NOT NULL,     
    product_warehouse_id  BIGINT NOT NULL,     
    total                 BIGINT NOT NULL,
    notes                 VARCHAR,

    CONSTRAINT fk_recording_depl_recording
        FOREIGN KEY (recording_id) REFERENCES recordings(id) ON DELETE CASCADE,

    CONSTRAINT fk_recording_depl_prodwh
        FOREIGN KEY (product_warehouse_id) REFERENCES product_warehouses(id),

    CONSTRAINT chk_recording_depl_total
        CHECK (total >= 0)
);

CREATE INDEX IF NOT EXISTS idx_recording_depl_recording
    ON recording_depletions (recording_id);

--? RECORDING_STOCKS 
CREATE TABLE IF NOT EXISTS recording_stocks (
    id                   BIGSERIAL PRIMARY KEY,
    recording_id         BIGINT NOT NULL,       
    product_warehouse_id BIGINT NOT NULL,       
    increase             NUMERIC(10,3),         --? penambahan (boleh NULL)
    decrease             NUMERIC(10,3),         --? pengurangan (boleh NULL)
    usage_amount         BIGINT,                --? pemakaian (opsional, jika konsep dipisah dari decrease)
    notes                VARCHAR,

    CONSTRAINT fk_recording_stocks_recording
        FOREIGN KEY (recording_id) REFERENCES recordings(id) ON DELETE CASCADE,

    CONSTRAINT fk_recording_stocks_prodwh
        FOREIGN KEY (product_warehouse_id) REFERENCES product_warehouses(id),

    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)
        )
);

CREATE INDEX IF NOT EXISTS idx_recording_stocks_recording
    ON recording_stocks (recording_id);

CREATE INDEX IF NOT EXISTS idx_recording_stocks_product
    ON recording_stocks (product_warehouse_id);

COMMIT;
