-- CalcText database schema
-- Run via Docker init or manually

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

-- Roles for RLS
DO $$ BEGIN
  IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'anon') THEN
    CREATE ROLE anon NOLOGIN;
  END IF;
  IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'authenticated') THEN
    CREATE ROLE authenticated NOLOGIN;
  END IF;
END $$;

GRANT USAGE ON SCHEMA public TO anon, authenticated;

-- ============================================================
-- User profiles (extends GoTrue auth.users)
-- ============================================================
CREATE TABLE IF NOT EXISTS profiles (
  id UUID PRIMARY KEY,
  display_name TEXT,
  avatar_url TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;

CREATE POLICY profiles_own ON profiles
  FOR ALL USING (id = current_setting('request.jwt.claims', true)::json->>'sub'::text::uuid);

GRANT SELECT, INSERT, UPDATE ON profiles TO authenticated;

-- ============================================================
-- Folders
-- ============================================================
CREATE TABLE IF NOT EXISTS folders (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  owner_id UUID NOT NULL,
  name TEXT NOT NULL DEFAULT 'New Folder',
  parent_id UUID REFERENCES folders(id) ON DELETE CASCADE,
  sort_order INTEGER DEFAULT 0,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

ALTER TABLE folders ENABLE ROW LEVEL SECURITY;

CREATE POLICY folders_own ON folders
  FOR ALL USING (owner_id = current_setting('request.jwt.claims', true)::json->>'sub'::text::uuid);

GRANT SELECT, INSERT, UPDATE, DELETE ON folders TO authenticated;

-- ============================================================
-- Documents
-- ============================================================
CREATE TABLE IF NOT EXISTS documents (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  owner_id UUID NOT NULL,
  title TEXT NOT NULL DEFAULT 'Untitled',
  folder_id UUID REFERENCES folders(id) ON DELETE SET NULL,
  is_favorite BOOLEAN NOT NULL DEFAULT false,
  share_token TEXT UNIQUE,
  share_permission TEXT CHECK (share_permission IN ('view', 'edit')),
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_documents_owner ON documents(owner_id);
CREATE INDEX idx_documents_share_token ON documents(share_token) WHERE share_token IS NOT NULL;

ALTER TABLE documents ENABLE ROW LEVEL SECURITY;

-- Owner can do anything
CREATE POLICY documents_owner ON documents
  FOR ALL USING (owner_id = current_setting('request.jwt.claims', true)::json->>'sub'::text::uuid);

-- Shared documents can be read via share token (anon access)
CREATE POLICY documents_shared_read ON documents
  FOR SELECT USING (share_token IS NOT NULL AND share_permission IS NOT NULL);

GRANT SELECT, INSERT, UPDATE, DELETE ON documents TO authenticated;
GRANT SELECT ON documents TO anon;

-- ============================================================
-- Document collaborators (explicit user-to-user sharing)
-- ============================================================
CREATE TABLE IF NOT EXISTS document_collaborators (
  document_id UUID NOT NULL REFERENCES documents(id) ON DELETE CASCADE,
  user_id UUID NOT NULL,
  permission TEXT NOT NULL CHECK (permission IN ('view', 'edit')),
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  PRIMARY KEY (document_id, user_id)
);

ALTER TABLE document_collaborators ENABLE ROW LEVEL SECURITY;

-- Users can see their own collaborations
CREATE POLICY collab_own ON document_collaborators
  FOR SELECT USING (user_id = current_setting('request.jwt.claims', true)::json->>'sub'::text::uuid);

-- Document owners can manage collaborators
CREATE POLICY collab_owner ON document_collaborators
  FOR ALL USING (
    document_id IN (
      SELECT id FROM documents
      WHERE owner_id = current_setting('request.jwt.claims', true)::json->>'sub'::text::uuid
    )
  );

GRANT SELECT, INSERT, UPDATE, DELETE ON document_collaborators TO authenticated;

-- ============================================================
-- Device sessions (password renewal per device)
-- ============================================================
CREATE TABLE IF NOT EXISTS device_sessions (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  user_id UUID NOT NULL,
  device_fingerprint TEXT NOT NULL,
  device_name TEXT,
  session_ttl_seconds INTEGER NOT NULL DEFAULT 86400,
  last_password_auth_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  UNIQUE (user_id, device_fingerprint)
);

ALTER TABLE device_sessions ENABLE ROW LEVEL SECURITY;

CREATE POLICY device_sessions_own ON device_sessions
  FOR ALL USING (user_id = current_setting('request.jwt.claims', true)::json->>'sub'::text::uuid);

GRANT SELECT, INSERT, UPDATE, DELETE ON device_sessions TO authenticated;

-- ============================================================
-- Y.js document snapshots storage
-- ============================================================
CREATE TABLE IF NOT EXISTS ydoc_snapshots (
  document_id UUID PRIMARY KEY REFERENCES documents(id) ON DELETE CASCADE,
  state BYTEA NOT NULL,
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

ALTER TABLE ydoc_snapshots ENABLE ROW LEVEL SECURITY;

-- Owner can read/write snapshots
CREATE POLICY ydoc_owner ON ydoc_snapshots
  FOR ALL USING (
    document_id IN (
      SELECT id FROM documents
      WHERE owner_id = current_setting('request.jwt.claims', true)::json->>'sub'::text::uuid
    )
  );

-- Collaborators can read/write snapshots
CREATE POLICY ydoc_collab ON ydoc_snapshots
  FOR ALL USING (
    document_id IN (
      SELECT document_id FROM document_collaborators
      WHERE user_id = current_setting('request.jwt.claims', true)::json->>'sub'::text::uuid
      AND permission = 'edit'
    )
  );

GRANT SELECT, INSERT, UPDATE ON ydoc_snapshots TO authenticated;
