//
//  TabBar.swift
//  Tabbar
//
//  Created by lym on 2021/1/1.
//

import Lottie
import UIKit

protocol TabBarDelegate: AnyObject {
    func tabBar(_ tabBar: TabBar, didSelectItemAt index: TabBarItemIndex)
    func tabBar(_ tabBar: TabBar, canTapEnterItem index: TabBarItemIndex) -> Bool
}

class TabBar: UITabBar {
    weak var tabBarDelegate: TabBarDelegate?

    var tabItems: [TabbarItem]? {
        didSet {
            guard let items = tabItems else {
                return
            }
            containerStack.removeSubviews()
            for (index, item) in items.enumerated() {
                containerStack.addArrangedSubview(item)
                item.addTarget(self, action: #selector(clickItem), for: .touchUpInside)
                item.selectedStatus = index == 0
            }
        }
    }

    static let containerHeight: CGFloat = 49
    private var containerInsets = UIEdgeInsets(top: 20, left: 24, bottom: 24, right: 24)

    private var container: UIView = {
        let view = UIView()
        view.backgroundColor = .clear // clear
        return view
    }()

    private var containerStack: UIStackView = {
        let stack = UIStackView()
        stack.axis = .horizontal
        stack.distribution = .fillEqually
        stack.alignment = .fill
        stack.spacing = 0
        return stack
    }()

    private lazy var bgView: UIView = {
        let view = UIView()
//        view.backgroundColor = .c.csdn
        view.backgroundColor = .clear // clear
        return view
    }()

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

        if #available(iOS 13.0, *) {
            let appearance = self.standardAppearance.copy()
            appearance.backgroundImage = UIColor.clear.toImage() ?? UIImage()
            appearance.shadowImage = UIColor.clear.toImage() ?? UIImage()
            appearance.shadowColor = .clear
            appearance.configureWithTransparentBackground()
            self.standardAppearance = appearance
        } else {
            backgroundImage = UIColor.clear.toImage() ?? UIImage()
            shadowImage = UIColor.clear.toImage() ?? UIImage()
            isTranslucent = true
            barTintColor = .clear
        }
        
//        backgroundColor = .c.cbd
        backgroundColor = .clear
        
        let bgImgView = UIImageView(image: R.image.tabbar_bg_img())
        
        bgImgView.contentMode = .scaleToFill
        bgImgView.clipsToBounds = true
        addSubview(bgImgView)
        bgImgView.snp.makeConstraints { make in
            make.top.left.right.equalToSuperview()
        }

        addSubview(bgView)
        bgView.addSubview(container)
        container.layer.cornerRadius = TabBar.containerHeight / 2
        container.addSubview(containerStack)
        bringSubviewToFront(bgView)

        bgView.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(UIEdgeInsets.zero)
        }

        let bottom = safeAreaInsets.bottom > 0 ? safeAreaInsets.bottom : containerInsets.bottom
        container.snp.makeConstraints { make in
            make.height.equalTo(TabBar.containerHeight)
            make.left.right.equalToSuperview()
            make.bottom.equalToSuperview().offset(-bottom)
        }

        containerStack.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(UIEdgeInsets.zero)
        }
    }

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

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        if clipsToBounds || alpha == 0 || isHidden {
            return nil
        }
        for item in containerStack.arrangedSubviews.reversed() {
            let subPoint = item.convert(point, from: self)
            let imgPoint = (item as! TitleItem).imageView.convert(point, from: self)
            let flag = item.point(inside: subPoint, with: event)
            let flag2 = item.point(inside: imgPoint, with: event)
            if flag || flag2 {
                return item
            }
        }
        return super.hitTest(point, with: event)
    }

//    override func layoutSubviews() {
//        super.layoutSubviews()
//    }
}

extension TabBar {
    public func setSelected(selected _: Bool, index: TabBarItemIndex) {
        guard let items = tabItems else { return }
        items.forEach { item in
            if item.itemIndex == index {
                item.selectedStatus = true
                item.starAnimation()
            } else {
                item.selectedStatus = false
                item.stopAnimation()
            }
        }
    }

    public func setCount(count: Int, index: TabBarItemIndex) {
        guard let items = tabItems else { return }
        items.forEach { item in
            if item.itemIndex == index {
                item.count = count
            }
        }
    }
}

extension TabBar {
    @objc private func clickItem(_ sender: TitleItem) {
        switch sender.itemIndex {
        case .friend, .me, .discover, .home, .add:
            if let can = tabBarDelegate?.tabBar(self, canTapEnterItem: sender.itemIndex), can == true {
                setSelected(selected: true, index: sender.itemIndex)
                tabBarDelegate?.tabBar(self, didSelectItemAt: sender.itemIndex)
            }
            //        case .add:
            //            tabBarDelegate?.tabBar(self, didSelectItemAt: sender.itemIndex)
            //        }
        }
    }
}

// MARK: - TabBar item

enum TabBarItemIndex {
    case home
    case friend
    /// 额外的添加按钮
    case add
    case discover
    case me
    
}

enum TitleItemStyle {
    case small
    case large
}

protocol TabbarItem: UIControl {
    var selectedStatus: Bool { get set }
    var count: Int { get set }
    var itemIndex: TabBarItemIndex { get set }
    func starAnimation()
    func stopAnimation()
}

extension TabbarItem {
    func starAnimation() {}
    func stopAnimation() {}
}

class TitleItem: UIControl, TabbarItem {
    private var titleLabel: UILabel!
    //private var bage: PaddingLabel!
    private var badgeView: BadgeView!
//    private var lotiView: AnimationView!

    var imageView: UIImageView!
    var image: UIImage!
    var selectedImage: UIImage!
    var style: TitleItemStyle!
    var font = UIFont.t.tll // UIFont = .popSemiBold(size: 12)
    var selectedFont: UIFont = .t.tll // .popSemiBold(size: 12)
    var textColor: UIColor = .c.ctsn
    var selectedTextColor: UIColor = .white // .hexEF7000

    public var title: String {
        didSet {
            titleLabel.text = title
        }
    }

    public var count: Int = 0 {
        didSet {
            badgeView.isHidden = count <= 0
            badgeView.badgeValue = count// > 99 ? "99+" : "\(count)"
        }
    }

    public var selectedStatus: Bool = false {
        didSet {
            if selectedStatus {
                imageView.image = selectedImage
            } else {
                imageView.image = image
            }
        }
    }

    public var itemIndex: TabBarItemIndex

    init(title: String, image: UIImage,
         selectedImage: UIImage,
         count: Int = 0,
         style: TitleItemStyle = .small,
         itemIndex: TabBarItemIndex) {
        self.title = title
        self.count = count
        self.image = image
        self.selectedImage = selectedImage
        self.style = style
        self.itemIndex = itemIndex
        super.init(frame: CGRect.zero)
        setUpUI()
    }

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

    func setUpUI() {
        backgroundColor = .clear

        imageView = UIImageView()
        imageView.image = image
        imageView.contentMode = .scaleAspectFit
        addSubview(imageView)
        imageView.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.centerY.equalToSuperview()
        }

        badgeView = {
            let v = BadgeView()
            v.showMax99 = true
            addSubview(v)
            v.snp.makeConstraints { make in
                make.leading.equalTo(imageView.snp.trailing).offset(-8)
                make.top.equalTo(imageView).offset(-4)
            }
            return v
        }()
        
    }
}
