//
//  StatusContentContainer.swift
//  Tusker
//
//  Created by Shadowfacts on 10/2/22.
//  Copyright © 2022 Shadowfacts. All rights reserved.
//

import UIKit

class StatusContentContainer: UIView {
    
    private var useTopSpacer = false
    private let topSpacer = UIView().configure {
        $0.backgroundColor = .clear
        // other 4pt is provided by this view's own spacing
        $0.heightAnchor.constraint(equalToConstant: 4).isActive = true
    }

    let contentTextView = StatusContentTextView().configure {
         $0.adjustsFontForContentSizeCategory = true
         $0.isScrollEnabled = false
         $0.backgroundColor = nil
         $0.isEditable = false
         $0.isSelectable = false
    }
    
    let cardView = StatusCardView().configure {
        NSLayoutConstraint.activate([
            $0.heightAnchor.constraint(equalToConstant: 90),
        ])
    }
    
    let attachmentsView = AttachmentsContainerView()
    
    let pollView = StatusPollView()
    
    private var arrangedSubviews: [UIView] {
        if useTopSpacer {
            return [topSpacer, contentTextView, cardView, attachmentsView, pollView]
        } else {
            return [contentTextView, cardView, attachmentsView, pollView]
        }
    }
    
    private var isHiddenObservations: [NSKeyValueObservation] = []
    
    private var verticalConstraints: [NSLayoutConstraint] = []
    private var lastSubviewBottomConstraint: NSLayoutConstraint?
    private var zeroHeightConstraint: NSLayoutConstraint!
    
    private var isCollapsed = false
    
    var visibleSubviewHeight: CGFloat {
        subviews.filter { !$0.isHidden }.map(\.bounds.height).reduce(0, +)
    }
   
    init(useTopSpacer: Bool) {
        self.useTopSpacer = useTopSpacer
        
        super.init(frame: .zero)
        
        for subview in arrangedSubviews {
            subview.translatesAutoresizingMaskIntoConstraints = false
            addSubview(subview)
            
            NSLayoutConstraint.activate([
                subview.leadingAnchor.constraint(equalTo: leadingAnchor),
                subview.trailingAnchor.constraint(equalTo: trailingAnchor),
            ])
        }
        
        // this constraint needs to have low priority so that during the collapse/expand animation, the content container is the view that shrinks/expands
        zeroHeightConstraint = heightAnchor.constraint(equalToConstant: 0)
        zeroHeightConstraint.priority = .defaultLow
        
        setNeedsUpdateConstraints()
                
        isHiddenObservations = arrangedSubviews.map {
            $0.observe(\.isHidden) { [unowned self] _, _ in
                self.setNeedsUpdateConstraints()
            }
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func updateConstraints() {
        NSLayoutConstraint.deactivate(verticalConstraints)
        verticalConstraints = []
        var lastVisibleSubview: UIView?
        
        for subview in arrangedSubviews {
            guard !subview.isHidden else {
                continue
            }
            
            if let lastVisibleSubview {
                verticalConstraints.append(subview.topAnchor.constraint(equalTo: lastVisibleSubview.bottomAnchor, constant: 4))
            } else {
                verticalConstraints.append(subview.topAnchor.constraint(equalTo: topAnchor))
            }
            
            lastVisibleSubview = subview
        }
        
        NSLayoutConstraint.activate(verticalConstraints)
        
        lastSubviewBottomConstraint?.isActive = false
        // this constraint needs to have low priority so that during the collapse/expand animation, the content container is the view that shrinks/expands
        lastSubviewBottomConstraint = subviews.last(where: { !$0.isHidden })!.bottomAnchor.constraint(equalTo: bottomAnchor)
        lastSubviewBottomConstraint!.isActive = !isCollapsed
        lastSubviewBottomConstraint!.priority = .defaultLow
        
        zeroHeightConstraint.isActive = isCollapsed
        
        super.updateConstraints()
    }
    
    func setCollapsed(_ collapsed: Bool) {
        guard collapsed != isCollapsed else {
            return
        }
        isCollapsed = collapsed
        
        // ensure that we have a lastSubviewBottomConstraint
        updateConstraintsIfNeeded()
        // force unwrap because the content container should always have at least one view
        lastSubviewBottomConstraint!.isActive = !collapsed
        zeroHeightConstraint.isActive = collapsed
    }
    
}
