import Foundation

struct ReaderAPI {
    private let api = APIClient.shared
    private let basePath = "/api/reader"

    // MARK: - Entries

    func getEntries(
        status: String? = nil,
        starred: Bool? = nil,
        feedId: Int? = nil,
        categoryId: Int? = nil,
        limit: Int = 50,
        offset: Int = 0
    ) async throws -> ReaderEntryList {
        var items: [URLQueryItem] = [
            URLQueryItem(name: "limit", value: String(limit)),
            URLQueryItem(name: "offset", value: String(offset)),
            URLQueryItem(name: "direction", value: "desc"),
            URLQueryItem(name: "order", value: "published_at"),
        ]
        if let status { items.append(URLQueryItem(name: "status", value: status)) }
        if let starred { items.append(URLQueryItem(name: "starred", value: String(starred))) }
        if let feedId { items.append(URLQueryItem(name: "feed_id", value: String(feedId))) }
        if let categoryId { items.append(URLQueryItem(name: "category_id", value: String(categoryId))) }

        return try await api.get("\(basePath)/entries", queryItems: items)
    }

    func getEntry(id: Int) async throws -> ReaderEntry {
        try await api.get("\(basePath)/entries/\(id)")
    }

    func markEntries(ids: [Int], status: String) async throws {
        let body = ReaderBulkUpdate(entryIds: ids, status: status)
        try await api.putVoid("\(basePath)/entries", body: body)
    }

    func markAllRead(feedId: Int? = nil, categoryId: Int? = nil) async throws -> ReaderMarkAllReadResponse {
        let body = ReaderMarkAllRead(feedId: feedId, categoryId: categoryId)
        return try await api.put("\(basePath)/entries/mark-all-read", body: body)
    }

    func toggleBookmark(entryId: Int) async throws -> ReaderBookmarkResponse {
        // PUT with empty body
        return try await api.put("\(basePath)/entries/\(entryId)/bookmark", body: EmptyBody())
    }

    func fetchFullContent(entryId: Int) async throws -> ReaderEntry {
        return try await api.post("\(basePath)/entries/\(entryId)/fetch-full-content", body: EmptyBody())
    }

    // MARK: - Feeds

    func getFeeds() async throws -> [ReaderFeed] {
        try await api.get("\(basePath)/feeds")
    }

    func getCounters() async throws -> ReaderCounters {
        try await api.get("\(basePath)/feeds/counters")
    }

    func createFeed(url: String, categoryId: Int? = nil) async throws -> ReaderFeed {
        let body = ReaderFeedCreate(feedUrl: url, categoryId: categoryId)
        return try await api.post("\(basePath)/feeds", body: body)
    }

    func deleteFeed(id: Int) async throws {
        _ = try await api.rawRequest("DELETE", path: "\(basePath)/feeds/\(id)")
    }

    func refreshFeed(id: Int) async throws -> ReaderRefreshResponse {
        try await api.post("\(basePath)/feeds/\(id)/refresh", body: EmptyBody())
    }

    func refreshAllFeeds() async throws -> ReaderRefreshResponse {
        try await api.post("\(basePath)/feeds/refresh-all", body: EmptyBody())
    }

    // MARK: - Categories

    func getCategories() async throws -> [ReaderCategory] {
        try await api.get("\(basePath)/categories")
    }

    func createCategory(title: String) async throws -> ReaderCategory {
        try await api.post("\(basePath)/categories", body: ReaderCategoryCreate(title: title))
    }

    // MARK: - Save to Brain

    func saveToBrain(url: String) async throws {
        let body = ["url": url]
        _ = try await api.rawRequest("POST", path: "/api/brain/items", body: body)
    }
}

private struct EmptyBody: Codable {}
