package com.all.pdfreader.pro.app.viewmodel

import android.content.Context
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.all.pdfreader.pro.app.PRApp
import com.all.pdfreader.pro.app.model.DeleteResult
import com.all.pdfreader.pro.app.model.FileActionEvent
import com.all.pdfreader.pro.app.room.entity.BookmarkEntity
import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
import com.all.pdfreader.pro.app.room.repository.PdfRepository
import com.all.pdfreader.pro.app.util.AppUtils.generateFastThumbnail
import com.all.pdfreader.pro.app.util.FileDeleteUtil
import com.all.pdfreader.pro.app.util.FileUtils
import com.all.pdfreader.pro.app.util.FileUtils.isPdfEncrypted
import com.all.pdfreader.pro.app.util.PdfMetadataExtractor
import com.all.pdfreader.pro.app.util.PdfSecurityUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File

class PdfViewModel : ViewModel() {
    private val pdfRepository = PdfRepository.getInstance()

    private val _pdfDocument = MutableLiveData<PdfDocumentEntity?>()
    val pdfDocument: LiveData<PdfDocumentEntity?> = _pdfDocument

    // 用于操作结果或通知UI
    private val _fileActionEvent = MutableLiveData<FileActionEvent>()
    val fileActionEvent: LiveData<FileActionEvent> = _fileActionEvent

    fun getPDFDocument(filePath: String) {
        viewModelScope.launch {
            val document = pdfRepository.getDocumentByPath(filePath)
            Log.d("ocean", "getPDFDocument->loadPdf: filePath=$filePath, document=$document")
            _pdfDocument.postValue(document)
        }
    }

    //触发修改文件名操作
    fun renamePdf(filePath: String, newName: String) {
        viewModelScope.launch(Dispatchers.IO) {
            val oldFile = File(filePath)
            val renameResult = FileUtils.renameFile(oldFile, newName)
            Log.d(
                "ocean",
                "renamePdf->oldFile: $oldFile, newName=$newName, renameResult=$renameResult"
            )
            if (renameResult.success) {//修改成功更新数据库
                val finalName = if (newName.contains('.')) {
                    // 用户提供了后缀，使用用户的
                    newName
                } else {
                    // 用户没有提供后缀，自动添加原文件后缀
                    val originalExtension = File(filePath).extension
                    if (originalExtension.isNotEmpty()) {
                        "$newName.$originalExtension"
                    } else {
                        newName
                    }
                }
                val parentDir = oldFile.parentFile
                val newFilePath = File(parentDir, finalName).absolutePath.toString()
                Log.d("ocean", "renamePdf->newFilePath: $newFilePath, finalName=$finalName")
                pdfRepository.updateFilePathAndFileName(filePath, newFilePath, finalName)
                val newResult = renameResult.copy(newFilePath = newFilePath)
                _fileActionEvent.postValue(FileActionEvent.Rename(newResult))
            } else {
                _fileActionEvent.postValue(FileActionEvent.Rename(renameResult))
            }
        }
    }

    fun deleteFile(filePath: String) {
        viewModelScope.launch(Dispatchers.IO) {
            val file = File(filePath)
            val deleteResult = FileDeleteUtil.deleteFile(file)
            Log.d("ocean", "deleteFile->file: $file, deleteResult=$deleteResult")
            if (deleteResult.success) {
                Log.d("ocean", "文件已删除，清除数据库数据")
                pdfRepository.deleteDocument(filePath)
            }
            _fileActionEvent.postValue(FileActionEvent.Delete(deleteResult))
        }
    }

    fun deleteFiles(files: List<File>) {
        viewModelScope.launch {
            _fileActionEvent.postValue(FileActionEvent.DeleteAll(FileActionEvent.DeleteAll.Status.START))
            val deleteResult = withContext(Dispatchers.IO) {
                try {
                    val result = FileDeleteUtil.deleteFiles(files)
                    if (result.success) {
                        // 批量清理数据库
                        val paths = files.map { it.absolutePath }
                        pdfRepository.deleteDocuments(paths)
                    }
                    result
                } catch (e: Exception) {
                    DeleteResult.failure(e.message ?: "Unknown error")
                }
            }
            _fileActionEvent.postValue(
                FileActionEvent.DeleteAll(
                    FileActionEvent.DeleteAll.Status.COMPLETE, deleteResult
                )
            )
        }
    }

    fun saveCollectState(filePath: String, isFavorite: Boolean) {
        viewModelScope.launch {
            pdfRepository.updateFavoriteStatus(filePath, isFavorite)
            _fileActionEvent.postValue(FileActionEvent.Favorite(isFavorite))
        }
    }

    fun cancelCollectState(filePaths: List<String>) {
        viewModelScope.launch {
            pdfRepository.cancelFavorites(filePaths)
            _fileActionEvent.postValue(FileActionEvent.Favorite(false))
        }
    }

    fun duplicateFile(context: Context, filePath: String) {
        viewModelScope.launch(Dispatchers.IO) {
            val file = FileUtils.duplicateFile(File(filePath))
            Log.d("ocean", "duplicateFile->$file")
            if (file != null) {
                val isPassword = isPdfEncrypted(file)
                val metadata = PdfMetadataExtractor.extractMetadata(file.absolutePath)
                val document = PdfDocumentEntity(
                    filePath = file.absolutePath,
                    fileName = file.name,
                    fileSize = file.length(),
                    lastModified = file.lastModified(),
                    pageCount = metadata?.pageCount ?: 0,
                    thumbnailPath = null,
                    metadataTitle = metadata?.title,
                    metadataAuthor = metadata?.author,
                    metadataSubject = metadata?.subject,
                    metadataKeywords = metadata?.keywords,
                    metadataCreationDate = metadata?.creationDate?.time,
                    metadataModificationDate = metadata?.modificationDate?.time,
                    isPassword = isPassword
                )
                pdfRepository.insertOrUpdateDocument(document)
                Log.d("ocean", "✅ 已保存到数据库: ${file.name}")
                if (!isPassword) {//没有密码的情况下才去获取缩略图
                    launch(Dispatchers.IO) {
                        val newThumbnail = generateFastThumbnail(context, file)
                        if (newThumbnail != null && document.thumbnailPath != newThumbnail) {
                            pdfRepository.updateThumbnailPath(
                                document.filePath, newThumbnail
                            )
                            Log.d("ocean", "✅ 缩略图已更新")
                        }
                    }
                }
            }
            _fileActionEvent.postValue(FileActionEvent.Duplicate(file))
        }
    }

    fun setPassword(filePath: String, password: String) {
        viewModelScope.launch {
            // 发送 START 事件，UI 显示进度框
            _fileActionEvent.postValue(FileActionEvent.SetPassword(FileActionEvent.SetPassword.Status.START))

            val success = withContext(Dispatchers.IO) {
                PdfSecurityUtils.setPasswordToPdf(filePath, password, password).also {
                    if (it) {
                        pdfRepository.updateIsPassword(filePath, true)
                    }
                }
            }
            _fileActionEvent.postValue(
                FileActionEvent.SetPassword(
                    FileActionEvent.SetPassword.Status.COMPLETE, success
                )
            )
        }
    }

    fun removePassword(filePath: String, password: String) {
        viewModelScope.launch {
            _fileActionEvent.postValue(FileActionEvent.RemovePassword(FileActionEvent.RemovePassword.Status.START))

            val success = try {
                withContext(Dispatchers.IO) {
                    val removed = PdfSecurityUtils.removePasswordFromPdf(filePath, password)
                    Log.d("ocean", "密码移除$removed")
                    if (removed) {
                        pdfRepository.updateIsPassword(filePath, false)
                        val document = pdfRepository.getDocumentByPath(filePath)
                        if (document?.thumbnailPath.isNullOrEmpty()) {
                            val newThumbnail =
                                generateFastThumbnail(PRApp.getContext(), File(filePath))
                            Log.d("ocean", "最新图片：$newThumbnail")
                            if (!newThumbnail.isNullOrEmpty() && filePath != newThumbnail) {
                                pdfRepository.updateThumbnailPath(filePath, newThumbnail)
                            }
                        }
                    }
                    removed // 这里直接返回移除密码的结果
                }
            } catch (e: Exception) {
                Log.e("ocean", "removePassword 失败", e)
                false
            }

            _fileActionEvent.postValue(
                FileActionEvent.RemovePassword(
                    FileActionEvent.RemovePassword.Status.COMPLETE, success
                )
            )
        }
    }

    fun noticeReloadPdf() {
        viewModelScope.launch {
            _fileActionEvent.postValue(FileActionEvent.NoticeReload)
        }
    }

    fun setColorInversion(b: Boolean) {
        viewModelScope.launch {
            _fileActionEvent.postValue(FileActionEvent.SetColorInversion(b))
        }
    }

    fun setSwipeVertical(b: Boolean) {
        viewModelScope.launch {
            _fileActionEvent.postValue(FileActionEvent.SetSwipeVertical(b))
        }
    }

    fun setPageFling(b: Boolean) {
        viewModelScope.launch {
            _fileActionEvent.postValue(FileActionEvent.SetPageFling(b))
        }
    }

    fun gotoPage(number: Int) {
        viewModelScope.launch {
            _fileActionEvent.postValue(FileActionEvent.GotoPage(number))
        }
    }

    fun removeRecent(filePath: String) {
        viewModelScope.launch {
            pdfRepository.updateLastOpenTime(filePath)
        }
    }

    fun removeRecentAll(filePaths: List<String>) {
        viewModelScope.launch {
            pdfRepository.updateLastOpenTimes(filePaths)
        }
    }

    /**
     * 书签相关方法
     */
    private val _pdfBookmark = MutableLiveData<List<BookmarkEntity>>()
    val pdfBookmark: LiveData<List<BookmarkEntity>> = _pdfBookmark

    fun getBookmarks(filePath: String) {
        viewModelScope.launch {
            Log.d("ocean", "getBookmarks->filePath: $filePath")
            pdfRepository.getBookmarksByPdf(filePath).distinctUntilChanged().collect { bookmarks ->
                _pdfBookmark.value = bookmarks
            }
        }
    }

    fun addBookMark(bookmark: BookmarkEntity) {
        viewModelScope.launch {
            Log.d("ocean", "addBookMarks->bookmark: $bookmark")
            val id = pdfRepository.addBookmark(bookmark)
            val success = id != -1L//插入成功，会返回 新生成的主键 id
            _fileActionEvent.postValue(FileActionEvent.AddBookmark(success))
        }
    }

    fun updateBookmark(bookmark: BookmarkEntity) {
        viewModelScope.launch {
            val int = pdfRepository.updateBookmark(bookmark)
            val success = int > 0
            Log.d("ocean", "updateBookmark->success: $success")
            _fileActionEvent.postValue(FileActionEvent.UpdateBookmark(success))
        }
    }

    fun deleteBookMark(bookmark: BookmarkEntity) {
        viewModelScope.launch {
            val int = pdfRepository.deleteBookmark(bookmark)
            val success = int > 0//受影响行数大于0
            Log.d("ocean", "deleteBookmark->success: $success")
            _fileActionEvent.postValue(FileActionEvent.DeleteBookmark(success))
        }
    }

    fun deleteAllBookmark(filePath: String) {
        viewModelScope.launch {
            val int = pdfRepository.deleteAllBookmark(filePath)
            val success = int > 0
            Log.d("ocean", "deleteAllBookmark->success: $success")
            _fileActionEvent.postValue(FileActionEvent.DeleteAllBookmark(success))
        }
    }
}