-- Supabase Schema for TabataFit
-- Run this in your Supabase SQL Editor

-- Enable UUID extension
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- Trainers table
CREATE TABLE trainers (
    id TEXT PRIMARY KEY,
    name TEXT NOT NULL,
    specialty TEXT NOT NULL,
    color TEXT NOT NULL,
    avatar_url TEXT,
    workout_count INTEGER DEFAULT 0,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Workouts table
CREATE TABLE workouts (
    id TEXT PRIMARY KEY,
    title TEXT NOT NULL,
    trainer_id TEXT NOT NULL REFERENCES trainers(id) ON DELETE CASCADE,
    category TEXT NOT NULL CHECK (category IN ('full-body', 'core', 'upper-body', 'lower-body', 'cardio')),
    level TEXT NOT NULL CHECK (level IN ('Beginner', 'Intermediate', 'Advanced')),
    duration INTEGER NOT NULL CHECK (duration IN (4, 8, 12, 20)),
    calories INTEGER NOT NULL,
    rounds INTEGER NOT NULL,
    prep_time INTEGER NOT NULL DEFAULT 10,
    work_time INTEGER NOT NULL DEFAULT 20,
    rest_time INTEGER NOT NULL DEFAULT 10,
    equipment TEXT[] DEFAULT '{}',
    music_vibe TEXT NOT NULL CHECK (music_vibe IN ('electronic', 'hip-hop', 'pop', 'rock', 'chill')),
    exercises JSONB NOT NULL DEFAULT '[]',
    thumbnail_url TEXT,
    video_url TEXT,
    is_featured BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Collections table
CREATE TABLE collections (
    id TEXT PRIMARY KEY,
    title TEXT NOT NULL,
    description TEXT NOT NULL,
    icon TEXT NOT NULL,
    gradient TEXT[],
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Collection-Workout junction table
CREATE TABLE collection_workouts (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    collection_id TEXT NOT NULL REFERENCES collections(id) ON DELETE CASCADE,
    workout_id TEXT NOT NULL REFERENCES workouts(id) ON DELETE CASCADE,
    sort_order INTEGER DEFAULT 0,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(collection_id, workout_id)
);

-- Programs table
CREATE TABLE programs (
    id TEXT PRIMARY KEY,
    title TEXT NOT NULL,
    description TEXT NOT NULL,
    weeks INTEGER NOT NULL,
    workouts_per_week INTEGER NOT NULL,
    level TEXT NOT NULL CHECK (level IN ('Beginner', 'Intermediate', 'Advanced')),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Program-Workout junction table
CREATE TABLE program_workouts (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    program_id TEXT NOT NULL REFERENCES programs(id) ON DELETE CASCADE,
    workout_id TEXT NOT NULL REFERENCES workouts(id) ON DELETE CASCADE,
    week_number INTEGER NOT NULL,
    day_number INTEGER NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(program_id, week_number, day_number)
);

-- Achievements table
CREATE TABLE achievements (
    id TEXT PRIMARY KEY,
    title TEXT NOT NULL,
    description TEXT NOT NULL,
    icon TEXT NOT NULL,
    requirement INTEGER NOT NULL,
    type TEXT NOT NULL CHECK (type IN ('workouts', 'streak', 'minutes', 'calories')),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Admin users table (for dashboard access)
CREATE TABLE admin_users (
    id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
    email TEXT NOT NULL,
    role TEXT NOT NULL DEFAULT 'editor' CHECK (role IN ('admin', 'editor')),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    last_login TIMESTAMP WITH TIME ZONE
);

-- Create storage buckets
INSERT INTO storage.buckets (id, name, public) VALUES 
    ('videos', 'videos', true),
    ('thumbnails', 'thumbnails', true),
    ('avatars', 'avatars', true)
ON CONFLICT (id) DO NOTHING;

-- Set up storage policies
CREATE POLICY "Public videos access"
    ON storage.objects FOR SELECT
    USING (bucket_id = 'videos');

CREATE POLICY "Admin videos upload"
    ON storage.objects FOR INSERT
    WITH CHECK (
        bucket_id = 'videos' 
        AND EXISTS (SELECT 1 FROM admin_users WHERE id = auth.uid())
    );

CREATE POLICY "Public thumbnails access"
    ON storage.objects FOR SELECT
    USING (bucket_id = 'thumbnails');

CREATE POLICY "Admin thumbnails upload"
    ON storage.objects FOR INSERT
    WITH CHECK (
        bucket_id = 'thumbnails' 
        AND EXISTS (SELECT 1 FROM admin_users WHERE id = auth.uid())
    );

CREATE POLICY "Public avatars access"
    ON storage.objects FOR SELECT
    USING (bucket_id = 'avatars');

CREATE POLICY "Admin avatars upload"
    ON storage.objects FOR INSERT
    WITH CHECK (
        bucket_id = 'avatars' 
        AND EXISTS (SELECT 1 FROM admin_users WHERE id = auth.uid())
    );

-- Row Level Security policies
ALTER TABLE trainers ENABLE ROW LEVEL SECURITY;
ALTER TABLE workouts ENABLE ROW LEVEL SECURITY;
ALTER TABLE collections ENABLE ROW LEVEL SECURITY;
ALTER TABLE collection_workouts ENABLE ROW LEVEL SECURITY;
ALTER TABLE programs ENABLE ROW LEVEL SECURITY;
ALTER TABLE program_workouts ENABLE ROW LEVEL SECURITY;
ALTER TABLE achievements ENABLE ROW LEVEL SECURITY;
ALTER TABLE admin_users ENABLE ROW LEVEL SECURITY;

-- Public read access for all content
CREATE POLICY "Public trainers read" ON trainers FOR SELECT USING (true);
CREATE POLICY "Public workouts read" ON workouts FOR SELECT USING (true);
CREATE POLICY "Public collections read" ON collections FOR SELECT USING (true);
CREATE POLICY "Public collection_workouts read" ON collection_workouts FOR SELECT USING (true);
CREATE POLICY "Public programs read" ON programs FOR SELECT USING (true);
CREATE POLICY "Public program_workouts read" ON program_workouts FOR SELECT USING (true);
CREATE POLICY "Public achievements read" ON achievements FOR SELECT USING (true);

-- Admin write access
CREATE POLICY "Admin trainers all" ON trainers 
    FOR ALL USING (EXISTS (SELECT 1 FROM admin_users WHERE id = auth.uid()));
CREATE POLICY "Admin workouts all" ON workouts 
    FOR ALL USING (EXISTS (SELECT 1 FROM admin_users WHERE id = auth.uid()));
CREATE POLICY "Admin collections all" ON collections 
    FOR ALL USING (EXISTS (SELECT 1 FROM admin_users WHERE id = auth.uid()));
CREATE POLICY "Admin collection_workouts all" ON collection_workouts 
    FOR ALL USING (EXISTS (SELECT 1 FROM admin_users WHERE id = auth.uid()));
CREATE POLICY "Admin programs all" ON programs 
    FOR ALL USING (EXISTS (SELECT 1 FROM admin_users WHERE id = auth.uid()));
CREATE POLICY "Admin program_workouts all" ON program_workouts 
    FOR ALL USING (EXISTS (SELECT 1 FROM admin_users WHERE id = auth.uid()));
CREATE POLICY "Admin achievements all" ON achievements 
    FOR ALL USING (EXISTS (SELECT 1 FROM admin_users WHERE id = auth.uid()));
CREATE POLICY "Admin users manage" ON admin_users 
    FOR ALL USING (EXISTS (SELECT 1 FROM admin_users WHERE id = auth.uid()));

-- Function to update updated_at timestamp
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ language 'plpgsql';

-- Triggers for updated_at
CREATE TRIGGER update_trainers_updated_at BEFORE UPDATE ON trainers
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_workouts_updated_at BEFORE UPDATE ON workouts
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_collections_updated_at BEFORE UPDATE ON collections
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_programs_updated_at BEFORE UPDATE ON programs
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_achievements_updated_at BEFORE UPDATE ON achievements
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
