//
//  DaysControlView.swift
//  1Weather
//
//  Created by Dmitry Stepanets on 17.03.2021.
//

import UIKit

protocol DaysControlViewDelegate:class {
    func didSelectButtonAt(index:Int)
    func offsetDidChange(offset:CGFloat)
}

class DaysControlView: UIView {
    //Private
    private let scrollView = UIScrollView()
    private let stackView = UIStackView()
    private let gradientView = GradientView(startColor:UIColor(hex: 0xffffff).withAlphaComponent(0),
                                            endColor: UIColor(hex: 0xdaddec),
                                            opacity: 0.5)
    
    //Public
    weak var delegate:DaysControlViewDelegate?
    
    private var statusBarHeight: CGFloat {
       var statusBarHeight: CGFloat = 0
       if #available(iOS 13.0, *) {
           let window = UIApplication.shared.windows.filter{ $0.isKeyWindow }.first
           statusBarHeight = window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
       } else {
           statusBarHeight = UIApplication.shared.statusBarFrame.height
       }
        
       return statusBarHeight
   }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        prepareView()
        prepareScrollView()
        prepareStackView()
        updateUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        updateUI()
    }
    
    //Private
    private func updateUI() {
        gradientView.isHidden = interfaceStyle == .dark
        backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
    }
    
    @objc private func handleDayButton(button:DayControlButton) {
        guard let buttons = stackView.arrangedSubviews as? [DayControlButton] else { return }
        
        buttons.enumerated().forEach {
            $1.isSelected = $1 === button
            
            if $1.isSelected {
                self.delegate?.didSelectButtonAt(index: $0)
            }
        }
    }
    
    //Public
    public func configure(dailyWeather: [DailyWeather]) {
        stackView.removeAll()
        
        for index in 0..<dailyWeather.count {
            let button = DayControlButton()
            button.addTarget(self, action: #selector(handleDayButton(button:)), for: .touchUpInside)
            button.configure(dailyWeather: dailyWeather[index])
            button.isSelected = index == 0
            stackView.addArrangedSubview(button)
        }
        stackView.layoutIfNeeded()
    }
    
    public func selectDayAt(index:Int) {
        guard let buttons = stackView.arrangedSubviews as? [DayControlButton] else {
            return
        }
        
        buttons.enumerated().forEach {
            $1.isSelected = $0 == index
            
            if $1.isSelected {
                scrollView.scrollRectToVisible($1.frame, animated: true)
            }
        }
    }
    
    public func update(offset:CGFloat) {
        if self.scrollView.contentOffset.x != offset {
            self.scrollView.setContentOffset(.init(x: offset, y: 0), animated: false)
        }
    }
}

//MARK:- Prepare
private extension DaysControlView {
    func prepareView() {
        insertSubview(gradientView, at: 0)
        
        gradientView.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
    }
    
    func prepareScrollView() {
        scrollView.showsVerticalScrollIndicator = false
        scrollView.showsHorizontalScrollIndicator = false
        scrollView.delegate = self
        addSubview(scrollView)
        
        scrollView.snp.makeConstraints { (make) in
            make.top.equalToSuperview().inset(statusBarHeight)
            make.left.right.equalToSuperview()
            make.bottom.equalToSuperview().inset(18)
            make.height.greaterThanOrEqualTo(50)
        }
    }
    
    func prepareStackView() {
        stackView.axis = .horizontal
        stackView.distribution = .equalSpacing
        stackView.alignment = .center
        stackView.spacing = 10
        stackView.clipsToBounds = false
        stackView.isLayoutMarginsRelativeArrangement = true
        stackView.layoutMargins = .init(top: 0, left: 6, bottom: 0, right: 6)
        scrollView.addSubview(stackView)
        
        stackView.snp.makeConstraints { (make) in
            make.edges.height.equalToSuperview()
        }
    }
}

//MARK:- UIScrollView Delegate
extension DaysControlView: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        delegate?.offsetDidChange(offset: scrollView.contentOffset.x)
    }
}

//MARK:- Button
private class DayControlButton: UIControl {
    //Private
    private let dayLabel = UILabel()
    private static var dateFormatter:DateFormatter = {
        let fmt = DateFormatter()
        fmt.dateFormat = "d, E"
        return fmt
    }()
    
    //Public
    var index:Int = -1
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        //Button
        self.layer.cornerRadius = 8
        self.layer.borderColor = ThemeManager.currentTheme.periodButtonBorderColor.cgColor
        
        //Label
        dayLabel.font = AppFont.SFPro.regular(size: 14)
        dayLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
        dayLabel.textAlignment = .center
        addSubview(dayLabel)
        
        self.snp.makeConstraints { (make) in
            make.height.equalTo(50)
            make.width.equalTo(70)
        }
        
        dayLabel.snp.makeConstraints { (make) in
            make.centerY.equalToSuperview()
            make.left.right.equalToSuperview().inset(2)
        }
    }
    
    override var isSelected: Bool {
        didSet {
            if isSelected {
                self.backgroundColor = UIColor(hex: 0x1f67f3)
                self.layer.borderWidth = 0
                self.dayLabel.textColor = UIColor.white
                self.dayLabel.font = AppFont.SFPro.bold(size: 16)
            }
            else {
                self.backgroundColor = ThemeManager.currentTheme.periodButtonBackgroundColor
                self.layer.borderWidth = 1
                self.dayLabel.font = AppFont.SFPro.regular(size: 14)
                
                switch interfaceStyle {
                case .light:
                    self.dayLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
                case .dark:
                    self.dayLabel.textColor = ThemeManager.currentTheme.primaryTextColor
                }
            }
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        updateUI()
    }
    
    //Private
    private func updateUI() {
        self.layer.borderColor = ThemeManager.currentTheme.periodButtonBorderColor.cgColor
    }
    
    //Public
    func configure(dailyWeather: DailyWeather) {
        DayControlButton.dateFormatter.timeZone = dailyWeather.timeZone
        
        if Calendar.timeZoneCalendar(timeZone: dailyWeather.timeZone).isDateInToday(dailyWeather.date) {
            dayLabel.text = "day.today".localized()
        }
        else {
            dayLabel.text = DayControlButton.dateFormatter.string(from: dailyWeather.date)
        }
    }
}
