// Copyright © 2020 Metabolist. All rights reserved.

import Combine
import DB
import Foundation
import Mastodon
import MastodonAPI

public struct TimelineService {
    public let sections: AnyPublisher<[CollectionSection], Error>
    public let navigationService: NavigationService
    public let nextPageMaxId: AnyPublisher<String, Never>
    public let title: AnyPublisher<String, Never>
    public let titleLocalizationComponents: AnyPublisher<[String], Never>

    private let timeline: Timeline
    private let mastodonAPIClient: MastodonAPIClient
    private let contentDatabase: ContentDatabase
    private let nextPageMaxIdSubject = PassthroughSubject<String, Never>()

    init(timeline: Timeline, mastodonAPIClient: MastodonAPIClient, contentDatabase: ContentDatabase) {
        self.timeline = timeline
        self.mastodonAPIClient = mastodonAPIClient
        self.contentDatabase = contentDatabase
        sections = contentDatabase.timelinePublisher(timeline)
        navigationService = NavigationService(mastodonAPIClient: mastodonAPIClient, contentDatabase: contentDatabase)
        nextPageMaxId = nextPageMaxIdSubject.eraseToAnyPublisher()

        switch timeline {
        case let .list(list):
            title = Just(list.title).eraseToAnyPublisher()
            titleLocalizationComponents = Empty().eraseToAnyPublisher()
        case let .tag(tag):
            title = Just("#".appending(tag)).eraseToAnyPublisher()
            titleLocalizationComponents = Empty().eraseToAnyPublisher()
        case .favorites:
            title = Empty().eraseToAnyPublisher()
            titleLocalizationComponents = Just(["favorites"]).eraseToAnyPublisher()
        case .bookmarks:
            title = Empty().eraseToAnyPublisher()
            titleLocalizationComponents = Just(["bookmarks"]).eraseToAnyPublisher()
        default:
            title = Empty().eraseToAnyPublisher()
            titleLocalizationComponents = Empty().eraseToAnyPublisher()
        }
    }
}

extension TimelineService: CollectionService {
    public var preferLastPresentIdOverNextPageMaxId: Bool {
        !timeline.ordered
    }

    public var markerTimeline: Marker.Timeline? {
        switch timeline {
        case .home:
            return .home
        default:
            return nil
        }
    }

    public func request(maxId: String?, minId: String?, search: Search?) -> AnyPublisher<Never, Error> {
        mastodonAPIClient.pagedRequest(timeline.endpoint, maxId: maxId, minId: minId)
            .handleEvents(receiveOutput: {
                if let maxId = $0.info.maxId {
                    nextPageMaxIdSubject.send(maxId)
                }
            })
            .flatMap { contentDatabase.insert(statuses: $0.result, timeline: timeline) }
            .eraseToAnyPublisher()
    }
}
