//
//  ProfileFieldsView.swift
//  Tusker
//
//  Created by Shadowfacts on 11/4/22.
//  Copyright © 2022 Shadowfacts. All rights reserved.
//

import UIKit
import Pachyderm

class ProfileFieldsView: UIView {
    
    weak var delegate: ProfileHeaderViewDelegate?
    
    private var fields = [Account.Field]()
    
    private var fieldViews: [(EmojiLabel, ProfileFieldValueView, UIView)] = []
    private var fieldConstraints: [NSLayoutConstraint] = []
    private lazy var dividerLayoutGuide: UILayoutGuide = {
        let guide = UILayoutGuide()
        addLayoutGuide(guide)
        guide.widthAnchor.constraint(equalToConstant: 8).isActive = true
        let centerDividerConstraint = guide.centerXAnchor.constraint(equalTo: centerXAnchor)
        centerDividerConstraint.priority = .defaultHigh
        centerDividerConstraint.isActive = true
        return guide
    }()
    private var dividerXConstraint: NSLayoutConstraint?
    private var boundsObservation: NSKeyValueObservation?
    
    private var isUsingSingleColumn: Bool = false
    private var needsSingleColumn: Bool {
        traitCollection.horizontalSizeClass == .compact && traitCollection.preferredContentSizeCategory > .extraLarge
    }
    
    override var accessibilityElements: [Any]? {
        get {
            fieldViews.flatMap { [$0.0, $0.1] }
        }
        set {}
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    
    private func commonInit() {
        boundsObservation = observe(\.bounds, changeHandler: { [unowned self] _, _ in
            self.setNeedsUpdateConstraints()
        })
    }
    
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        if isUsingSingleColumn != needsSingleColumn {
            configureFields()
        }
    }
    
    func updateUI(account: AccountMO) {
        isHidden = account.fields.isEmpty
        guard !account.fields.isEmpty,
              fields != account.fields else {
            return
        }
        fields = account.fields
        
        for (name, value, fieldContainer) in fieldViews {
            name.removeFromSuperview()
            value.removeFromSuperview()
            fieldContainer.removeFromSuperview()
        }
        fieldViews = []
        
        for (index, field) in account.fields.enumerated() {
            let nameLabel = EmojiLabel()
            nameLabel.text = field.name
            nameLabel.font = .preferredFont(forTextStyle: .body).withTraits(.traitBold)!
            nameLabel.adjustsFontForContentSizeCategory = true
            nameLabel.numberOfLines = 0
            nameLabel.lineBreakMode = .byWordWrapping
            nameLabel.showsExpansionTextWhenTruncated = true
            nameLabel.setEmojis(account.emojis, identifier: account.id)
            nameLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
            
            let valueView = ProfileFieldValueView(field: field, account: account)
            valueView.navigationDelegate = delegate
            valueView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
            
            let container = UIView()
            container.translatesAutoresizingMaskIntoConstraints = false
            addSubview(container)
            
            nameLabel.translatesAutoresizingMaskIntoConstraints = false
            container.addSubview(nameLabel)
            valueView.translatesAutoresizingMaskIntoConstraints = false
            container.addSubview(valueView)
            
            if index % 2 == 0 {
                container.backgroundColor = .secondarySystemFill
            } else {
                container.backgroundColor = .quaternarySystemFill
            }
            if index == 0 || index == fields.count - 1 {
                if fields.count > 1 && index == 0 {
                    container.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
                } else if fields.count > 1 && index == fields.count - 1 {
                    container.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
                }
                container.layer.cornerRadius = 8
                container.layer.cornerCurve = .continuous
            }
            
            fieldViews.append((nameLabel, valueView, container))
        }
        
        configureFields()
    }
    
    @objc private func configureFields() {
        guard !isHidden else {
            return
        }
        
        isUsingSingleColumn = needsSingleColumn
        
        NSLayoutConstraint.deactivate(fieldConstraints)
        fieldConstraints = []
        
        var prevContainer: UIView?
        
        for (name, value, container) in fieldViews {
            fieldConstraints.append(contentsOf: [
                container.leadingAnchor.constraint(equalTo: leadingAnchor),
                container.trailingAnchor.constraint(equalTo: trailingAnchor),
            ])
            
            if needsSingleColumn {
                name.textAlignment = .natural
                value.setTextAlignment(.natural)
                
                fieldConstraints.append(contentsOf: [
                    name.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 4),
                    name.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -4),
                    name.topAnchor.constraint(equalTo: container.topAnchor, constant: 4),
                    
                    value.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 4),
                    value.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -4),
                    value.topAnchor.constraint(equalTo: name.bottomAnchor),
                    value.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: -4),
                ])
            } else {
                name.textAlignment = .right
                value.setTextAlignment(.left)
                
                fieldConstraints.append(contentsOf: [
                    container.heightAnchor.constraint(greaterThanOrEqualToConstant: 32),
                    
                    name.leadingAnchor.constraint(greaterThanOrEqualTo: container.leadingAnchor, constant: 4),
                    name.trailingAnchor.constraint(equalTo: dividerLayoutGuide.leadingAnchor),
                    name.topAnchor.constraint(equalTo: container.topAnchor, constant: 4),
                    name.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: -4),
                    
                    value.leadingAnchor.constraint(equalTo: dividerLayoutGuide.trailingAnchor),
                    value.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -4),
                    value.topAnchor.constraint(equalTo: container.topAnchor, constant: 4),
                    value.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: -4),
                ])
            }
            
            let containerTopConstraint = container.topAnchor.constraint(equalTo: prevContainer?.bottomAnchor ?? topAnchor)
            fieldConstraints.append(containerTopConstraint)
            prevContainer = container
        }
        
        if let prevContainer {
            let lastContainerBottomConstraint = prevContainer.bottomAnchor.constraint(equalTo: bottomAnchor)
            fieldConstraints.append(lastContainerBottomConstraint)
        }
        
        NSLayoutConstraint.activate(fieldConstraints)
    }
    
    override func updateConstraints() {
        if !needsSingleColumn,
           !fieldViews.isEmpty {
            let maxNameWidth = fieldViews.map {
                $0.0.sizeThatFits(UIView.layoutFittingCompressedSize).width
            }.max()!
            let maxValueWidth = fieldViews.map {
                $0.1.sizeThatFits(UIView.layoutFittingCompressedSize).width
            }.max()!
            
            let defaultWidth = (bounds.width - 8) / 2
            
            dividerXConstraint?.isActive = false
            if maxNameWidth > defaultWidth && maxValueWidth < defaultWidth {
                dividerXConstraint = dividerLayoutGuide.leadingAnchor.constraint(equalTo: leadingAnchor, constant: min(maxNameWidth, bounds.width * 2 / 3))
                dividerXConstraint!.isActive = true
            } else if maxNameWidth < defaultWidth && maxValueWidth > defaultWidth {
                dividerXConstraint = dividerLayoutGuide.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -min(maxValueWidth, bounds.width * 2 / 3))
                dividerXConstraint!.isActive = true
            }
        }
        
        super.updateConstraints()
    }
    
}
