//
//  HashtagTimelineViewController.swift
//  Tusker
//
//  Created by Shadowfacts on 12/19/19.
//  Copyright © 2019 Shadowfacts. All rights reserved.
//

import UIKit
import Pachyderm

class HashtagTimelineViewController: TimelineViewController {

    let hashtagName: String
    private var hashtag: Hashtag?
    private var fetchHashtag: Task<Hashtag?, Never>?
    
    var toggleSaveButton: UIBarButtonItem!
    
    var isHashtagSaved: Bool {
        let req = SavedHashtag.fetchRequest(name: hashtagName, account: mastodonController.accountInfo!)
        return mastodonController.persistentContainer.viewContext.objectExists(for: req)
    }
    
    private var isHashtagFollowed: Bool {
        mastodonController.followedHashtags.contains(where: { $0.name == hashtagName })
    }
    
    convenience init(for hashtag: Hashtag, mastodonController: MastodonController) {
        self.init(forNamed: hashtag.name, mastodonController: mastodonController)
        self.hashtag = hashtag
    }
    
    init(forNamed name: String, mastodonController: MastodonController) {
        self.hashtagName = name
        
        super.init(for: .tag(hashtag: hashtagName), mastodonController: mastodonController)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        if hashtag == nil {
            fetchHashtag = Task {
                let name = hashtagName.lowercased()
                let hashtag: Hashtag?
                if mastodonController.instanceFeatures.hasMastodonVersion(4, 0, 0) {
                    let req = Client.getHashtag(name: name)
                    hashtag = try? await mastodonController.run(req).0
                } else {
                    let req = Client.search(query: "#\(name)", types: [.hashtags])
                    let results = try? await mastodonController.run(req).0
                    hashtag = results?.hashtags.first(where: { $0.name.lowercased() == name })
                }
                self.hashtag = hashtag
                return hashtag
            }
        }

        let menu = UIMenu(children: [
            // uncached so that the saved/followed updates every time
            UIDeferredMenuElement.uncached({ [unowned self] elementHandler in
                if let hashtag = self.hashtag {
                    elementHandler(actionsForHashtag(hashtag, source: .barButtonItem(self.navigationItem.rightBarButtonItem!)))
                } else {
                    Task {
                        if let hashtag = await fetchHashtag?.value {
                            elementHandler(actionsForHashtag(hashtag, source: .barButtonItem(self.navigationItem.rightBarButtonItem!)))
                        } else {
                            elementHandler([])
                        }
                    }
                }
            })
        ])
        navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "ellipsis"), menu: menu)
    }
    
    private func toggleSave() {
        let context = mastodonController.persistentContainer.viewContext
        if let existing = try? context.fetch(SavedHashtag.fetchRequest(name: hashtagName, account: mastodonController.accountInfo!)).first {
            context.delete(existing)
            mastodonController.persistentContainer.save(context: context)
        } else {
            Task { @MainActor in
                let hashtag: Hashtag?
                if let tag = self.hashtag {
                    hashtag = tag
                } else {
                    hashtag = await fetchHashtag?.value
                }
                if let hashtag {
                    _ = SavedHashtag(hashtag: hashtag, account: mastodonController.accountInfo!, context: context)
                    mastodonController.persistentContainer.save(context: context)
                }
            }
        }
    }
    
    private func toggleFollow() {
        Task {
            await ToggleFollowHashtagService(hashtagName: hashtagName, presenter: self).toggleFollow()
        }
    }

}
