-- Local Issue Tracking Database Schema
-- SQLite schema for local issue storage with full referential integrity

-- Enable foreign key constraints
PRAGMA foreign_keys = ON;

-- Issues table - core issue data
CREATE TABLE IF NOT EXISTS issues (
    id TEXT PRIMARY KEY,
    number INTEGER UNIQUE NOT NULL,
    title TEXT NOT NULL,
    description TEXT NOT NULL DEFAULT '',
    state TEXT NOT NULL CHECK (state IN ('open', 'closed', 'in_progress', 'blocked')),
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    closed_at TIMESTAMP NULL,
    milestone_id TEXT,
    backend_id TEXT,
    backend_type TEXT DEFAULT 'local',
    sync_metadata TEXT, -- JSON for sync data
    FOREIGN KEY (milestone_id) REFERENCES milestones(id) ON DELETE SET NULL
);

-- Create index for issue number lookups
CREATE INDEX IF NOT EXISTS idx_issues_number ON issues(number);
CREATE INDEX IF NOT EXISTS idx_issues_state ON issues(state);
CREATE INDEX IF NOT EXISTS idx_issues_updated_at ON issues(updated_at);
CREATE INDEX IF NOT EXISTS idx_issues_backend_id ON issues(backend_id);

-- Labels table
CREATE TABLE IF NOT EXISTS labels (
    id TEXT PRIMARY KEY,
    name TEXT UNIQUE NOT NULL,
    color TEXT,
    description TEXT,
    backend_id TEXT,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- Create index for label name lookups
CREATE INDEX IF NOT EXISTS idx_labels_name ON labels(name);

-- Issue-Label many-to-many relationship
CREATE TABLE IF NOT EXISTS issue_labels (
    issue_id TEXT NOT NULL,
    label_id TEXT NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (issue_id, label_id),
    FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE,
    FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE CASCADE
);

-- Users table
CREATE TABLE IF NOT EXISTS users (
    id TEXT PRIMARY KEY,
    username TEXT UNIQUE NOT NULL,
    display_name TEXT,
    email TEXT,
    avatar_url TEXT,
    backend_id TEXT,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- Create index for username lookups
CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);

-- Issue-User assignment many-to-many relationship
CREATE TABLE IF NOT EXISTS issue_assignees (
    issue_id TEXT NOT NULL,
    user_id TEXT NOT NULL,
    assigned_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (issue_id, user_id),
    FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

-- Milestones table
CREATE TABLE IF NOT EXISTS milestones (
    id TEXT PRIMARY KEY,
    title TEXT NOT NULL,
    description TEXT,
    state TEXT NOT NULL DEFAULT 'open' CHECK (state IN ('open', 'closed')),
    due_date TIMESTAMP,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    backend_id TEXT
);

-- Create index for milestone title lookups
CREATE INDEX IF NOT EXISTS idx_milestones_title ON milestones(title);

-- Comments table
CREATE TABLE IF NOT EXISTS comments (
    id TEXT PRIMARY KEY,
    issue_id TEXT NOT NULL,
    author_id TEXT NOT NULL,
    body TEXT NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP,
    backend_id TEXT,
    FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE,
    FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE CASCADE
);

-- Create index for comment lookups
CREATE INDEX IF NOT EXISTS idx_comments_issue_id ON comments(issue_id);
CREATE INDEX IF NOT EXISTS idx_comments_created_at ON comments(created_at);

-- Sync tracking table
CREATE TABLE IF NOT EXISTS sync_history (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    backend_type TEXT NOT NULL,
    sync_timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    success BOOLEAN NOT NULL,
    issues_synced INTEGER DEFAULT 0,
    errors_count INTEGER DEFAULT 0,
    details TEXT -- JSON for sync details
);

-- Configuration table for backend settings
CREATE TABLE IF NOT EXISTS config (
    key TEXT PRIMARY KEY,
    value TEXT NOT NULL,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- Triggers to automatically update updated_at timestamps
CREATE TRIGGER IF NOT EXISTS update_issues_timestamp
    AFTER UPDATE ON issues
BEGIN
    UPDATE issues SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
END;

CREATE TRIGGER IF NOT EXISTS update_milestones_timestamp
    AFTER UPDATE ON milestones
BEGIN
    UPDATE milestones SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
END;

-- Views for common queries
CREATE VIEW IF NOT EXISTS issue_summary AS
SELECT
    i.id,
    i.number,
    i.title,
    i.state,
    i.created_at,
    i.updated_at,
    i.closed_at,
    m.title as milestone_title,
    COUNT(c.id) as comment_count,
    GROUP_CONCAT(l.name) as labels,
    GROUP_CONCAT(u.username) as assignees
FROM issues i
LEFT JOIN milestones m ON i.milestone_id = m.id
LEFT JOIN comments c ON i.id = c.issue_id
LEFT JOIN issue_labels il ON i.id = il.issue_id
LEFT JOIN labels l ON il.label_id = l.id
LEFT JOIN issue_assignees ia ON i.id = ia.issue_id
LEFT JOIN users u ON ia.user_id = u.id
GROUP BY i.id, i.number, i.title, i.state, i.created_at, i.updated_at, i.closed_at, m.title;

-- Full-text search setup (optional - disabled for now due to compatibility issues)
-- Can be enabled later by creating FTS5 virtual table manually
-- CREATE VIRTUAL TABLE IF NOT EXISTS issue_search USING fts5(
--     issue_id UNINDEXED,
--     title,
--     description
-- );