-- =====================================================
-- TABLOS SYSTEM DATABASE SCHEMA
-- =====================================================

-- 1. TABLOS TABLE
-- Main table for storing tablo/workspace information
CREATE TABLE tablos (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL,
    description TEXT,
    color VARCHAR(50) NOT NULL DEFAULT 'bg-blue-500',
    owner_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    is_archived BOOLEAN DEFAULT FALSE,
    is_public BOOLEAN DEFAULT FALSE,
    settings JSONB DEFAULT '{}',
    
    -- Indexes for performance
    CONSTRAINT tablos_name_not_empty CHECK (LENGTH(TRIM(name)) > 0),
    CONSTRAINT tablos_color_format CHECK (color ~ '^bg-[a-z]+-[0-9]+$')
);

-- 2. TABLO MEMBERS TABLE
-- Junction table for tablo membership and permissions
CREATE TABLE tablo_members (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tablo_id UUID NOT NULL REFERENCES tablos(id) ON DELETE CASCADE,
    user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
    role VARCHAR(50) NOT NULL DEFAULT 'member',
    permissions JSONB DEFAULT '{"read": true, "write": false, "admin": false}',
    joined_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    invited_by UUID REFERENCES auth.users(id),
    
    -- Ensure unique membership per tablo
    UNIQUE(tablo_id, user_id),
    
    -- Valid roles constraint
    CONSTRAINT valid_member_role CHECK (role IN ('owner', 'admin', 'member', 'viewer'))
);

-- 3. TABLO BOARDS TABLE
-- Different boards within a tablo (like Kanban boards, calendars, etc.)
CREATE TABLE tablo_boards (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tablo_id UUID NOT NULL REFERENCES tablos(id) ON DELETE CASCADE,
    name VARCHAR(255) NOT NULL,
    type VARCHAR(50) NOT NULL DEFAULT 'kanban',
    description TEXT,
    position INTEGER NOT NULL DEFAULT 0,
    settings JSONB DEFAULT '{}',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    created_by UUID NOT NULL REFERENCES auth.users(id),
    
    -- Valid board types
    CONSTRAINT valid_board_type CHECK (type IN ('kanban', 'calendar', 'table', 'timeline', 'chat'))
);

-- 4. TABLO LISTS TABLE
-- Lists/columns within boards (for Kanban-style organization)
CREATE TABLE tablo_lists (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    board_id UUID NOT NULL REFERENCES tablo_boards(id) ON DELETE CASCADE,
    name VARCHAR(255) NOT NULL,
    position INTEGER NOT NULL DEFAULT 0,
    color VARCHAR(50),
    settings JSONB DEFAULT '{}',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 5. TABLO CARDS TABLE
-- Individual cards/items within lists
CREATE TABLE tablo_cards (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    list_id UUID NOT NULL REFERENCES tablo_lists(id) ON DELETE CASCADE,
    title VARCHAR(500) NOT NULL,
    description TEXT,
    position INTEGER NOT NULL DEFAULT 0,
    due_date TIMESTAMP WITH TIME ZONE,
    priority VARCHAR(20) DEFAULT 'medium',
    labels JSONB DEFAULT '[]',
    assignees JSONB DEFAULT '[]',
    attachments JSONB DEFAULT '[]',
    checklist JSONB DEFAULT '[]',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    created_by UUID NOT NULL REFERENCES auth.users(id),
    
    -- Valid priority levels
    CONSTRAINT valid_priority CHECK (priority IN ('low', 'medium', 'high', 'urgent'))
);

-- 6. TABLO ACTIVITIES TABLE
-- Activity log for tracking changes and actions
CREATE TABLE tablo_activities (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tablo_id UUID NOT NULL REFERENCES tablos(id) ON DELETE CASCADE,
    user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
    action VARCHAR(100) NOT NULL,
    entity_type VARCHAR(50) NOT NULL,
    entity_id UUID,
    details JSONB DEFAULT '{}',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    
    -- Valid entity types
    CONSTRAINT valid_entity_type CHECK (entity_type IN ('tablo', 'board', 'list', 'card', 'member'))
);

-- 7. TABLO CHAT CHANNELS TABLE
-- Chat channels within tablos
CREATE TABLE tablo_chat_channels (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tablo_id UUID NOT NULL REFERENCES tablos(id) ON DELETE CASCADE,
    name VARCHAR(255) NOT NULL,
    type VARCHAR(20) NOT NULL DEFAULT 'public',
    description TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    created_by UUID NOT NULL REFERENCES auth.users(id),
    
    -- Valid channel types
    CONSTRAINT valid_channel_type CHECK (type IN ('public', 'private', 'direct'))
);

-- 8. TABLO CHAT MESSAGES TABLE
-- Messages within chat channels
CREATE TABLE tablo_chat_messages (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    channel_id UUID NOT NULL REFERENCES tablo_chat_channels(id) ON DELETE CASCADE,
    user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
    content TEXT NOT NULL,
    message_type VARCHAR(20) DEFAULT 'text',
    attachments JSONB DEFAULT '[]',
    reply_to UUID REFERENCES tablo_chat_messages(id),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    is_edited BOOLEAN DEFAULT FALSE,
    
    -- Valid message types
    CONSTRAINT valid_message_type CHECK (message_type IN ('text', 'image', 'file', 'system'))
);

-- =====================================================
-- INDEXES FOR PERFORMANCE
-- =====================================================

-- Tablos indexes
CREATE INDEX idx_tablos_owner_id ON tablos(owner_id);
CREATE INDEX idx_tablos_created_at ON tablos(created_at DESC);
CREATE INDEX idx_tablos_name_search ON tablos USING gin(to_tsvector('french', name));

-- Tablo members indexes
CREATE INDEX idx_tablo_members_tablo_id ON tablo_members(tablo_id);
CREATE INDEX idx_tablo_members_user_id ON tablo_members(user_id);

-- Boards indexes
CREATE INDEX idx_tablo_boards_tablo_id ON tablo_boards(tablo_id);
CREATE INDEX idx_tablo_boards_position ON tablo_boards(tablo_id, position);

-- Lists indexes
CREATE INDEX idx_tablo_lists_board_id ON tablo_lists(board_id);
CREATE INDEX idx_tablo_lists_position ON tablo_lists(board_id, position);

-- Cards indexes
CREATE INDEX idx_tablo_cards_list_id ON tablo_cards(list_id);
CREATE INDEX idx_tablo_cards_position ON tablo_cards(list_id, position);
CREATE INDEX idx_tablo_cards_assignees ON tablo_cards USING gin(assignees);
CREATE INDEX idx_tablo_cards_due_date ON tablo_cards(due_date) WHERE due_date IS NOT NULL;

-- Activities indexes
CREATE INDEX idx_tablo_activities_tablo_id ON tablo_activities(tablo_id);
CREATE INDEX idx_tablo_activities_created_at ON tablo_activities(created_at DESC);
CREATE INDEX idx_tablo_activities_user_id ON tablo_activities(user_id);

-- Chat indexes
CREATE INDEX idx_tablo_chat_channels_tablo_id ON tablo_chat_channels(tablo_id);
CREATE INDEX idx_tablo_chat_messages_channel_id ON tablo_chat_messages(channel_id);
CREATE INDEX idx_tablo_chat_messages_created_at ON tablo_chat_messages(created_at DESC);

-- =====================================================
-- ROW LEVEL SECURITY (RLS) POLICIES
-- =====================================================

-- Enable RLS on all tables
ALTER TABLE tablos ENABLE ROW LEVEL SECURITY;
ALTER TABLE tablo_members ENABLE ROW LEVEL SECURITY;
ALTER TABLE tablo_boards ENABLE ROW LEVEL SECURITY;
ALTER TABLE tablo_lists ENABLE ROW LEVEL SECURITY;
ALTER TABLE tablo_cards ENABLE ROW LEVEL SECURITY;
ALTER TABLE tablo_activities ENABLE ROW LEVEL SECURITY;
ALTER TABLE tablo_chat_channels ENABLE ROW LEVEL SECURITY;
ALTER TABLE tablo_chat_messages ENABLE ROW LEVEL SECURITY;

-- Tablos policies
CREATE POLICY "Users can view tablos they are members of" ON tablos
    FOR SELECT USING (
        id IN (
            SELECT tablo_id FROM tablo_members 
            WHERE user_id = auth.uid()
        ) OR owner_id = auth.uid() OR is_public = true
    );

CREATE POLICY "Users can create their own tablos" ON tablos
    FOR INSERT WITH CHECK (owner_id = auth.uid());

CREATE POLICY "Owners and admins can update tablos" ON tablos
    FOR UPDATE USING (
        owner_id = auth.uid() OR
        id IN (
            SELECT tablo_id FROM tablo_members 
            WHERE user_id = auth.uid() AND role IN ('admin', 'owner')
        )
    );

-- Tablo members policies
CREATE POLICY "Users can view members of tablos they belong to" ON tablo_members
    FOR SELECT USING (
        tablo_id IN (
            SELECT tablo_id FROM tablo_members 
            WHERE user_id = auth.uid()
        )
    );

CREATE POLICY "Owners and admins can manage members" ON tablo_members
    FOR ALL USING (
        tablo_id IN (
            SELECT id FROM tablos WHERE owner_id = auth.uid()
        ) OR
        tablo_id IN (
            SELECT tablo_id FROM tablo_members 
            WHERE user_id = auth.uid() AND role IN ('admin', 'owner')
        )
    );

-- =====================================================
-- TRIGGERS FOR AUTOMATIC UPDATES
-- =====================================================

-- 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';

-- Apply triggers to relevant tables
CREATE TRIGGER update_tablos_updated_at BEFORE UPDATE ON tablos
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_tablo_boards_updated_at BEFORE UPDATE ON tablo_boards
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_tablo_lists_updated_at BEFORE UPDATE ON tablo_lists
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_tablo_cards_updated_at BEFORE UPDATE ON tablo_cards
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- Function to automatically add owner as member
CREATE OR REPLACE FUNCTION add_owner_as_member()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO tablo_members (tablo_id, user_id, role, permissions)
    VALUES (
        NEW.id, 
        NEW.owner_id, 
        'owner',
        '{"read": true, "write": true, "admin": true}'::jsonb
    );
    RETURN NEW;
END;
$$ language 'plpgsql';

CREATE TRIGGER add_owner_as_member_trigger AFTER INSERT ON tablos
    FOR EACH ROW EXECUTE FUNCTION add_owner_as_member();

-- =====================================================
-- SAMPLE DATA
-- =====================================================

-- Insert sample tablos (assuming user IDs exist)
-- Note: Replace with actual user UUIDs from your auth.users table
/*
INSERT INTO tablos (name, description, color, owner_id) VALUES
('Projet Alpha', 'Développement de la nouvelle application', 'bg-blue-500', 'user-uuid-1'),
('Marketing Q4', 'Campagnes marketing pour le quatrième trimestre', 'bg-green-500', 'user-uuid-2'),
('Équipe Dev', 'Coordination de l''équipe de développement', 'bg-purple-500', 'user-uuid-1'),
('Budget 2024', 'Planification budgétaire pour 2024', 'bg-red-500', 'user-uuid-3'),
('Roadmap', 'Feuille de route produit', 'bg-yellow-500', 'user-uuid-1'),
('Support Client', 'Gestion du support client', 'bg-indigo-500', 'user-uuid-2');
*/ 