import type { SQLiteDatabase } from 'expo-sqlite';
import {
  CREATE_MESSAGES_TABLE,
  CREATE_MESSAGES_INDEXES,
  MIGRATE_MESSAGES_TABLE,
} from './MessageSchema';
import {
  CREATE_CONVERSATIONS_TABLE,
  CREATE_CONVERSATION_CACHE_TABLE,
  CREATE_CONVERSATION_LIST_CACHE_TABLE,
  MIGRATE_CONVERSATIONS_TABLE,
} from './ConversationSchema';
import {
  CREATE_USERS_TABLE,
  CREATE_CURRENT_USER_CACHE_TABLE,
} from './UserSchema';
import {
  CREATE_GROUPS_TABLE,
  CREATE_GROUP_MEMBERS_TABLE,
  CREATE_GROUP_INDEXES,
} from './GroupSchema';
import {
  CREATE_POSTS_CACHE_TABLE,
} from './PostSchema';

async function execWithRetry(db: SQLiteDatabase, sql: string, maxRetries = 5): Promise<void> {
  for (let i = 0; i < maxRetries; i++) {
    try {
      await db.execAsync(sql);
      return;
    } catch (error) {
      const msg = String(error);
      if (msg.includes('database is locked') && i < maxRetries - 1) {
        const delay = 200 * (i + 1);
        console.warn(`[MigrationManager] 数据库锁定，${delay}ms 后重试 (${i + 1}/${maxRetries})`);
        await new Promise(r => setTimeout(r, delay));
        continue;
      }
      throw error;
    }
  }
}

export async function runMigrations(db: SQLiteDatabase): Promise<void> {
  await execWithRetry(db, 'PRAGMA busy_timeout = 10000;');
  
  await execWithRetry(db, CREATE_MESSAGES_TABLE);
  await execWithRetry(db, CREATE_CONVERSATIONS_TABLE);
  await execWithRetry(db, CREATE_CONVERSATION_CACHE_TABLE);
  await execWithRetry(db, CREATE_CONVERSATION_LIST_CACHE_TABLE);
  await execWithRetry(db, CREATE_USERS_TABLE);
  await execWithRetry(db, CREATE_CURRENT_USER_CACHE_TABLE);
  await execWithRetry(db, CREATE_GROUPS_TABLE);
  await execWithRetry(db, CREATE_GROUP_MEMBERS_TABLE);
  await execWithRetry(db, CREATE_POSTS_CACHE_TABLE);

  for (const indexSql of CREATE_MESSAGES_INDEXES) {
    await execWithRetry(db, indexSql);
  }
  for (const indexSql of CREATE_GROUP_INDEXES) {
    await execWithRetry(db, indexSql);
  }

  await MIGRATE_MESSAGES_TABLE(db);
  await MIGRATE_CONVERSATIONS_TABLE(db);
}