package com.aletheia.app.data

import android.net.Uri
import com.aletheia.app.model.Book
import com.aletheia.app.model.ReadingBookmark
import com.aletheia.app.model.ReadingNote
import com.aletheia.app.model.ReadingProgress
import java.io.File
import java.io.IOException

class BookRepository(
    private val databaseHelper: AppDatabaseHelper,
    private val parserService: BookParserService,
    private val settingsRepository: SettingsRepository
) {
    fun getAllBooks(query: String? = null): List<Book> {
        val books = databaseHelper.getAllBooks()
        val search = query?.trim()?.lowercase().orEmpty()
        if (search.isBlank()) {
            return books
        }

        return books.filter { book ->
            book.title.lowercase().contains(search) || book.author.lowercase().contains(search)
        }
    }

    fun getBookById(id: Long): Book? = databaseHelper.getBookById(id)

    fun getBookByRemoteId(remoteId: String): Book? =
        databaseHelper.getAllBooks().firstOrNull { it.remoteId == remoteId }

    fun importBook(uri: Uri): Book {
        val book = parserService.parseAndStoreBookFromUri(uri)
        val id = databaseHelper.saveBook(book)
        return requireNotNull(databaseHelper.getBookById(id))
    }

    fun importDownloadedBook(file: File, originalFileName: String, remoteId: String?, coverImage: ByteArray?): Book {
        val parsedBook = parserService.parseAndStoreBook(file, originalFileName)
        val book = parsedBook.copy(remoteId = remoteId, coverImage = coverImage ?: parsedBook.coverImage)
        val id = databaseHelper.saveBook(book)
        return requireNotNull(databaseHelper.getBookById(id))
    }

    fun deleteBook(book: Book) {
        val booksDirectory = parserService.getBooksDirectory().canonicalFile
        val bookFile = File(book.filePath).canonicalFile
        val isStoredBook = bookFile.parentFile == booksDirectory
        require(isStoredBook) {
            "Файл книги находится вне внутренней папки библиотеки."
        }
        if (bookFile.exists() && !bookFile.delete()) {
            throw IOException("Не удалось удалить скачанный файл книги.")
        }
        databaseHelper.deleteBook(book)
    }

    fun updateBook(book: Book) {
        databaseHelper.saveBook(book)
    }

    fun saveLocations(bookId: Long, locations: String) {
        val book = getBookById(bookId) ?: return
        updateBook(book.copy(locations = locations))
    }

    fun saveProgress(
        bookId: Long,
        progress: Double,
        cfi: String?,
        chapter: String?,
        currentPage: Int,
        totalPages: Int
    ) {
        val book = getBookById(bookId) ?: return
        val updated = book.copy(
            readingProgress = progress,
            lastCfi = cfi,
            lastChapter = chapter,
            currentPage = currentPage,
            totalPages = totalPages,
            lastRead = System.currentTimeMillis()
        )
        updateBook(updated)
        databaseHelper.saveProgress(
            ReadingProgress(
                bookId = bookId,
                cfi = cfi,
                progress = progress,
                currentPage = currentPage,
                chapterTitle = chapter
            )
        )
    }

    fun getBookmarks(bookId: Long): List<ReadingBookmark> =
        databaseHelper.getBookmarks(bookId)

    fun addBookmark(
        bookId: Long,
        cfi: String?,
        progress: Double,
        currentPage: Int,
        totalPages: Int,
        chapter: String?,
        label: String
    ): ReadingBookmark {
        val bookmark = ReadingBookmark(
            bookId = bookId,
            cfi = cfi,
            progress = progress,
            currentPage = currentPage,
            totalPages = totalPages,
            chapterTitle = chapter,
            label = label
        )
        val id = databaseHelper.saveBookmark(bookmark)
        return bookmark.copy(id = id)
    }

    fun deleteBookmark(bookmark: ReadingBookmark) {
        databaseHelper.deleteBookmark(bookmark.id)
    }

    fun getNotes(bookId: Long): List<ReadingNote> =
        databaseHelper.getNotes(bookId)

    fun addNote(
        bookId: Long,
        cfi: String?,
        progress: Double,
        currentPage: Int,
        totalPages: Int,
        chapter: String?,
        selectedText: String?,
        noteText: String,
        highlightColor: String? = null,
        kind: String = ReadingNote.KIND_NOTE
    ): ReadingNote {
        val note = ReadingNote(
            bookId = bookId,
            cfi = cfi,
            progress = progress,
            currentPage = currentPage,
            totalPages = totalPages,
            chapterTitle = chapter,
            selectedText = selectedText,
            noteText = noteText,
            highlightColor = highlightColor,
            kind = kind
        )
        val id = databaseHelper.saveNote(note)
        return note.copy(id = id)
    }

    fun deleteNote(note: ReadingNote) {
        databaseHelper.deleteNote(note.id)
    }

    fun getDefaultFontSize(): Int =
        settingsRepository.getInt(SettingsRepository.KEY_DEFAULT_FONT_SIZE, 20)

    fun getDefaultFontFamily(): String =
        settingsRepository.getString(SettingsRepository.KEY_DEFAULT_FONT_FAMILY, "serif")

    fun getDefaultTheme(): String =
        settingsRepository.getString(SettingsRepository.KEY_THEME, "light")

    fun getDefaultBrightness(): Double =
        settingsRepository.getDouble(SettingsRepository.KEY_BRIGHTNESS, 100.0)
}
