//
//  AccountMO.swift
//  Tusker
//
//  Created by Shadowfacts on 4/11/20.
//  Copyright © 2020 Shadowfacts. All rights reserved.
//
//

import Foundation
import CoreData
import Pachyderm

@objc(AccountMO)
public final class AccountMO: NSManagedObject, AccountProtocol {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<AccountMO> {
        return NSFetchRequest<AccountMO>(entityName: "Account")
    }
    
    @nonobjc public class func fetchRequest(url: URL) -> NSFetchRequest<AccountMO> {
        let req = NSFetchRequest<AccountMO>(entityName: "Account")
        req.predicate = NSPredicate(format: "url = %@", url as NSURL)
        return req
    }
    
    @NSManaged public var acct: String
    /// Whether this AccountMO is the active (logged-in) account.
    @NSManaged public var active: Bool
    @NSManaged public var avatar: URL?
    @NSManaged public var botCD: Bool
    @NSManaged public var createdAt: Date
    @NSManaged public var displayName: String
    @NSManaged private var emojisData: Data?
    @NSManaged private var fieldsData: Data?
    @NSManaged public var followersCount: Int
    @NSManaged public var followingCount: Int
    @NSManaged public var header: URL?
    @NSManaged public var id: String
    @NSManaged public var locked: Bool
    @NSManaged public var movedCD: Bool
    @NSManaged public var note: String
    @NSManaged public var statusesCount: Int
    @NSManaged public var url: URL
    @NSManaged public var username: String
    @NSManaged public var lastFetchedAt: Date?
    @NSManaged public var movedTo: AccountMO?
    
    @LazilyDecoding(arrayFrom: \AccountMO.emojisData)
    public var emojis: [Emoji]
    
    @LazilyDecoding(arrayFrom: \AccountMO.fieldsData)
    public var fields: [Pachyderm.Account.Field]
    
    public var bot: Bool? { botCD }
    public var moved: Bool? { movedCD }
    
    public override func awakeFromFetch() {
        super.awakeFromFetch()
        
        managedObjectContext?.perform {
            self.touch()
        }
    }
    
    /// Update the `lastFetchedAt` date so this object isn't pruned early.
    func touch() {
        lastFetchedAt = Date()
    }

}

extension AccountMO {
    convenience init(apiAccount account: Pachyderm.Account, container: MastodonCachePersistentStore, context: NSManagedObjectContext) {
        self.init(context: context)
        self.updateFrom(apiAccount: account, container: container)
        self.lastFetchedAt = Date()
    }
    
    func updateFrom(apiAccount account: Pachyderm.Account, container: MastodonCachePersistentStore) {
        guard let context = managedObjectContext else {
            // we've been deleted, don't bother updating
            return
        }
        
        self.acct = account.acct
        self.avatar = account.avatarStatic // we don't animate avatars
        self.botCD = account.bot ?? false
        self.createdAt = account.createdAt
        self.displayName = account.displayName
        self.emojis = account.emojis
        self.fields = account.fields
        self.followersCount = account.followersCount
        self.followingCount = account.followingCount
        self.header = account.headerStatic // we don't animate headers
        self.id = account.id
        self.locked = account.locked
        self.movedCD = account.moved ?? false
        self.note = account.note
        self.statusesCount = account.statusesCount
        self.url = account.url
        self.username = account.username
        if let movedTo = account.movedTo {
            self.movedTo = container.account(for: movedTo.id, in: context) ?? AccountMO(apiAccount: movedTo, container: container, context: context)
        } else {
            self.movedTo = nil
        }
    }
}
