-- Migration 017: Complete Schema from Provided Migrations
-- This migration creates all tables from the provided 001_github_integration.sql and 002_diff_storage.sql files

-- =============================================
-- Core Repository Tables
-- =============================================

-- Create table for GitHub repositories (enhanced version from provided migration)
-- Note: Table already exists from migration 001, skipping recreation
-- CREATE TABLE IF NOT EXISTS all_repositories (
--   id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
--   template_id UUID, -- References templates(id) but table may not exist
--   repository_url VARCHAR(500) NOT NULL,
--   repository_name VARCHAR(200) NOT NULL,
--   owner_name VARCHAR(100) NOT NULL,
--   provider_name VARCHAR(50) DEFAULT 'github' NOT NULL,
--   branch_name VARCHAR(100) DEFAULT 'main',
--   is_public BOOLEAN DEFAULT true,
--   requires_auth BOOLEAN DEFAULT false,
--   last_synced_at TIMESTAMP,
--   sync_status VARCHAR(50) DEFAULT 'pending',
--   metadata JSONB,
--   codebase_analysis JSONB,
--   last_synced_commit_sha VARCHAR(64),
--   created_at TIMESTAMP DEFAULT NOW(),
--   updated_at TIMESTAMP DEFAULT NOW()
-- );

-- =============================================
-- Repository File Storage Tables
-- =============================================

-- Create table for repository local storage tracking
CREATE TABLE IF NOT EXISTS repository_storage (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  repository_id UUID REFERENCES all_repositories(id) ON DELETE CASCADE,
  local_path TEXT NOT NULL,
  storage_status VARCHAR(50) DEFAULT 'pending', -- pending, downloading, completed, error
  total_files_count INTEGER DEFAULT 0,
  total_directories_count INTEGER DEFAULT 0,
  total_size_bytes BIGINT DEFAULT 0,
  download_started_at TIMESTAMP,
  download_completed_at TIMESTAMP,
  last_verified_at TIMESTAMP,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW(),
  UNIQUE(repository_id)
);

-- Create table for directory structure
CREATE TABLE IF NOT EXISTS repository_directories (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  repository_id UUID REFERENCES all_repositories(id) ON DELETE CASCADE,
  storage_id UUID REFERENCES repository_storage(id) ON DELETE CASCADE,
  parent_directory_id UUID REFERENCES repository_directories(id) ON DELETE CASCADE,
  directory_name VARCHAR(255) NOT NULL,
  relative_path TEXT NOT NULL, -- path from repository root
  absolute_path TEXT NOT NULL, -- full local filesystem path
  level INTEGER DEFAULT 0, -- depth in hierarchy (0 = root)
  files_count INTEGER DEFAULT 0,
  subdirectories_count INTEGER DEFAULT 0,
  total_size_bytes BIGINT DEFAULT 0,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- Create table for individual files
CREATE TABLE IF NOT EXISTS repository_files (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  repository_id UUID REFERENCES all_repositories(id) ON DELETE CASCADE,
  storage_id UUID REFERENCES repository_storage(id) ON DELETE CASCADE,
  directory_id UUID REFERENCES repository_directories(id) ON DELETE SET NULL,
  filename VARCHAR(255) NOT NULL,
  file_extension VARCHAR(50),
  relative_path TEXT NOT NULL, -- path from repository root
  absolute_path TEXT NOT NULL, -- full local filesystem path
  file_size_bytes BIGINT DEFAULT 0,
  file_hash VARCHAR(64), -- SHA-256 hash for integrity
  mime_type VARCHAR(100),
  is_binary BOOLEAN DEFAULT false,
  encoding VARCHAR(50) DEFAULT 'utf-8',
  github_sha VARCHAR(40), -- GitHub blob SHA for tracking changes
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- =============================================
-- Webhook Tables
-- =============================================

-- GitHub webhooks table
CREATE TABLE IF NOT EXISTS github_webhooks (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  delivery_id VARCHAR(120),
  event_type VARCHAR(100) NOT NULL,
  action VARCHAR(100),
  owner_name VARCHAR(120),
  repository_name VARCHAR(200),
  repository_id UUID REFERENCES all_repositories(id) ON DELETE SET NULL,
  ref VARCHAR(255),
  before_sha VARCHAR(64),
  after_sha VARCHAR(64),
  commit_count INTEGER,
  payload JSONB NOT NULL,
  processed_at TIMESTAMP,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- GitLab webhooks table
CREATE TABLE IF NOT EXISTS gitlab_webhooks (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  delivery_id TEXT,
  event_type TEXT NOT NULL,
  action TEXT,
  owner_name TEXT NOT NULL,
  repository_name TEXT NOT NULL,
  repository_id UUID REFERENCES all_repositories(id),
  ref TEXT,
  before_sha TEXT,
  after_sha TEXT,
  commit_count INTEGER DEFAULT 0,
  payload JSONB,
  created_at TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- Bitbucket webhooks table
CREATE TABLE IF NOT EXISTS bitbucket_webhooks (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  delivery_id TEXT,
  event_type TEXT NOT NULL,
  action TEXT,
  owner_name TEXT NOT NULL,
  repository_name TEXT NOT NULL,
  repository_id UUID REFERENCES all_repositories(id),
  ref TEXT,
  before_sha TEXT,
  after_sha TEXT,
  commit_count INTEGER DEFAULT 0,
  payload JSONB,
  created_at TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- Gitea webhooks table
CREATE TABLE IF NOT EXISTS gitea_webhooks (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  delivery_id TEXT,
  event_type TEXT NOT NULL,
  action TEXT,
  owner_name TEXT NOT NULL,
  repository_name TEXT NOT NULL,
  repository_id UUID REFERENCES all_repositories(id),
  ref TEXT,
  before_sha TEXT,
  after_sha TEXT,
  commit_count INTEGER DEFAULT 0,
  payload JSONB,
  created_at TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- =============================================
-- Commit Tracking Tables
-- =============================================

-- Per-commit details linked to an attached repository
CREATE TABLE IF NOT EXISTS repository_commit_details (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  repository_id UUID REFERENCES all_repositories(id) ON DELETE CASCADE,
  commit_sha VARCHAR(64) NOT NULL,
  author_name VARCHAR(200),
  author_email VARCHAR(320),
  message TEXT,
  url TEXT,
  committed_at TIMESTAMP DEFAULT NOW(),
  created_at TIMESTAMP DEFAULT NOW()
);

-- Per-file changes for each commit
CREATE TABLE IF NOT EXISTS repository_commit_files (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  commit_id UUID REFERENCES repository_commit_details(id) ON DELETE CASCADE,
  change_type VARCHAR(20) NOT NULL, -- added | modified | removed
  file_path TEXT NOT NULL,
  created_at TIMESTAMP DEFAULT NOW()
);

-- =============================================
-- OAuth Token Tables
-- =============================================

-- GitHub OAuth tokens
CREATE TABLE IF NOT EXISTS github_user_tokens (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  access_token TEXT NOT NULL,
  github_username VARCHAR(100) NOT NULL,
  github_user_id INTEGER NOT NULL,
  scopes JSONB,
  expires_at TIMESTAMP,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- GitLab OAuth tokens
CREATE TABLE IF NOT EXISTS gitlab_user_tokens (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  access_token TEXT NOT NULL,
  gitlab_username TEXT,
  gitlab_user_id TEXT,
  scopes JSONB,
  expires_at TIMESTAMP NULL,
  created_at TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- Bitbucket OAuth tokens
CREATE TABLE IF NOT EXISTS bitbucket_user_tokens (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  access_token TEXT NOT NULL,
  bitbucket_username TEXT,
  bitbucket_user_id TEXT,
  scopes JSONB,
  expires_at TIMESTAMP NULL,
  created_at TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- Gitea OAuth tokens
CREATE TABLE IF NOT EXISTS gitea_user_tokens (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  access_token TEXT NOT NULL,
  gitea_username TEXT,
  gitea_user_id TEXT,
  scopes JSONB,
  expires_at TIMESTAMP NULL,
  created_at TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- =============================================
-- Diff Storage Tables (from 002_diff_storage.sql)
-- =============================================

-- Store actual diff content with size-based strategy
CREATE TABLE IF NOT EXISTS diff_contents (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  commit_id UUID REFERENCES repository_commit_details(id) ON DELETE CASCADE,
  file_change_id UUID REFERENCES repository_commit_files(id) ON DELETE CASCADE,
  
  -- Diff metadata
  diff_header TEXT, -- "diff --git a/file.py b/file.py"
  diff_size_bytes INTEGER NOT NULL,
  
  -- Storage strategy based on size
  storage_type VARCHAR(20) NOT NULL, -- 'external' (all diffs stored on disk)
  
  -- Store reference only (path on disk)
  external_storage_path TEXT NOT NULL,
  external_storage_provider VARCHAR(50) DEFAULT 'local', -- 'local', 's3', 'gcs'
  
  -- File information
  file_path TEXT NOT NULL,
  change_type VARCHAR(20) NOT NULL, -- 'added', 'modified', 'deleted', 'renamed'
  
  -- Processing status
  processing_status VARCHAR(20) DEFAULT 'pending', -- 'pending', 'processed', 'failed'
  processing_error TEXT,
  
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- Diff Processing Queue (for background processing)
CREATE TABLE IF NOT EXISTS diff_processing_queue (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  commit_id UUID REFERENCES repository_commit_details(id) ON DELETE CASCADE,
  repository_id UUID REFERENCES all_repositories(id) ON DELETE CASCADE,
  
  -- Processing metadata
  queue_status VARCHAR(20) DEFAULT 'pending', -- 'pending', 'processing', 'completed', 'failed'
  priority INTEGER DEFAULT 0, -- Higher number = higher priority
  retry_count INTEGER DEFAULT 0,
  max_retries INTEGER DEFAULT 3,
  
  -- Git diff parameters
  from_sha VARCHAR(64),
  to_sha VARCHAR(64),
  repo_local_path TEXT NOT NULL,
  
  -- Processing results
  processed_at TIMESTAMP,
  error_message TEXT,
  
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- Diff Statistics (for monitoring and optimization)
CREATE TABLE IF NOT EXISTS diff_statistics (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  repository_id UUID REFERENCES all_repositories(id) ON DELETE CASCADE,
  
  -- Statistics period
  period_start TIMESTAMP NOT NULL,
  period_end TIMESTAMP NOT NULL,
  
  -- Count statistics
  total_commits INTEGER DEFAULT 0,
  total_files_changed INTEGER DEFAULT 0,
  total_diffs_processed INTEGER DEFAULT 0,
  
  -- Size statistics
  total_diff_size_bytes BIGINT DEFAULT 0,
  avg_diff_size_bytes DECIMAL(10,2) DEFAULT 0,
  max_diff_size_bytes BIGINT DEFAULT 0,
  
  -- Storage type breakdown
  diffs_stored_external INTEGER DEFAULT 0,
  
  -- Performance metrics
  avg_processing_time_ms DECIMAL(10,2) DEFAULT 0,
  failed_processing_count INTEGER DEFAULT 0,
  
  created_at TIMESTAMP DEFAULT NOW()
);

-- =============================================
-- Indexes for Performance
-- =============================================

-- GitHub repositories indexes (commented out - template_id column was removed)
-- CREATE INDEX IF NOT EXISTS idx_github_repos_template_id ON all_repositories(template_id);
CREATE INDEX IF NOT EXISTS idx_github_repos_owner_name ON all_repositories(owner_name);
CREATE INDEX IF NOT EXISTS idx_all_repos_provider_name ON all_repositories(provider_name);

-- Repository storage indexes
CREATE INDEX IF NOT EXISTS idx_repository_storage_repo_id ON repository_storage(repository_id);
CREATE INDEX IF NOT EXISTS idx_repository_storage_status ON repository_storage(storage_status);

-- Repository directories indexes
CREATE INDEX IF NOT EXISTS idx_repo_directories_repo_id ON repository_directories(repository_id);
CREATE INDEX IF NOT EXISTS idx_repo_directories_parent_id ON repository_directories(parent_directory_id);
CREATE INDEX IF NOT EXISTS idx_repo_directories_storage_id ON repository_directories(storage_id);
CREATE INDEX IF NOT EXISTS idx_repo_directories_level ON repository_directories(level);
CREATE INDEX IF NOT EXISTS idx_repo_directories_relative_path ON repository_directories(relative_path);

-- Repository files indexes
-- Note: The repository_files table has been optimized in migration 003_optimize_repository_files.sql
-- The following indexes are already created in the optimized table structure:
-- - idx_repo_files_repo_id (B-tree index on repository_id)
-- - idx_repo_files_directory_id (B-tree index on directory_id) 
-- - idx_repo_files_storage_id (B-tree index on storage_id)
-- - idx_repo_files_relative_path (B-tree index on relative_path)
-- - idx_repo_files_files_gin (GIN index on files JSONB column)
-- - idx_repo_files_filename (GIN index on files->>'filename')
-- - idx_repo_files_extension (GIN index on files->>'file_extension')
-- - idx_repo_files_is_binary (GIN index on files->>'is_binary')

-- GitHub webhooks indexes
CREATE INDEX IF NOT EXISTS idx_github_webhooks_delivery_id ON github_webhooks(delivery_id);
CREATE INDEX IF NOT EXISTS idx_github_webhooks_repo ON github_webhooks(owner_name, repository_name);
CREATE INDEX IF NOT EXISTS idx_github_webhooks_event_type ON github_webhooks(event_type);

-- GitLab webhooks indexes
CREATE INDEX IF NOT EXISTS idx_gitlab_webhooks_repository_id ON gitlab_webhooks(repository_id);
CREATE INDEX IF NOT EXISTS idx_gitlab_webhooks_created_at ON gitlab_webhooks(created_at);
CREATE INDEX IF NOT EXISTS idx_gitlab_webhooks_event_type ON gitlab_webhooks(event_type);

-- Bitbucket webhooks indexes
CREATE INDEX IF NOT EXISTS idx_bitbucket_webhooks_repository_id ON bitbucket_webhooks(repository_id);
CREATE INDEX IF NOT EXISTS idx_bitbucket_webhooks_created_at ON bitbucket_webhooks(created_at);
CREATE INDEX IF NOT EXISTS idx_bitbucket_webhooks_event_type ON bitbucket_webhooks(event_type);

-- Gitea webhooks indexes
CREATE INDEX IF NOT EXISTS idx_gitea_webhooks_repository_id ON gitea_webhooks(repository_id);
CREATE INDEX IF NOT EXISTS idx_gitea_webhooks_created_at ON gitea_webhooks(created_at);
CREATE INDEX IF NOT EXISTS idx_gitea_webhooks_event_type ON gitea_webhooks(event_type);

-- Commit details indexes
CREATE UNIQUE INDEX IF NOT EXISTS uq_repo_commit_sha ON repository_commit_details(repository_id, commit_sha);
CREATE INDEX IF NOT EXISTS idx_repo_commit_created_at ON repository_commit_details(created_at);

-- Commit files indexes
CREATE INDEX IF NOT EXISTS idx_commit_files_commit_id ON repository_commit_files(commit_id);
CREATE INDEX IF NOT EXISTS idx_commit_files_path ON repository_commit_files(file_path);

-- OAuth token indexes
CREATE INDEX IF NOT EXISTS idx_github_user_tokens_github_username ON github_user_tokens(github_username);

-- Diff contents indexes
CREATE INDEX IF NOT EXISTS idx_diff_contents_commit_id ON diff_contents(commit_id);
CREATE INDEX IF NOT EXISTS idx_diff_contents_file_change_id ON diff_contents(file_change_id);
CREATE INDEX IF NOT EXISTS idx_diff_contents_storage_type ON diff_contents(storage_type);
CREATE INDEX IF NOT EXISTS idx_diff_contents_file_path ON diff_contents(file_path);
CREATE INDEX IF NOT EXISTS idx_diff_contents_change_type ON diff_contents(change_type);
CREATE INDEX IF NOT EXISTS idx_diff_contents_processing_status ON diff_contents(processing_status);
CREATE INDEX IF NOT EXISTS idx_diff_contents_created_at ON diff_contents(created_at);

-- Processing queue indexes
CREATE INDEX IF NOT EXISTS idx_diff_queue_status ON diff_processing_queue(queue_status);
CREATE INDEX IF NOT EXISTS idx_diff_queue_priority ON diff_processing_queue(priority DESC);
CREATE INDEX IF NOT EXISTS idx_diff_queue_repository_id ON diff_processing_queue(repository_id);
CREATE INDEX IF NOT EXISTS idx_diff_queue_created_at ON diff_processing_queue(created_at);

-- Statistics indexes
CREATE INDEX IF NOT EXISTS idx_diff_stats_repository_id ON diff_statistics(repository_id);
CREATE INDEX IF NOT EXISTS idx_diff_stats_period ON diff_statistics(period_start, period_end);

-- =============================================
-- Triggers for Updated At Columns
-- =============================================

-- Create update function if it doesn't exist
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ language 'plpgsql';

-- GitHub repositories trigger
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_trigger WHERE tgname = 'update_github_repos_updated_at'
  ) THEN
    CREATE TRIGGER update_github_repos_updated_at BEFORE UPDATE ON all_repositories
      FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
  END IF;
END $$;

-- Repository storage trigger
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_trigger WHERE tgname = 'update_repository_storage_updated_at'
  ) THEN
    CREATE TRIGGER update_repository_storage_updated_at BEFORE UPDATE ON repository_storage
      FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
  END IF;
END $$;

-- Repository directories trigger
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_trigger WHERE tgname = 'update_repository_directories_updated_at'
  ) THEN
    CREATE TRIGGER update_repository_directories_updated_at BEFORE UPDATE ON repository_directories
      FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
  END IF;
END $$;

-- Repository files trigger
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_trigger WHERE tgname = 'update_repository_files_updated_at'
  ) THEN
    CREATE TRIGGER update_repository_files_updated_at BEFORE UPDATE ON repository_files
      FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
  END IF;
END $$;

-- GitHub webhooks trigger
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_trigger WHERE tgname = 'update_github_webhooks_updated_at'
  ) THEN
    CREATE TRIGGER update_github_webhooks_updated_at BEFORE UPDATE ON github_webhooks
      FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
  END IF;
END $$;

-- GitLab user tokens trigger
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_trigger WHERE tgname = 'update_gitlab_user_tokens_updated_at'
  ) THEN
    CREATE TRIGGER update_gitlab_user_tokens_updated_at BEFORE UPDATE ON gitlab_user_tokens
      FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
  END IF;
END $$;

-- Bitbucket user tokens trigger
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_trigger WHERE tgname = 'update_bitbucket_user_tokens_updated_at'
  ) THEN
    CREATE TRIGGER update_bitbucket_user_tokens_updated_at BEFORE UPDATE ON bitbucket_user_tokens
      FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
  END IF;
END $$;

-- Gitea user tokens trigger
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_trigger WHERE tgname = 'update_gitea_user_tokens_updated_at'
  ) THEN
    CREATE TRIGGER update_gitea_user_tokens_updated_at BEFORE UPDATE ON gitea_user_tokens
      FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
  END IF;
END $$;

-- Diff contents trigger
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_trigger WHERE tgname = 'update_diff_contents_updated_at'
  ) THEN
    CREATE TRIGGER update_diff_contents_updated_at BEFORE UPDATE ON diff_contents
      FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
  END IF;
END $$;

-- Processing queue trigger
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_trigger WHERE tgname = 'update_diff_queue_updated_at'
  ) THEN
    CREATE TRIGGER update_diff_queue_updated_at BEFORE UPDATE ON diff_processing_queue
      FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
  END IF;
END $$;

-- =============================================
-- Helper Functions
-- =============================================

-- Function to get diff storage statistics for a repository
CREATE OR REPLACE FUNCTION get_repository_diff_stats(repo_id UUID, days_back INTEGER DEFAULT 30)
RETURNS TABLE (
  total_diffs BIGINT,
  total_size_bytes BIGINT,
  avg_size_bytes DECIMAL(10,2),
  storage_breakdown JSONB
) AS $$
BEGIN
  RETURN QUERY
  SELECT 
    COUNT(*)::BIGINT as total_diffs,
    COALESCE(SUM(dc.diff_size_bytes), 0)::BIGINT as total_size_bytes,
    COALESCE(AVG(dc.diff_size_bytes), 0)::DECIMAL(10,2) as avg_size_bytes,
    jsonb_build_object(
      'external', COUNT(*) FILTER (WHERE dc.storage_type = 'external')
    ) as storage_breakdown
  FROM diff_contents dc
  JOIN repository_commit_details rcd ON dc.commit_id = rcd.id
  WHERE rcd.repository_id = repo_id
    AND dc.created_at >= NOW() - INTERVAL '1 day' * days_back;
END;
$$ LANGUAGE plpgsql;

-- Function to clean up old diff processing queue entries
CREATE OR REPLACE FUNCTION cleanup_old_diff_queue_entries(days_back INTEGER DEFAULT 7)
RETURNS INTEGER AS $$
DECLARE
  deleted_count INTEGER;
BEGIN
  DELETE FROM diff_processing_queue 
  WHERE created_at < NOW() - INTERVAL '1 day' * days_back
    AND queue_status IN ('completed', 'failed');
  
  GET DIAGNOSTICS deleted_count = ROW_COUNT;
  RETURN deleted_count;
END;
$$ LANGUAGE plpgsql;
