//
//  ForecastTimePeriodControl.swift
//  1Weather
//
//  Created by Dmitry Stepanets on 15.02.2021.
//

import UIKit

enum TimePeriod: Int {
    case daily = 0
    case hourly = 1
}

class ForecastTimePeriodControl: UISegmentedControl {
    private let kTopInset: CGFloat = 2
    private let kSideInset:CGFloat = 11
    private var selectedIndexObserver:NSKeyValueObservation?

    override init(frame: CGRect) {
        super.init(frame: frame)
        prepare()
        updateUI()
    }
    
    override init(items: [Any]?) {
        super.init(items: items)
        prepare()
        updateUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override var backgroundColor: UIColor? {
        get {
            return super.backgroundColor
        }
        
        set {
            super.backgroundColor = ThemeManager.currentTheme.segmentBackgroundColor
        }
    }
    
    override func layoutSubviews(){
        super.layoutSubviews()
        
        layer.cornerRadius = 12
        
        if #available(iOS 13, *) {
            let foregroundIndex = numberOfSegments
            if subviews.indices.contains(foregroundIndex),
               let foregroundImageView = subviews[foregroundIndex] as? UIImageView
            {
                updateSegment(segmentImageView: foregroundImageView)
            }
        }
        else {
            iOS12UpdateSegments()
        }
    }
    
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        updateUI()
    }
    
    private func updateUI() {
        backgroundColor = ThemeManager.currentTheme.segmentBackgroundColor
        layer.borderColor = ThemeManager.currentTheme.segmentBorderColor.cgColor
        
        self.setTitleTextAttributes([.font : AppFont.SFPro.regular(size: 14),
                                     .foregroundColor: ThemeManager.currentTheme.segmentTextColor],
                                    for: .normal)
        self.setTitleTextAttributes([.font : AppFont.SFPro.bold(size: 14),
                                     .foregroundColor : ThemeManager.currentTheme.segmentSelectedTextColor],
                                    for: .selected)
    }
    
    private func updateSegment(segmentImageView: UIImageView) {
        let segmentWidth = segmentImageView.bounds.width - kSideInset
        let segmentHeight = self.frame.height - kTopInset * 2
        segmentImageView.bounds = CGRect(x: 0, y: 0, width: segmentWidth, height: segmentHeight)
        segmentImageView.layer.removeAnimation(forKey: "SelectionBounds") //this removes the weird scaling animation!
        segmentImageView.layer.masksToBounds = true
        segmentImageView.layer.cornerRadius = 9
        segmentImageView.clipsToBounds = false
        segmentImageView.layer.shadowColor = UIColor.black.cgColor
        segmentImageView.layer.shadowOpacity = 0.12
        segmentImageView.layer.shadowOffset = .init(width: 0, height: 3)
        segmentImageView.layer.shadowRadius = 8
        
        //substitute with our own colored image
        let imageFrame = CGRect(x: 0, y: 0, width: segmentWidth, height: segmentHeight)
        let rect = CGRect(origin: .zero, size: imageFrame.size)
        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = ThemeManager.currentTheme.segmentSelectedGradient.map{$0.cgColor}
        gradientLayer.bounds = imageFrame
        gradientLayer.cornerRadius = 9
        
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
        guard let ctx = UIGraphicsGetCurrentContext() else { return }
        gradientLayer.render(in: ctx)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        segmentImageView.image = image
    }

    
    private func iOS12UpdateSegments() {
        let sortedSubviews = subviews.sorted{$0.frame.origin.x < $1.frame.origin.x}
        for (index, subview) in sortedSubviews.enumerated() {
            let segmentWidth = subview.bounds.width - 2
            let segmentHeight = self.bounds.height - kTopInset * 2
            subview.bounds = CGRect(x: 0, y: 0, width: segmentWidth, height: segmentHeight)
            subview.layer.removeAnimation(forKey: "SelectionBounds") //this removes the weird scaling animation!
            subview.layer.cornerRadius = 9
            subview.clipsToBounds = false
            subview.layer.shadowColor = UIColor.black.cgColor
            subview.layer.shadowOpacity = 0.12
            subview.layer.shadowOffset = .init(width: 0, height: 3)
            subview.layer.shadowRadius = 8
            
            //substitute with our own colored image
            let imageFrame = CGRect(x: 0, y: 0, width: segmentWidth, height: segmentHeight)
            let rect = CGRect(origin: .zero, size: imageFrame.size)
            let gradientLayer = CAGradientLayer()
            gradientLayer.colors = ThemeManager.currentTheme.segmentSelectedGradient.map{$0.cgColor}
            gradientLayer.bounds = imageFrame
            gradientLayer.cornerRadius = 9
            
            UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
            guard let ctx = UIGraphicsGetCurrentContext() else { return }
            gradientLayer.render(in: ctx)
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            if selectedSegmentIndex == index {
                subview.backgroundColor = UIColor(patternImage: image!)
            }
            else {
                subview.backgroundColor = nil
            }
        }
    }
}

private extension ForecastTimePeriodControl {
    func prepare() {
        self.tintColor = .clear
        self.setDividerImage(UIImage(), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
        layer.borderWidth = 1 / UIScreen.main.scale
        
        self.selectedIndexObserver = self.observe(\.selectedSegmentIndex, options: .new) { (control, change) in
            if #available(iOS 13, *) {
                //do nothing
            }
            else {
                self.iOS12UpdateSegments()
            }
        }
    }
}
