//
//  RefreshProgressModel.swift
//  NetNewsWire
//
//  Created by Phil Viso on 7/2/20.
//  Copyright © 2020 Ranchero Software. All rights reserved.
//

import SwiftUI
import Combine
import RSCore
import Account

class RefreshProgressModel: ObservableObject {
	
	enum State {
		case refreshProgress(Float)
		case lastRefreshDateText(String)
		case none
	}
		
	@Published var state = State.none
	
	private static var dateFormatter: RelativeDateTimeFormatter = {
		let formatter = RelativeDateTimeFormatter()
		formatter.dateTimeStyle = .named
		
		return formatter
	}()
		
	private static let lastRefreshDateTextUpdateInterval = 60
	private static let lastRefreshDateTextRelativeDateFormattingThreshold = 60.0
	
	func startup() {
		updateState()
		observeRefreshProgress()
		scheduleLastRefreshDateTextUpdate()
	}
	
	// MARK: Observing account changes
	
	private func observeRefreshProgress() {
		NotificationCenter.default.addObserver(self, selector: #selector(accountRefreshProgressDidChange), name: .AccountRefreshProgressDidChange, object: nil)
	}
	
	// MARK: Refreshing state
	
	@objc private func accountRefreshProgressDidChange() {
		CoalescingQueue.standard.add(self, #selector(updateState))
	}
	
	@objc private func updateState() {
		let progress = AccountManager.shared.combinedRefreshProgress
		
		if !progress.isComplete {
			let fractionCompleted = Float(progress.numberCompleted) / Float(progress.numberOfTasks)
			self.state = .refreshProgress(fractionCompleted)
		} else if let lastRefreshDate = AccountManager.shared.lastArticleFetchEndTime {
			let text = localizedLastRefreshText(lastRefreshDate: lastRefreshDate)
			self.state = .lastRefreshDateText(text)
		} else {
			self.state = .none
		}
	}
	
	private func scheduleLastRefreshDateTextUpdate() {
		DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(Self.lastRefreshDateTextUpdateInterval)) {
			self.updateState()
			self.scheduleLastRefreshDateTextUpdate()
		}
	}
	
	private func localizedLastRefreshText(lastRefreshDate: Date) -> String {
		let now = Date()
		
		if now > lastRefreshDate.addingTimeInterval(Self.lastRefreshDateTextRelativeDateFormattingThreshold) {
			let localizedDate = Self.dateFormatter.localizedString(for: lastRefreshDate, relativeTo: now)
			let formatString = NSLocalizedString("Updated %@", comment: "Updated") as NSString
			
			return NSString.localizedStringWithFormat(formatString, localizedDate) as String
		} else {
			return NSLocalizedString("Updated Just Now", comment: "Updated Just Now")
		}
	}
		
}