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

import UIKit
import UserAccounts
import WebURL

class FastSwitchingAccountView: UIView {
    
    private lazy var selectedColor = UIColor { [unowned self] (traits) in
        var hue: CGFloat = 0
        var saturation: CGFloat = 0
        var brightness: CGFloat = 0
        var alpha: CGFloat = 0
        self.tintColor.resolvedColor(with: traits).getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
        brightness = min(1, brightness + 0.4)
        saturation = max(0, saturation - 0.3)
        return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
    }
    private lazy var currentColor = UIColor { [unowned self] (traits) in
        var hue: CGFloat = 0
        var saturation: CGFloat = 0
        var brightness: CGFloat = 0
        var alpha: CGFloat = 0
        self.tintColor.resolvedColor(with: traits).getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
        brightness = min(1, brightness + 0.3)
        saturation = max(0, saturation - 0.2)
        return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
    }
    var isSelected = false {
        didSet {
            updateLabelColors()
        }
    }
    var isCurrent = false {
        didSet {
            updateLabelColors()
        }
    }
    
    private let orientation: FastAccountSwitcherViewController.ItemOrientation
    
    private let usernameLabel = UILabel()
    private let instanceLabel = UILabel()
    private let avatarImageView = UIImageView()
    
    private var avatarRequest: ImageCache.Request?
    
    init(account: UserAccountInfo, orientation: FastAccountSwitcherViewController.ItemOrientation) {
        self.orientation = orientation
        super.init(frame: .zero)
        commonInit()
        setupAccount(account: account)
    }
    
    init(orientation: FastAccountSwitcherViewController.ItemOrientation) {
        self.orientation = orientation
        super.init(frame: .zero)
        commonInit()
        setupPlaceholder()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func commonInit() {
        usernameLabel.textColor = .white
        usernameLabel.font = UIFont(descriptor: .preferredFontDescriptor(withTextStyle: .headline), size: 0)
        
        instanceLabel.textColor = .white
        instanceLabel.font = UIFont(descriptor: .preferredFontDescriptor(withTextStyle: .subheadline), size: 0)
        
        let stackView = UIStackView(arrangedSubviews: [
            usernameLabel,
            instanceLabel
        ])
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .vertical
        addSubview(stackView)
        
        avatarImageView.translatesAutoresizingMaskIntoConstraints = false
        avatarImageView.layer.masksToBounds = true
        avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 40
        avatarImageView.layer.cornerCurve = .continuous
        avatarImageView.image = UIImage(systemName: Preferences.shared.avatarStyle == .circle ? "person.crop.circle" : "person.crop.square")
        // todo: this should really be fit, but somehow the image view ends up being 37pt tall?
        avatarImageView.contentMode = .scaleAspectFill
        addSubview(avatarImageView)
        
        NSLayoutConstraint.activate([
            avatarImageView.topAnchor.constraint(equalTo: topAnchor, constant: 8),
            avatarImageView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8),
            avatarImageView.widthAnchor.constraint(equalToConstant: 40),
            avatarImageView.heightAnchor.constraint(equalTo: avatarImageView.widthAnchor),
            
            stackView.centerYAnchor.constraint(equalTo: avatarImageView.centerYAnchor),
        ])
        
        switch orientation {
        case .iconsLeading:
            stackView.alignment = .leading
            NSLayoutConstraint.activate([
                avatarImageView.leadingAnchor.constraint(equalTo: leadingAnchor),
                stackView.leadingAnchor.constraint(equalTo: avatarImageView.trailingAnchor, constant: 8),
                stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
            ])
            
        case .iconsTrailing:
            stackView.alignment = .trailing
            NSLayoutConstraint.activate([
                avatarImageView.trailingAnchor.constraint(equalTo: trailingAnchor),
                stackView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8),
                stackView.trailingAnchor.constraint(equalTo: avatarImageView.leadingAnchor, constant: -8),
            ])
        }
        
        updateLabelColors()
        
        isAccessibilityElement = true
    }
    
    private func setupAccount(account: UserAccountInfo) {
        usernameLabel.text = account.username
        if let domain = WebURL.Domain(account.instanceURL.host!) {
            instanceLabel.text = domain.render(.uncheckedUnicodeString)
        } else {
            instanceLabel.text = account.instanceURL.host!
        }
        let controller = MastodonController.getForAccount(account)
        controller.getOwnAccount { [weak self] (result) in
            guard let self = self,
                  case let .success(account) = result,
                  let avatar = account.avatar else { return }
            self.avatarRequest = ImageCache.avatars.get(avatar) { [weak self] (_, image) in
                guard let self = self, let image = image else { return }
                DispatchQueue.main.async {
                    self.avatarImageView.image = image
                }
            }
        }
        
        accessibilityLabel = "\(account.username!)@\(instanceLabel.text!)"
    }
    
    private func setupPlaceholder() {
        usernameLabel.text = "Add Account"
        instanceLabel.isHidden = true
        avatarImageView.image = UIImage(systemName: "plus")
        
        accessibilityLabel = "Add Account"
    }
    
    private func updateLabelColors() {
        let color: UIColor
        if isSelected {
            color = selectedColor
        } else if isCurrent {
            color = currentColor
        } else {
            color = .white
        }
        usernameLabel.textColor = color
        instanceLabel.textColor = color
        avatarImageView.tintColor = color
    }

}
