package com.durian.tssparty.di

import android.content.Context
import androidx.room.Room
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.durian.tssparty.data.local.AppSettingDao
import com.durian.tssparty.data.local.ShareRecordDao
import com.durian.tssparty.data.local.TransactionRecordDao
import com.durian.tssparty.data.local.TssDatabase
import com.durian.tssparty.data.local.TssNativeBridge
import com.durian.tssparty.data.remote.GrpcClient
import com.durian.tssparty.data.repository.TssRepository
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

    // Migration from version 1 to 2: add app_settings table
    private val MIGRATION_1_2 = object : Migration(1, 2) {
        override fun migrate(database: SupportSQLiteDatabase) {
            database.execSQL(
                "CREATE TABLE IF NOT EXISTS `app_settings` (" +
                "`key` TEXT NOT NULL PRIMARY KEY, " +
                "`value` TEXT NOT NULL)"
            )
        }
    }

    // Migration from version 2 to 3: add party_id column to share_records
    // This is critical for backup/restore - the partyId must be preserved for signing to work
    private val MIGRATION_2_3 = object : Migration(2, 3) {
        override fun migrate(database: SupportSQLiteDatabase) {
            // Add party_id column with empty default (existing records will need to be re-exported)
            database.execSQL(
                "ALTER TABLE `share_records` ADD COLUMN `party_id` TEXT NOT NULL DEFAULT ''"
            )
        }
    }

    // Migration from version 3 to 4: add transaction_records table for transfer history
    // 添加转账记录表，用于存储交易历史和分类账
    private val MIGRATION_3_4 = object : Migration(3, 4) {
        override fun migrate(database: SupportSQLiteDatabase) {
            // 创建转账记录表
            database.execSQL("""
                CREATE TABLE IF NOT EXISTS `transaction_records` (
                    `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
                    `share_id` INTEGER NOT NULL,
                    `from_address` TEXT NOT NULL,
                    `to_address` TEXT NOT NULL,
                    `amount` TEXT NOT NULL,
                    `token_type` TEXT NOT NULL,
                    `tx_hash` TEXT NOT NULL,
                    `gas_price` TEXT NOT NULL,
                    `gas_used` TEXT NOT NULL DEFAULT '',
                    `tx_fee` TEXT NOT NULL DEFAULT '',
                    `status` TEXT NOT NULL,
                    `direction` TEXT NOT NULL,
                    `note` TEXT NOT NULL DEFAULT '',
                    `created_at` INTEGER NOT NULL,
                    `confirmed_at` INTEGER,
                    `block_number` INTEGER,
                    FOREIGN KEY(`share_id`) REFERENCES `share_records`(`id`) ON DELETE CASCADE
                )
            """.trimIndent())

            // 创建索引以优化查询性能
            database.execSQL("CREATE INDEX IF NOT EXISTS `index_transaction_records_share_id` ON `transaction_records` (`share_id`)")
            database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_transaction_records_tx_hash` ON `transaction_records` (`tx_hash`)")
            database.execSQL("CREATE INDEX IF NOT EXISTS `index_transaction_records_from_address` ON `transaction_records` (`from_address`)")
            database.execSQL("CREATE INDEX IF NOT EXISTS `index_transaction_records_to_address` ON `transaction_records` (`to_address`)")
            database.execSQL("CREATE INDEX IF NOT EXISTS `index_transaction_records_created_at` ON `transaction_records` (`created_at`)")
        }
    }

    @Provides
    @Singleton
    fun provideGson(): Gson {
        return GsonBuilder().create()
    }

    @Provides
    @Singleton
    fun provideDatabase(@ApplicationContext context: Context): TssDatabase {
        return Room.databaseBuilder(
            context,
            TssDatabase::class.java,
            "tss_party.db"
        )
            .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4)
            .build()
    }

    @Provides
    @Singleton
    fun provideShareRecordDao(database: TssDatabase): ShareRecordDao {
        return database.shareRecordDao()
    }

    @Provides
    @Singleton
    fun provideAppSettingDao(database: TssDatabase): AppSettingDao {
        return database.appSettingDao()
    }

    @Provides
    @Singleton
    fun provideTransactionRecordDao(database: TssDatabase): TransactionRecordDao {
        return database.transactionRecordDao()
    }

    @Provides
    @Singleton
    fun provideGrpcClient(): GrpcClient {
        return GrpcClient()
    }

    @Provides
    @Singleton
    fun provideTssNativeBridge(gson: Gson): TssNativeBridge {
        return TssNativeBridge(gson)
    }

    @Provides
    @Singleton
    fun provideTssRepository(
        grpcClient: GrpcClient,
        tssNativeBridge: TssNativeBridge,
        shareRecordDao: ShareRecordDao,
        appSettingDao: AppSettingDao,
        transactionRecordDao: TransactionRecordDao
    ): TssRepository {
        return TssRepository(grpcClient, tssNativeBridge, shareRecordDao, appSettingDao, transactionRecordDao)
    }
}
