-- Experiment-level phase config tables
-- One row per experiment per phase; linked by experiment_id. Used when creating an experiment
-- so soaking, airdrying, cracking, and shelling parameters are stored and can be applied to repetitions.

-- =============================================
-- 1. EXPERIMENT_SOAKING (template for soaking phase)
-- =============================================

CREATE TABLE IF NOT EXISTS public.experiment_soaking (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    experiment_id UUID NOT NULL REFERENCES public.experiments(id) ON DELETE CASCADE,
    soaking_duration_hr DOUBLE PRECISION NOT NULL CHECK (soaking_duration_hr >= 0),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    created_by UUID NOT NULL REFERENCES public.user_profiles(id),
    CONSTRAINT unique_experiment_soaking_per_experiment UNIQUE (experiment_id)
);

CREATE INDEX IF NOT EXISTS idx_experiment_soaking_experiment_id ON public.experiment_soaking(experiment_id);
GRANT ALL ON public.experiment_soaking TO authenticated;
ALTER TABLE public.experiment_soaking ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Experiment soaking config is viewable by authenticated" ON public.experiment_soaking FOR SELECT USING (auth.role() = 'authenticated');
CREATE POLICY "Experiment soaking config is insertable by authenticated" ON public.experiment_soaking FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Experiment soaking config is updatable by authenticated" ON public.experiment_soaking FOR UPDATE USING (auth.role() = 'authenticated');
CREATE POLICY "Experiment soaking config is deletable by authenticated" ON public.experiment_soaking FOR DELETE USING (auth.role() = 'authenticated');

CREATE TRIGGER set_updated_at_experiment_soaking
    BEFORE UPDATE ON public.experiment_soaking
    FOR EACH ROW EXECUTE FUNCTION public.handle_updated_at();

-- =============================================
-- 2. EXPERIMENT_AIRDRYING (template for airdrying phase)
-- =============================================

CREATE TABLE IF NOT EXISTS public.experiment_airdrying (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    experiment_id UUID NOT NULL REFERENCES public.experiments(id) ON DELETE CASCADE,
    duration_minutes INTEGER NOT NULL CHECK (duration_minutes >= 0),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    created_by UUID NOT NULL REFERENCES public.user_profiles(id),
    CONSTRAINT unique_experiment_airdrying_per_experiment UNIQUE (experiment_id)
);

CREATE INDEX IF NOT EXISTS idx_experiment_airdrying_experiment_id ON public.experiment_airdrying(experiment_id);
GRANT ALL ON public.experiment_airdrying TO authenticated;
ALTER TABLE public.experiment_airdrying ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Experiment airdrying config is viewable by authenticated" ON public.experiment_airdrying FOR SELECT USING (auth.role() = 'authenticated');
CREATE POLICY "Experiment airdrying config is insertable by authenticated" ON public.experiment_airdrying FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Experiment airdrying config is updatable by authenticated" ON public.experiment_airdrying FOR UPDATE USING (auth.role() = 'authenticated');
CREATE POLICY "Experiment airdrying config is deletable by authenticated" ON public.experiment_airdrying FOR DELETE USING (auth.role() = 'authenticated');

CREATE TRIGGER set_updated_at_experiment_airdrying
    BEFORE UPDATE ON public.experiment_airdrying
    FOR EACH ROW EXECUTE FUNCTION public.handle_updated_at();

-- =============================================
-- 3. EXPERIMENT_CRACKING (template for cracking; supports JC and Meyer params)
-- =============================================

CREATE TABLE IF NOT EXISTS public.experiment_cracking (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    experiment_id UUID NOT NULL REFERENCES public.experiments(id) ON DELETE CASCADE,
    machine_type_id UUID NOT NULL REFERENCES public.machine_types(id) ON DELETE RESTRICT,
    -- JC Cracker parameters (nullable; used when machine is JC)
    plate_contact_frequency_hz DOUBLE PRECISION CHECK (plate_contact_frequency_hz IS NULL OR plate_contact_frequency_hz > 0),
    throughput_rate_pecans_sec DOUBLE PRECISION CHECK (throughput_rate_pecans_sec IS NULL OR throughput_rate_pecans_sec > 0),
    crush_amount_in DOUBLE PRECISION CHECK (crush_amount_in IS NULL OR crush_amount_in >= 0),
    entry_exit_height_diff_in DOUBLE PRECISION,
    -- Meyer Cracker parameters (nullable; used when machine is Meyer)
    motor_speed_hz DOUBLE PRECISION CHECK (motor_speed_hz IS NULL OR motor_speed_hz > 0),
    jig_displacement_inches DOUBLE PRECISION CHECK (jig_displacement_inches IS NULL OR jig_displacement_inches >= 0),
    spring_stiffness_nm DOUBLE PRECISION CHECK (spring_stiffness_nm IS NULL OR spring_stiffness_nm > 0),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    created_by UUID NOT NULL REFERENCES public.user_profiles(id),
    CONSTRAINT unique_experiment_cracking_per_experiment UNIQUE (experiment_id)
);

CREATE INDEX IF NOT EXISTS idx_experiment_cracking_experiment_id ON public.experiment_cracking(experiment_id);
CREATE INDEX IF NOT EXISTS idx_experiment_cracking_machine_type_id ON public.experiment_cracking(machine_type_id);
GRANT ALL ON public.experiment_cracking TO authenticated;
ALTER TABLE public.experiment_cracking ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Experiment cracking config is viewable by authenticated" ON public.experiment_cracking FOR SELECT USING (auth.role() = 'authenticated');
CREATE POLICY "Experiment cracking config is insertable by authenticated" ON public.experiment_cracking FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Experiment cracking config is updatable by authenticated" ON public.experiment_cracking FOR UPDATE USING (auth.role() = 'authenticated');
CREATE POLICY "Experiment cracking config is deletable by authenticated" ON public.experiment_cracking FOR DELETE USING (auth.role() = 'authenticated');

CREATE TRIGGER set_updated_at_experiment_cracking
    BEFORE UPDATE ON public.experiment_cracking
    FOR EACH ROW EXECUTE FUNCTION public.handle_updated_at();

-- =============================================
-- 4. EXPERIMENT_SHELLING (template for shelling phase)
-- =============================================

CREATE TABLE IF NOT EXISTS public.experiment_shelling (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    experiment_id UUID NOT NULL REFERENCES public.experiments(id) ON DELETE CASCADE,
    ring_gap_inches NUMERIC(6,2) CHECK (ring_gap_inches IS NULL OR ring_gap_inches > 0),
    drum_rpm INTEGER CHECK (drum_rpm IS NULL OR drum_rpm > 0),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    created_by UUID NOT NULL REFERENCES public.user_profiles(id),
    CONSTRAINT unique_experiment_shelling_per_experiment UNIQUE (experiment_id)
);

CREATE INDEX IF NOT EXISTS idx_experiment_shelling_experiment_id ON public.experiment_shelling(experiment_id);
GRANT ALL ON public.experiment_shelling TO authenticated;
ALTER TABLE public.experiment_shelling ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Experiment shelling config is viewable by authenticated" ON public.experiment_shelling FOR SELECT USING (auth.role() = 'authenticated');
CREATE POLICY "Experiment shelling config is insertable by authenticated" ON public.experiment_shelling FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Experiment shelling config is updatable by authenticated" ON public.experiment_shelling FOR UPDATE USING (auth.role() = 'authenticated');
CREATE POLICY "Experiment shelling config is deletable by authenticated" ON public.experiment_shelling FOR DELETE USING (auth.role() = 'authenticated');

CREATE TRIGGER set_updated_at_experiment_shelling
    BEFORE UPDATE ON public.experiment_shelling
    FOR EACH ROW EXECUTE FUNCTION public.handle_updated_at();
