//
//  RefeshProgressView.swift
//  NetNewsWire-iOS
//
//  Created by Maurice Parker on 10/24/19.
//  Copyright © 2019 Ranchero Software. All rights reserved.
//

import UIKit
import Account

class RefreshProgressView: UIView {
	
	@IBOutlet weak var progressView: UIProgressView!
	@IBOutlet weak var label: UILabel!
	
	override func awakeFromNib() {
		NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .AccountRefreshProgressDidChange, object: nil)
		NotificationCenter.default.addObserver(self, selector: #selector(contentSizeCategoryDidChange(_:)), name: UIContentSizeCategory.didChangeNotification, object: nil)
		update()
		scheduleUpdateRefreshLabel()

		isAccessibilityElement = true
		accessibilityTraits = [.updatesFrequently, .notEnabled]
	}
	
	func update() {
		if !AccountManager.shared.combinedRefreshProgress.isComplete {
			progressChanged(animated: false)
		} else {
			updateRefreshLabel()
		}
	}

	override func didMoveToSuperview() {
		progressChanged(animated: false)
	}

	@objc func progressDidChange(_ note: Notification) {
		progressChanged(animated: true)
	}

	@objc func contentSizeCategoryDidChange(_ note: Notification) {
		// This hack is probably necessary because custom views in the toolbar don't get
		// notifications that the content size changed.
		label.font = UIFont.preferredFont(forTextStyle: .footnote)
	}

	deinit {
		NotificationCenter.default.removeObserver(self)
	}
	
}

// MARK: Private

private extension RefreshProgressView {

	func progressChanged(animated: Bool) {
		// Layout may crash if not in the view hierarchy.
		// https://github.com/Ranchero-Software/NetNewsWire/issues/1764
		let isInViewHierarchy = self.superview != nil

		let progress = AccountManager.shared.combinedRefreshProgress

		if progress.isComplete {
			if isInViewHierarchy {
				progressView.setProgress(1, animated: animated)
			}
			
			func completeLabel() {
				// Check that there are no pending downloads.
				if AccountManager.shared.combinedRefreshProgress.isComplete {
					self.updateRefreshLabel()
					self.label.isHidden = false
					self.progressView.isHidden = true
					if self.superview != nil {
						self.progressView.setProgress(0, animated: animated)
					}
				}
			}

			if animated {
				DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
					completeLabel()
				}
			} else {
				completeLabel()
			}
		} else {
			label.isHidden = true
			progressView.isHidden = false
			if isInViewHierarchy {
				let percent = Float(progress.numberCompleted) / Float(progress.numberOfTasks)

				// Don't let the progress bar go backwards unless we need to go back more than 25%
				if percent > progressView.progress || progressView.progress - percent > 0.25 {
					progressView.setProgress(percent, animated: animated)
				}
			}
		}
	}
	
	func updateRefreshLabel() {
		if let accountLastArticleFetchEndTime = AccountManager.shared.lastArticleFetchEndTime {

			if Date() > accountLastArticleFetchEndTime.addingTimeInterval(60) {

				let relativeDateTimeFormatter = RelativeDateTimeFormatter()
				relativeDateTimeFormatter.dateTimeStyle = .named
				let refreshed = relativeDateTimeFormatter.localizedString(for: accountLastArticleFetchEndTime, relativeTo: Date())
				let localizedRefreshText = NSLocalizedString("Updated %@", comment: "Updated")
				let refreshText = NSString.localizedStringWithFormat(localizedRefreshText as NSString, refreshed) as String
				label.text = refreshText

			} else {
				label.text = NSLocalizedString("Updated Just Now", comment: "Updated Just Now")
			}

		} else {
			label.text = ""
		}

		accessibilityLabel = label.text
	}

	func scheduleUpdateRefreshLabel() {
		DispatchQueue.main.asyncAfter(deadline: .now() + 60) { [weak self] in
			self?.updateRefreshLabel()
			self?.scheduleUpdateRefreshLabel()
		}
	}
	
}