//
//  View+CONTRAIT.swift
//  react-native-firework-sdk
//
//  Created by Jeff Zheng on 2021/12/30.
//

import Foundation

public struct LayoutDirection: OptionSet {
    public let rawValue: Int

    public init(rawValue: Int) {
        self.rawValue = rawValue
    }

    public static let top = LayoutDirection(rawValue: 1 << 0)
    public static let bottom = LayoutDirection(rawValue: 1 << 1)
    public static let leading = LayoutDirection(rawValue: 1 << 2)
    public static let trailing = LayoutDirection(rawValue: 1 << 3)

    public static let horizontal: LayoutDirection = [.leading, .trailing]
    public static let vertical: LayoutDirection = [.top, .bottom]

    public static let all: LayoutDirection = [.horizontal, .vertical]
}

extension UILayoutPriority {
    public static var almostRequired: UILayoutPriority {
        return .required - 1
    }
}

extension NSLayoutConstraint {
    public func withPriority(_ new: UILayoutPriority) -> NSLayoutConstraint {
        priority = new
        return self
    }
}

extension UIView {
    public func setContentHuggingPriorities(_ new: UILayoutPriority) {
        setContentHuggingPriority(new, for: .horizontal)
        setContentHuggingPriority(new, for: .vertical)
    }

    public func setContentCompressionResistancePriorities(_ new: UILayoutPriority) {
        setContentCompressionResistancePriority(new, for: .horizontal)
        setContentCompressionResistancePriority(new, for: .vertical)
    }

    public func constraints(
        equalTo other: UIView, directions: LayoutDirection = .all,
        priority: UILayoutPriority = .required
    ) -> [NSLayoutConstraint] {
        var constraints: [NSLayoutConstraint] = []
        if directions.contains(.top) {
            constraints.append(
                topAnchor.constraint(equalTo: other.topAnchor).withPriority(priority))
        }
        if directions.contains(.leading) {
            constraints.append(
                leadingAnchor.constraint(equalTo: other.leadingAnchor).withPriority(priority))
        }
        if directions.contains(.bottom) {
            constraints.append(
                bottomAnchor.constraint(equalTo: other.bottomAnchor).withPriority(priority))
        }
        if directions.contains(.trailing) {
            constraints.append(
                trailingAnchor.constraint(equalTo: other.trailingAnchor).withPriority(priority))
        }
        return constraints
    }

    public func constraints(
        equalTo layoutGuide: UILayoutGuide, directions: LayoutDirection = .all,
        priority: UILayoutPriority = .required
    ) -> [NSLayoutConstraint] {
        var constraints: [NSLayoutConstraint] = []
        if directions.contains(.top) {
            constraints.append(
                topAnchor.constraint(equalTo: layoutGuide.topAnchor).withPriority(priority))
        }
        if directions.contains(.leading) {
            constraints.append(
                leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).withPriority(priority))
        }
        if directions.contains(.bottom) {
            constraints.append(
                bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).withPriority(priority))
        }
        if directions.contains(.trailing) {
            constraints.append(
                trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).withPriority(
                    priority))
        }
        return constraints
    }

    public var isRightToLeft: Bool {
        return UIView.userInterfaceLayoutDirection(for: semanticContentAttribute) == .rightToLeft
    }
}
