import APIClient
import ComposableArchitecture
import Foundation

final actor FeedState: Sendable {
    public var hooks: [Hook] = []
    public var isLoading = false
    public var currentPage = 0
    public var config: HooksFeedConfig

    @Dependency(\.apiClientV2) var apiClientV2

    init() {
        self.config = .init()
    }

    func loadInitialHooks(config: HooksFeedConfig) async throws -> [Hook] {
        isLoading = true
        currentPage = 0
        let prioritizeCache = true

        do {
            let hooks = try await apiClientV2.getHooks(prioritizeCache)
            self.hooks = hooks
            self.config = config
            currentPage += 1
            isLoading = false
            return hooks
        } catch {
            isLoading = false
            throw error
        }
    }

    func loadNextHooks() async throws -> [Hook] {
        guard !isLoading else { return [] }
        let prioritizeCache = false
        isLoading = true

        do {
            let hooks = try await apiClientV2.getHooks(prioritizeCache)
            self.hooks.append(contentsOf: hooks)
            currentPage += 1
            isLoading = false
            return hooks
        } catch {
            isLoading = false
            throw error
        }
    }

    func reloadHooks() async throws -> [Hook] {
        isLoading = true
        currentPage = 0
        let prioritizeCache = false
        do {
            let hooks = try await apiClientV2.getHooks(prioritizeCache)
            self.hooks = hooks
            currentPage = 0
            isLoading = false
            return hooks
        } catch {
            isLoading = false
            throw error
        }
    }

    // After hiding a creator, fetch more hooks and filter out duplicates and hidden creators
    func loadMoreHooks(currentIndex: Int, hiddenCreatorHandles: [String: Bool]) async throws -> [Hook] {
        guard !isLoading else { return [] }
        isLoading = true
        let prioritizeCache = false
        // Remove the hooks after the current index
        self.hooks.removeSubrange((currentIndex + 1) ..< self.hooks.count)
        do {
            let hooks = try await apiClientV2.getHooks(prioritizeCache)

            // Filter out duplicates and hidden creators
            let existingIds = Set(self.hooks.map(\.id))
            let filteredHooks = hooks.filter { hook in
                let isNotHidden = !(hiddenCreatorHandles[hook.user?.handle ?? ""] ?? false)
                let isNotDuplicate = !existingIds.contains(hook.id)
                return isNotHidden && isNotDuplicate
            }

            self.hooks.append(contentsOf: filteredHooks)

            isLoading = false
            return filteredHooks
        } catch {
            isLoading = false
            throw error
        }
    }

    func getAllHooks() async -> [Hook] {
        return hooks
    }
}
