-- =====================================================
-- 0. MASTER TABLE: m_synonym (HAS HEADER)
-- =====================================================
-- CSV columns: from, to
CREATE TABLE IF NOT EXISTS m_synonym (
  "from" TEXT PRIMARY KEY,
  "to" TEXT
);
-- =====================================================
-- SUPABASE DATABASE SETUP
-- =====================================================
-- Run these SQL commands in your Supabase SQL Editor
-- (Dashboard > SQL Editor > New Query)

-- =====================================================
-- 1. CREATE PROFILES TABLE
-- =====================================================
-- This table stores user profile information
-- It's linked to Supabase auth.users table

CREATE TABLE IF NOT EXISTS public.profiles (
  id UUID REFERENCES auth.users(id) PRIMARY KEY,
  email TEXT,
  full_name TEXT,
  avatar_url TEXT,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- =====================================================
-- 2. ENABLE ROW LEVEL SECURITY
-- =====================================================
-- This ensures users can only access their own data

ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;

-- =====================================================
-- 3. CREATE RLS POLICIES
-- =====================================================

-- Allow users to view their own profile
CREATE POLICY "Users can view their own profile"
  ON public.profiles
  FOR SELECT
  USING (auth.uid() = id);

-- Allow users to insert their own profile
CREATE POLICY "Users can insert their own profile"
  ON public.profiles
  FOR INSERT
  WITH CHECK (auth.uid() = id);

-- Allow users to update their own profile
CREATE POLICY "Users can update their own profile"
  ON public.profiles
  FOR UPDATE
  USING (auth.uid() = id)
  WITH CHECK (auth.uid() = id);

-- Allow users to delete their own profile (optional)
CREATE POLICY "Users can delete their own profile"
  ON public.profiles
  FOR DELETE
  USING (auth.uid() = id);

-- =====================================================
-- 4. CREATE FUNCTION TO HANDLE NEW USER SIGNUPS
-- =====================================================
-- Automatically creates a profile when a new user signs up

CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS TRIGGER AS $$
BEGIN
  INSERT INTO public.profiles (id, email, full_name, avatar_url)
  VALUES (
    NEW.id,
    NEW.email,
    NEW.raw_user_meta_data->>'full_name',
    NEW.raw_user_meta_data->>'avatar_url'
  );
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- =====================================================
-- 5. CREATE TRIGGER FOR NEW USER SIGNUPS
-- =====================================================
-- Trigger the function whenever a new user is created

DROP TRIGGER IF EXISTS on_auth_user_created ON auth.users;

CREATE TRIGGER on_auth_user_created
  AFTER INSERT ON auth.users
  FOR EACH ROW
  EXECUTE FUNCTION public.handle_new_user();

-- =====================================================
-- 6. CREATE FUNCTION TO UPDATE updated_at TIMESTAMP
-- =====================================================

CREATE OR REPLACE FUNCTION public.handle_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- =====================================================
-- 7. CREATE TRIGGER FOR updated_at
-- =====================================================

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

-- =====================================================
-- 8. EXAMPLE: CREATE A CUSTOM TABLE WITH RLS
-- =====================================================
-- Example of how to create your own tables with RLS

CREATE TABLE IF NOT EXISTS public.user_items (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id UUID REFERENCES auth.users(id) NOT NULL,
  title TEXT NOT NULL,
  description TEXT,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Enable RLS
ALTER TABLE public.user_items ENABLE ROW LEVEL SECURITY;

-- Create policies
CREATE POLICY "Users can view their own items"
  ON public.user_items
  FOR SELECT
  USING (auth.uid() = user_id);

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

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

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

-- Add updated_at trigger
CREATE TRIGGER set_user_items_updated_at
  BEFORE UPDATE ON public.user_items
  FOR EACH ROW
  EXECUTE FUNCTION public.handle_updated_at();

-- =====================================================
-- 9. OPTIONAL: CREATE STORAGE BUCKET
-- =====================================================
-- For file uploads (avatars, documents, etc.)
-- Run this in the SQL Editor or create via Dashboard > Storage

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

-- Create storage policy for avatars
CREATE POLICY "Avatar images are publicly accessible"
  ON storage.objects FOR SELECT
  USING (bucket_id = 'avatars');

CREATE POLICY "Users can upload their own avatar"
  ON storage.objects FOR INSERT
  WITH CHECK (
    bucket_id = 'avatars' AND
    auth.uid()::text = (storage.foldername(name))[1]
  );

CREATE POLICY "Users can update their own avatar"
  ON storage.objects FOR UPDATE
  USING (
    bucket_id = 'avatars' AND
    auth.uid()::text = (storage.foldername(name))[1]
  );

CREATE POLICY "Users can delete their own avatar"
  ON storage.objects FOR DELETE
  USING (
    bucket_id = 'avatars' AND
    auth.uid()::text = (storage.foldername(name))[1]
  );

-- =====================================================
-- 10. MASTER DATA AND FACT TABLES
-- =====================================================
-- SQL schema for master data and fact tables from CSV files
-- CSV Import Notes:
-- - Master tables (m_*) have headers: skip 1 row on import
-- - Fact tables have NO headers: import from row 1
-- - Keys with leading zeros are VARCHAR to preserve formatting
-- - Currency fields NUMERIC(18,2); volumes NUMERIC(18,3)


-- =====================================================
-- 1. MASTER DATA TABLES (HAS HEADER)
-- =====================================================

-- m_synonym
-- CSV columns: from, to
CREATE TABLE IF NOT EXISTS m_synonym (
  "from" TEXT PRIMARY KEY,
  "to" TEXT
);

-- m_country
-- CSV columns: Index,Country_code,Country,Region,Subregion,Country_key
CREATE TABLE IF NOT EXISTS m_country (
  idx INTEGER NULL,
  country_code VARCHAR(10) NOT NULL,
  country VARCHAR(100) NOT NULL,
  region VARCHAR(100) NULL,
  subregion VARCHAR(100) NULL,
  country_key VARCHAR(64) NOT NULL,
  CONSTRAINT pk_m_country PRIMARY KEY (country_key)
);
CREATE INDEX IF NOT EXISTS ix_m_country_code ON m_country(country_code);
CREATE INDEX IF NOT EXISTS ix_m_country_region ON m_country(region);

-- m_customer_shipto
-- CSV columns: Customer_shipto_key,Customer_shipto
CREATE TABLE IF NOT EXISTS m_customer_shipto (
  customer_shipto_key VARCHAR(10) NOT NULL,
  customer_shipto VARCHAR(255) NOT NULL,
  CONSTRAINT [REDACTED]PRIMARY KEY (customer_shipto_key)
);

-- m_customer_soldto
-- CSV columns: Customer_soldto_key,Customer_soldto,Customer_group
CREATE TABLE IF NOT EXISTS m_customer_soldto (
  customer_soldto_key VARCHAR(10) NOT NULL,
  customer_soldto VARCHAR(255) NOT NULL,
  customer_group VARCHAR(100) NULL,
  CONSTRAINT [REDACTED]PRIMARY KEY (customer_soldto_key)
);

-- m_product
-- CSV columns: Product_article_key,Product_article,Product_group_key,Product_group
CREATE TABLE IF NOT EXISTS m_product (
  product_article_key VARCHAR(10) NOT NULL,
  product_article VARCHAR(255) NOT NULL,
  product_group_key VARCHAR(10) NOT NULL,
  product_group VARCHAR(255) NOT NULL,
  CONSTRAINT pk_m_product PRIMARY KEY (product_article_key)
);
CREATE INDEX IF NOT EXISTS ix_m_product_group_key ON m_product(product_group_key);

-- Fact Table: fact_inventory.csv (NO HEADER)
-- CSV columns: Country_key, Product_article_key, Inventory_volume, Source
CREATE TABLE fact_inventory (
  country_key VARCHAR(64) NOT NULL,
  product_article_key VARCHAR(10) NOT NULL,
  inventory_volume NUMERIC(18,3) NOT NULL,
  source VARCHAR(32) NOT NULL,
  CONSTRAINT pk_fact_inventory PRIMARY KEY (country_key, product_article_key),
  CONSTRAINT fk_inv_country FOREIGN KEY (country_key) REFERENCES m_country(country_key),
  CONSTRAINT fk_inv_product FOREIGN KEY (product_article_key) REFERENCES m_product(product_article_key)
);

CREATE INDEX ix_inv_country ON fact_inventory(country_key);
CREATE INDEX ix_inv_product ON fact_inventory(product_article_key);

-- Fact Table: fact_orders.csv (NO HEADER)
-- CSV columns: Date, Country_key, Document_number, Customer_soldto_key, Customer_shipto_key,
--              Product_article_key, PO_number, Order_volume, Order_eur, Order_lc, Order_usd, Source
CREATE TABLE fact_orders (
  date DATE NOT NULL,
  country_key VARCHAR(64) NOT NULL,
  document_number VARCHAR(40) NOT NULL,
  customer_soldto_key VARCHAR(10) NOT NULL,
  customer_shipto_key VARCHAR(10) NOT NULL,
  product_article_key VARCHAR(10) NOT NULL,
  po_number VARCHAR(40) NULL,
  order_volume NUMERIC(18,3) NOT NULL,
  order_eur NUMERIC(18,2) NULL,
  order_lc NUMERIC(18,2) NULL,
  order_usd NUMERIC(18,2) NULL,
  source VARCHAR(32) NOT NULL,
  CONSTRAINT pk_fact_orders PRIMARY KEY (document_number),
  CONSTRAINT fk_ord_country FOREIGN KEY (country_key) REFERENCES m_country(country_key),
  CONSTRAINT fk_ord_soldto FOREIGN KEY (customer_soldto_key) REFERENCES m_customer_soldto(customer_soldto_key),
  CONSTRAINT fk_ord_shipto FOREIGN KEY (customer_shipto_key) REFERENCES m_customer_shipto(customer_shipto_key),
  CONSTRAINT fk_ord_product FOREIGN KEY (product_article_key) REFERENCES m_product(product_article_key)
);

CREATE INDEX ix_ord_date ON fact_orders(date);
CREATE INDEX ix_ord_country ON fact_orders(country_key);
CREATE INDEX ix_ord_soldto ON fact_orders(customer_soldto_key);
CREATE INDEX ix_ord_shipto ON fact_orders(customer_shipto_key);
CREATE INDEX ix_ord_product ON fact_orders(product_article_key);

-- Fact Table: fact_overdues.csv (NO HEADER)
-- CSV columns: Country_key, Customer_soldto_key, Customer_shipto_key, Product_article_key,
--              Document_number, Due_date, Overdue_eur, Overdue_lc, Overdue_usd, Source
CREATE TABLE fact_overdues (
  country_key VARCHAR(64) NOT NULL,
  customer_soldto_key VARCHAR(10) NOT NULL,
  customer_shipto_key VARCHAR(10) NOT NULL,
  product_article_key VARCHAR(10) NOT NULL,
  document_number VARCHAR(40) NOT NULL,
  due_date DATE NOT NULL,
  overdue_eur NUMERIC(18,2) NULL,
  overdue_lc NUMERIC(18,2) NULL,
  overdue_usd NUMERIC(18,2) NULL,
  source VARCHAR(32) NOT NULL,
  CONSTRAINT pk_fact_overdues PRIMARY KEY (document_number),
  CONSTRAINT fk_ovd_country FOREIGN KEY (country_key) REFERENCES m_country(country_key),
  CONSTRAINT fk_ovd_soldto FOREIGN KEY (customer_soldto_key) REFERENCES m_customer_soldto(customer_soldto_key),
  CONSTRAINT fk_ovd_shipto FOREIGN KEY (customer_shipto_key) REFERENCES m_customer_shipto(customer_shipto_key),
  CONSTRAINT fk_ovd_product FOREIGN KEY (product_article_key) REFERENCES m_product(product_article_key)
);

CREATE INDEX ix_ovd_due_date ON fact_overdues(due_date);
CREATE INDEX ix_ovd_country ON fact_overdues(country_key);
CREATE INDEX ix_ovd_soldto ON fact_overdues(customer_soldto_key);
CREATE INDEX ix_ovd_shipto ON fact_overdues(customer_shipto_key);
CREATE INDEX ix_ovd_product ON fact_overdues(product_article_key);

-- Fact Table: fact_sales.csv (NO HEADER)
-- CSV columns: Date, Country_key, Customer_soldto_key, Customer_shipto_key, Product_article_key,
--              Sales_volume, Sales_eur, Sales_lc, Sales_usd, Source
CREATE TABLE fact_sales (
  date DATE NOT NULL,
  country_key VARCHAR(64) NOT NULL,
  customer_soldto_key VARCHAR(10) NOT NULL,
  customer_shipto_key VARCHAR(10) NOT NULL,
  product_article_key VARCHAR(10) NOT NULL,
  sales_volume NUMERIC(18,3) NOT NULL,
  sales_eur NUMERIC(18,2) NULL,
  sales_lc NUMERIC(18,2) NULL,
  sales_usd NUMERIC(18,2) NULL,
  source VARCHAR(32) NOT NULL,
  CONSTRAINT pk_fact_sales PRIMARY KEY (date, country_key, customer_soldto_key, customer_shipto_key, product_article_key),
  CONSTRAINT fk_sal_country FOREIGN KEY (country_key) REFERENCES m_country(country_key),
  CONSTRAINT fk_sal_soldto FOREIGN KEY (customer_soldto_key) REFERENCES m_customer_soldto(customer_soldto_key),
  CONSTRAINT fk_sal_shipto FOREIGN KEY (customer_shipto_key) REFERENCES m_customer_shipto(customer_shipto_key),
  CONSTRAINT fk_sal_product FOREIGN KEY (product_article_key) REFERENCES m_product(product_article_key)
);

CREATE INDEX ix_sal_date ON fact_sales(date);
CREATE INDEX ix_sal_country ON fact_sales(country_key);
CREATE INDEX ix_sal_soldto ON fact_sales(customer_soldto_key);
CREATE INDEX ix_sal_shipto ON fact_sales(customer_shipto_key);
CREATE INDEX ix_sal_product ON fact_sales(product_article_key);

-- =====================================================
-- 11. ENABLE RLS FOR MASTER DATA TABLES
-- =====================================================
-- Enable Row Level Security for master data tables
-- These policies allow all authenticated users to access master data


-- =====================================================
-- 2. ENABLE RLS FOR MASTER DATA TABLES
-- =====================================================

-- Enable RLS on master tables
ALTER TABLE m_synonym ENABLE ROW LEVEL SECURITY;
ALTER TABLE m_country ENABLE ROW LEVEL SECURITY;
ALTER TABLE m_customer_shipto ENABLE ROW LEVEL SECURITY;
ALTER TABLE m_customer_soldto ENABLE ROW LEVEL SECURITY;
ALTER TABLE m_product ENABLE ROW LEVEL SECURITY;

-- RLS Policies for m_synonym
CREATE POLICY "Authenticated users can view synonyms"
  ON m_synonym FOR SELECT
  TO authenticated
  USING (true);

CREATE POLICY "Authenticated users can insert synonyms"
  ON m_synonym FOR INSERT
  TO authenticated
  WITH CHECK (true);

CREATE POLICY "Authenticated users can update synonyms"
  ON m_synonym FOR UPDATE
  TO authenticated
  USING (true)
  WITH CHECK (true);

CREATE POLICY "Authenticated users can delete synonyms"
  ON m_synonym FOR DELETE
  TO authenticated
  USING (true);

-- RLS Policies for m_country
CREATE POLICY "Authenticated users can view countries"
  ON m_country FOR SELECT
  TO authenticated
  USING (true);

CREATE POLICY "Authenticated users can insert countries"
  ON m_country FOR INSERT
  TO authenticated
  WITH CHECK (true);

CREATE POLICY "Authenticated users can update countries"
  ON m_country FOR UPDATE
  TO authenticated
  USING (true)
  WITH CHECK (true);

CREATE POLICY "Authenticated users can delete countries"
  ON m_country FOR DELETE
  TO authenticated
  USING (true);

-- RLS Policies for m_customer_shipto
CREATE POLICY "Authenticated users can view ship-to customers"
  ON m_customer_shipto FOR SELECT
  TO authenticated
  USING (true);

CREATE POLICY "Authenticated users can insert ship-to customers"
  ON m_customer_shipto FOR INSERT
  TO authenticated
  WITH CHECK (true);

CREATE POLICY "Authenticated users can update ship-to customers"
  ON m_customer_shipto FOR UPDATE
  TO authenticated
  USING (true)
  WITH CHECK (true);

CREATE POLICY "Authenticated users can delete ship-to customers"
  ON m_customer_shipto FOR DELETE
  TO authenticated
  USING (true);

-- RLS Policies for m_customer_soldto
CREATE POLICY "Authenticated users can view sold-to customers"
  ON m_customer_soldto FOR SELECT
  TO authenticated
  USING (true);

CREATE POLICY "Authenticated users can insert sold-to customers"
  ON m_customer_soldto FOR INSERT
  TO authenticated
  WITH CHECK (true);

CREATE POLICY "Authenticated users can update sold-to customers"
  ON m_customer_soldto FOR UPDATE
  TO authenticated
  USING (true)
  WITH CHECK (true);

CREATE POLICY "Authenticated users can delete sold-to customers"
  ON m_customer_soldto FOR DELETE
  TO authenticated
  USING (true);

-- RLS Policies for m_product
CREATE POLICY "Authenticated users can view products"
  ON m_product FOR SELECT
  TO authenticated
  USING (true);

CREATE POLICY "Authenticated users can insert products"
  ON m_product FOR INSERT
  TO authenticated
  WITH CHECK (true);

CREATE POLICY "Authenticated users can update products"
  ON m_product FOR UPDATE
  TO authenticated
  USING (true)
  WITH CHECK (true);

CREATE POLICY "Authenticated users can delete products"
  ON m_product FOR DELETE
  TO authenticated
  USING (true);

-- =====================================================
-- DONE! 
-- =====================================================
-- Your Supabase database is now set up with:
-- ✅ Profiles table with RLS
-- ✅ Automatic profile creation on signup
-- ✅ Example custom table (user_items)
-- ✅ Storage bucket for avatars
-- ✅ Master data tables with RLS policies
--
-- Next steps:
-- 1. Update your .env file with Supabase credentials
-- 2. Configure OAuth providers in Supabase Dashboard (optional)
-- 3. Test authentication from your frontend
-- 4. Import CSV data into master and fact tables

-- Table for storing embeddings and metadata for filter values and RAG vectors. This is a unified table that can be used for both purposes, differentiated by the 'type' column.
CREATE TABLE IF NOT EXISTS public.rag_vector (
  id uuid not null default gen_random_uuid (),
  embeddings public.vector not null,
  value_to_be_embedded character varying(200) not null,
  actual_value character varying(255) null,
  column_name character varying(255) null,
  type character varying(200) not null,
  created_at timestamp with time zone null default now(),
  updated_at timestamp with time zone null default now(),
  constraint rag_vector_pkey primary key (id)
) TABLESPACE pg_default;

create index IF not exists ix_rag_vector_type on public.rag_vector using btree (type) TABLESPACE pg_default;
create index IF not exists ix_rag_vector_value on public.rag_vector using btree (value_to_be_embedded) TABLESPACE pg_default;

-- RLS Policies for profiles_rls
create table public.profiles_rls (
  id bigint generated by default as identity not null,
  email text not null,
  source text not null,
  country text not null,
  customer_soldto text not null,
  constraint profiles_rls_pkey primary key (id)
) TABLESPACE pg_default;


-- Supabase setup script for documents storage and metadata
-- 1) Create a Storage bucket named 'documents' via Supabase Dashboard -> Storage
--    (Set Public Access = false if you want private files.)

-- 2) Optional: ensure pgcrypto extension (for gen_random_uuid)
-- Run in SQL editor if your DB allows extensions
create extension if not exists pgcrypto;

-- 3) Create metadata table
create table if not exists documents (
  id uuid primary key default gen_random_uuid(),
  user_id uuid references auth.users(id) not null,
  filename text not null,
  storage_path text not null,
  uploaded_at timestamp with time zone default now()
);

-- 4) Enable Row-Level Security (RLS)
alter table documents enable row level security;

-- 5) Policies
-- Users can only view their own documents
drop policy if exists "Users can view own documents" on documents;
create policy "Users can view own documents"
on documents for select
using (auth.uid() = user_id);

-- Users can only insert documents with their own user_id
drop policy if exists "Users can insert own documents" on documents;
create policy "Users can insert own documents"
on documents for insert
with check (auth.uid() = user_id);

-- Users can update only their own documents
drop policy if exists "Users can update own documents" on documents;
create policy "Users can update own documents"
on documents for update
using (auth.uid() = user_id)
with check (auth.uid() = user_id);

-- Users can delete only their own documents
drop policy if exists "Users can delete own documents" on documents;
create policy "Users can delete own documents"
on documents for delete
using (auth.uid() = user_id);

-- Notes:
-- - Create the storage bucket in the Supabase dashboard called `documents`.
-- - Make sure your service_role key or server-side client is used for storage uploads
--   from a trusted backend (do not embed the service_role key in frontend code).


create table public.rag_user_documents (
  id uuid not null default gen_random_uuid (),
  user_id uuid not null,
  content text not null,
  embedding double precision[] not null,
  doc_id uuid null,
  constraint rag_user_documents_pkey primary key (id),
  constraint rag_user_documents_doc_id_fkey foreign KEY (doc_id) references documents (id) on update CASCADE on delete CASCADE
) TABLESPACE pg_default;