-- Supabase SQL Setup for Whisky Vault

-- Profiles table
CREATE TABLE IF NOT EXISTS profiles (
  id UUID REFERENCES auth.users ON DELETE CASCADE PRIMARY KEY,
  username TEXT UNIQUE,
  avatar_url TEXT,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now())
);

-- Function to handle new user signup
CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS trigger AS $$
BEGIN
  INSERT INTO public.profiles (id, username, avatar_url)
  VALUES (
    new.id, 
    COALESCE(new.raw_user_meta_data->>'username', 'user_' || substr(new.id::text, 1, 8)), 
    new.raw_user_meta_data->>'avatar_url'
  )
  ON CONFLICT (id) DO NOTHING;
  RETURN new;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- Manual sync for existing users (Run this once)
-- INSERT INTO public.profiles (id)
-- SELECT id FROM auth.users
-- ON CONFLICT (id) DO NOTHING;

-- Bottles table
CREATE TABLE IF NOT EXISTS bottles (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL,
  name TEXT NOT NULL,
  distillery TEXT,
  category TEXT, -- Single Malt, Bourbon, etc.
  abv DECIMAL,
  age INTEGER,
  status TEXT DEFAULT 'sealed' CHECK (status IN ('sealed', 'open', 'sampled', 'empty')),
  whiskybase_id TEXT,
  image_url TEXT,
  purchase_price DECIMAL(10, 2),
  is_whisky BOOLEAN DEFAULT true,
  confidence INTEGER DEFAULT 100,
  finished_at TIMESTAMP WITH TIME ZONE,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now()),
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now())
);

-- Buddies table
CREATE TABLE IF NOT EXISTS buddies (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL,
  name TEXT NOT NULL,
  buddy_profile_id UUID REFERENCES profiles(id) ON DELETE SET NULL, -- Link to real account
  created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now())
);

-- Tasting Sessions table
CREATE TABLE IF NOT EXISTS tasting_sessions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL,
  name TEXT NOT NULL,
  scheduled_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now()),
  created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now())
);

-- Session Participants junction (updated with user_id to avoid RLS recursion)
CREATE TABLE IF NOT EXISTS session_participants (
  session_id UUID REFERENCES tasting_sessions(id) ON DELETE CASCADE NOT NULL,
  buddy_id UUID REFERENCES buddies(id) ON DELETE CASCADE NOT NULL,
  user_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL, -- The owner of the session
  PRIMARY KEY (session_id, buddy_id)
);

-- Tastings table (updated with session and buddy tagging)
CREATE TABLE IF NOT EXISTS tastings (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  bottle_id UUID REFERENCES bottles(id) ON DELETE CASCADE NOT NULL,
  user_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL,
  session_id UUID REFERENCES tasting_sessions(id) ON DELETE SET NULL,
  rating INTEGER CHECK (rating >= 0 AND rating <= 100),
  nose_notes TEXT,
  palate_notes TEXT,
  finish_notes TEXT,
  audio_transcript_url TEXT,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now())
);

-- Tasting Tagging (updated with user_id to avoid RLS recursion)
CREATE TABLE IF NOT EXISTS tasting_tags (
  tasting_id UUID REFERENCES tastings(id) ON DELETE CASCADE NOT NULL,
  buddy_id UUID REFERENCES buddies(id) ON DELETE CASCADE NOT NULL,
  user_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL, -- The owner of the tasting
  PRIMARY KEY (tasting_id, buddy_id)
);

-- Enable Row Level Security (RLS)
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
ALTER TABLE bottles ENABLE ROW LEVEL SECURITY;
ALTER TABLE tastings ENABLE ROW LEVEL SECURITY;

-- Policies for Profiles
CREATE POLICY "Users can view their own profile" ON profiles
  FOR SELECT USING (auth.uid() = id);

CREATE POLICY "Users can update their own profile" ON profiles
  FOR UPDATE USING (auth.uid() = id);

-- Policies for Bottles
CREATE POLICY "Users can view their own bottles" ON bottles
  FOR SELECT USING (auth.uid() = user_id);

CREATE POLICY "Users can insert their own bottles" ON bottles
  FOR INSERT WITH CHECK (auth.uid() = user_id);

CREATE POLICY "Users can update their own bottles" ON bottles
  FOR UPDATE USING (auth.uid() = user_id);

CREATE POLICY "Users can delete their own bottles" ON bottles
  FOR DELETE USING (auth.uid() = user_id);

-- Policies for Tastings
CREATE POLICY "Users can view their own tastings" ON tastings
  FOR SELECT USING (auth.uid() = user_id);

-- Geteilte Tastings für Buddies sichtbar machen (wenn verknüpft)
CREATE POLICY "Users can view tastings they are tagged in" ON tastings
  FOR SELECT USING (
    id IN (
      SELECT tasting_id FROM tasting_tags 
      WHERE buddy_id IN (SELECT id FROM buddies WHERE buddy_profile_id = auth.uid())
    )
  );

CREATE POLICY "Users can insert their own tastings" ON tastings
  FOR INSERT WITH CHECK (auth.uid() = user_id);

CREATE POLICY "Users can update their own tastings" ON tastings
  FOR UPDATE USING (auth.uid() = user_id);

CREATE POLICY "Users can delete their own tastings" ON tastings
  FOR DELETE USING (auth.uid() = user_id);

-- Policies for Buddies
ALTER TABLE buddies ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can manage their own buddies" ON buddies
  FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "Users can see buddies linked to their profile" ON buddies
  FOR SELECT USING (buddy_profile_id = auth.uid());

-- TASTINGS (Core Table)
ALTER TABLE tastings ENABLE ROW LEVEL SECURITY;

-- SIMPLEST POLICY: You see your own stuff. 
-- No subqueries = No recursion.
CREATE POLICY "tastings_owner_policy" ON tastings
  FOR ALL USING (auth.uid() = user_id);

-- Policies for Tasting Sessions
ALTER TABLE tasting_sessions ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can manage their own sessions" ON tasting_sessions
  FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "Users can see sessions they participate in" ON tasting_sessions
  FOR SELECT USING (
    id IN (
      SELECT session_id FROM session_participants 
      WHERE buddy_id IN (SELECT id FROM buddies WHERE buddy_profile_id = auth.uid())
    )
  );

-- SESSION PARTICIPANTS
ALTER TABLE session_participants ENABLE ROW LEVEL SECURITY;
CREATE POLICY "session_participants_owner_policy" ON session_participants
  FOR ALL USING (auth.uid() = user_id);

-- TASTING TAGS
ALTER TABLE tasting_tags ENABLE ROW LEVEL SECURITY;
CREATE POLICY "tasting_tags_owner_policy" ON tasting_tags
  FOR ALL USING (auth.uid() = user_id);

-- STORAGE SETUP
-- Create 'bottles' bucket if it doesn't exist
INSERT INTO storage.buckets (id, name, public)
VALUES ('bottles', 'bottles', true)
ON CONFLICT (id) DO NOTHING;

-- Policy to allow authenticated users to upload images to their own folder
-- Falls der Folder-Check zu strikt ist, erlauben wir hier generell Uploads für Authenticated User
-- Aber wir behalten die Zuordnung im Dateinamen bei.
CREATE POLICY "Allow authenticated uploads"
ON storage.objects FOR INSERT
TO authenticated
WITH CHECK (
  bucket_id = 'bottles'
);

-- Policy to allow users to update/delete their own images
CREATE POLICY "Allow users to manage own images"
ON storage.objects FOR ALL
TO authenticated
USING (
  bucket_id = 'bottles' AND
  (storage.foldername(name))[1] = auth.uid()::text
);

-- Policy to allow public to view images
CREATE POLICY "Allow public view access"
ON storage.objects FOR SELECT
TO public
USING (bucket_id = 'bottles');

-- VISION CACHE
CREATE TABLE IF NOT EXISTS vision_cache (
  hash TEXT PRIMARY KEY,
  result JSONB NOT NULL,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('utc'::text, now())
);

-- Enable RLS for vision_cache (though it's only accessed via Service Role/Server Actions)
ALTER TABLE vision_cache ENABLE ROW LEVEL SECURITY;

-- Policy to allow authenticated users to view the cache (optional, but good for transparency)
CREATE POLICY "Allow authenticated users to view cache"
ON vision_cache FOR SELECT
TO authenticated
USING (true);
