// Copyright © 2020 Metabolist. All rights reserved.

import Mastodon
import SDWebImage
import UIKit
import ViewModels

final class CardView: UIView {
    let imageView = UIImageView()
    let titleLabel = UILabel()
    let descriptionLabel = UILabel()
    let urlLabel = UILabel()
    let button = UIButton()

    var viewModel: CardViewModel? {
        didSet {
            guard let viewModel = viewModel else { return }

            var accessibilityLabel = NSLocalizedString("card.link.accessibility-label", comment: "")
                .appendingWithSeparator(viewModel.title)

            imageView.isHidden = viewModel.imageURL == nil
            imageView.sd_setImage(with: viewModel.imageURL)

            titleLabel.text = viewModel.title
            descriptionLabel.text = viewModel.description
            descriptionLabel.isHidden = descriptionLabel.text == "" || descriptionLabel.text == titleLabel.text

            if
                let host = viewModel.url.host, host.hasPrefix("www."),
                let withoutWww = host.components(separatedBy: "www.").last {
                urlLabel.text = withoutWww
            } else {
                urlLabel.text = viewModel.url.host
            }

            if let urlLabelText = urlLabel.text {
                accessibilityLabel.appendWithSeparator(urlLabelText)
            }

            self.accessibilityLabel = accessibilityLabel
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)

        initialSetup()
        setupAccessibility()
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension CardView {
    static func estimatedHeight(width: CGFloat,
                                identityContext: IdentityContext,
                                status: Status,
                                configuration: CollectionItem.StatusConfiguration) -> CGFloat {
        if status.displayStatus.card != nil {
            return round(UIFont.preferredFont(forTextStyle: .headline).lineHeight
                            + UIFont.preferredFont(forTextStyle: .subheadline).lineHeight
                            + UIFont.preferredFont(forTextStyle: .footnote).lineHeight
                            + .defaultSpacing * 2
                            + .compactSpacing * 2)
        } else {
            return 0
        }
    }
}

private extension CardView {
    // swiftlint:disable:next function_body_length
    func initialSetup() {
        backgroundColor = .secondarySystemBackground
        layer.cornerRadius = .defaultCornerRadius
        clipsToBounds = true

        let stackView = UIStackView()
        let innerStackView = UIStackView()

        addSubview(stackView)
        stackView.translatesAutoresizingMaskIntoConstraints = false

        addSubview(button)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setBackgroundImage(.highlightedButtonBackground, for: .highlighted)

        stackView.addArrangedSubview(imageView)
        stackView.addArrangedSubview(innerStackView)

        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true
        imageView.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
        imageView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)

        innerStackView.axis = .vertical
        innerStackView.isLayoutMarginsRelativeArrangement = true
        innerStackView.directionalLayoutMargins =
            .init(top: .defaultSpacing, leading: .defaultSpacing, bottom: .defaultSpacing, trailing: .defaultSpacing)
        innerStackView.spacing = .compactSpacing
        innerStackView.addArrangedSubview(titleLabel)
        innerStackView.addArrangedSubview(descriptionLabel)
        innerStackView.addArrangedSubview(urlLabel)

        titleLabel.font = .preferredFont(forTextStyle: .headline)
        titleLabel.adjustsFontForContentSizeCategory = true
        titleLabel.setContentCompressionResistancePriority(.required, for: .vertical)
        descriptionLabel.font = .preferredFont(forTextStyle: .subheadline)
        descriptionLabel.adjustsFontForContentSizeCategory = true
        descriptionLabel.setContentCompressionResistancePriority(.required, for: .vertical)
        urlLabel.font = .preferredFont(forTextStyle: .footnote)
        urlLabel.adjustsFontForContentSizeCategory = true
        urlLabel.setContentCompressionResistancePriority(.required, for: .vertical)
        urlLabel.textColor = .secondaryLabel

        NSLayoutConstraint.activate([
            stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
            stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
            stackView.topAnchor.constraint(equalTo: topAnchor),
            stackView.bottomAnchor.constraint(equalTo: bottomAnchor),
            button.leadingAnchor.constraint(equalTo: leadingAnchor),
            button.trailingAnchor.constraint(equalTo: trailingAnchor),
            button.topAnchor.constraint(equalTo: topAnchor),
            button.bottomAnchor.constraint(equalTo: bottomAnchor),
            imageView.heightAnchor.constraint(equalTo: innerStackView.heightAnchor),
            imageView.widthAnchor.constraint(equalTo: imageView.heightAnchor)
        ])
    }

    func setupAccessibility() {
        isAccessibilityElement = true
    }
}
