package com.aletheia.app.data

import android.content.Context
import com.aletheia.app.model.AudioBook
import com.aletheia.app.model.Book
import java.io.File

class AudioBookRepository(
    context: Context,
    private val databaseHelper: AppDatabaseHelper
) {
    private val outputDirectory = File(context.cacheDir, "audiobooks").apply { mkdirs() }

    fun getAll(): List<AudioBook> = databaseHelper.getAllAudioBooks().map(::reconcileFile)

    fun getById(id: Long): AudioBook? = databaseHelper.getAudioBookById(id)?.let(::reconcileFile)

    fun getBySourceBookId(bookId: Long): AudioBook? =
        databaseHelper.getAudioBookBySourceBookId(bookId)?.let(::reconcileFile)

    fun createOrReset(book: Book): AudioBook {
        val existing = databaseHelper.getAudioBookBySourceBookId(book.id)
        existing?.filePath?.takeIf(String::isNotBlank)?.let { File(it).delete() }
        val now = System.currentTimeMillis()
        val audioBook = AudioBook(
            id = existing?.id ?: 0,
            sourceBookId = book.id,
            title = book.title,
            author = book.author,
            remoteJobId = null,
            status = AudioBook.Status.QUEUED,
            createdAt = existing?.createdAt ?: now,
            updatedAt = now
        )
        val id = databaseHelper.saveAudioBook(audioBook)
        return requireNotNull(databaseHelper.getAudioBookById(id))
    }

    fun save(audioBook: AudioBook): AudioBook {
        val id = databaseHelper.saveAudioBook(audioBook.copy(updatedAt = System.currentTimeMillis()))
        return requireNotNull(databaseHelper.getAudioBookById(id))
    }

    fun savePosition(id: Long, positionMs: Long) {
        val current = databaseHelper.getAudioBookById(id) ?: return
        databaseHelper.saveAudioBook(
            current.copy(positionMs = positionMs.coerceAtLeast(0), updatedAt = System.currentTimeMillis())
        )
    }

    fun outputFile(audioBookId: Long): File = File(outputDirectory, "audiobook-$audioBookId.m4a")

    fun partialOutputFile(audioBookId: Long): File = File(outputDirectory, "audiobook-$audioBookId.partial.m4a")

    fun delete(audioBook: AudioBook) {
        audioBook.filePath.takeIf(String::isNotBlank)?.let { File(it).delete() }
        partialOutputFile(audioBook.id).delete()
        databaseHelper.deleteAudioBook(audioBook.id)
    }

    private fun reconcileFile(audioBook: AudioBook): AudioBook {
        if (audioBook.status != AudioBook.Status.READY || File(audioBook.filePath).isFile) {
            return audioBook
        }
        return save(
            audioBook.copy(
                status = AudioBook.Status.FAILED,
                errorMessage = "Файл аудиокниги удалён системой из кэша. Создайте его повторно."
            )
        )
    }
}
