/*
 * Book's Story — free and open-source Material You eBook reader.
 * Copyright (C) 2024-2026 Acclorite
 * SPDX-License-Identifier: GPL-3.0-only
 */

package org.dueattendant149.bookshelf.domain.use_case.file_system

import org.dueattendant149.bookshelf.core.helpers.compareByWithOrder
import org.dueattendant149.bookshelf.core.log.logE
import org.dueattendant149.bookshelf.core.log.logI
import org.dueattendant149.bookshelf.data.settings.SettingsManager
import org.dueattendant149.bookshelf.domain.model.file.File
import org.dueattendant149.bookshelf.domain.repository.FileSystemRepository
import org.dueattendant149.bookshelf.presentation.browse.model.BrowseSortOrder
import javax.inject.Inject

private const val TAG = "GetFiles"

class GetFilesUseCase @Inject constructor(
    private val fileSystemRepository: FileSystemRepository,
    private val settings: SettingsManager
) {

    suspend operator fun invoke(query: String = ""): List<File> {
        logI(TAG, "Searching for files with query: \"$query\".")

        fun List<File>.filterFiles(): List<File> {
            return if (settings.browseIncludedFilterItems.lastValue.isEmpty()) this
            else filter { file ->
                settings.browseIncludedFilterItems.lastValue.any { extension ->
                    file.path.endsWith(
                        extension, ignoreCase = true
                    )
                }
            }
        }

        fun List<File>.sortFiles(): List<File> {
            return sortedWith(
                compareByWithOrder(settings.browseSortOrderDescending.lastValue) { file ->
                    when (settings.browseSortOrder.lastValue) {
                        BrowseSortOrder.NAME -> file.name.trim()

                        BrowseSortOrder.FILE_FORMAT -> file.path
                            .substringAfterLast(".")
                            .lowercase()
                            .trimEnd()

                        BrowseSortOrder.FILE_SIZE -> file.size

                        else -> file.lastModified
                    }
                }
            )
        }

        return runCatching {
            fileSystemRepository.searchFiles(query)
                .getOrThrow()
                .filterFiles()
                .sortFiles()
        }.fold(
            onSuccess = {
                logI(TAG, "Successfully found [${it.size}] files.")
                it
            },
            onFailure = {
                logE(TAG, "Could not find files with error: ${it.message}")
                emptyList()
            }
        )
    }
}