//
//  DropShawdowViewController.swift
//  VDSSample
//
//  Created by Matt Bruce on 6/13/23.
//

import Foundation
import UIKit
import VDS
import VDSColorTokens
import Combine

class DropShadowViewController: BaseViewController<ShadowView> {
    var viewPaddingRange = Slider()
    var viewRadiusRange = Slider()
    var viewSpacerRange = Slider()

    //shadow 1
    var showShadow = Toggle()
    var opacityRange = Slider()
    var radiusRange = Slider()
    var offsetXRange = Slider()
    var offsetYRange = Slider()

    //shadow 2
    var showShadow2 = Toggle()
    var opacityRange2 = Slider()
    var radiusRange2 = Slider()
    var offsetXRange2 = Slider()
    var offsetYRange2 = Slider()

    var viewSize: CGFloat = 100.0
    var componentWrapper: UIView!
    var componentConstraints: NSLayoutConstraint.Container!
    
    var secondView = View()
    var thirdView = View()

    lazy var dropShadowLightColorPickerSelectorView = {
        PickerSelectorView(title: "",
                           picker: self.picker,
                           items: UIColor.VDSColor.allCases)
    }()
    
    lazy var dropShadowDarkColorPickerSelectorView = {
        PickerSelectorView(title: "",
                           picker: self.picker,
                           items: UIColor.VDSColor.allCases)
    }()
    
    lazy var dropShadow2LightColorPickerSelectorView = {
        PickerSelectorView(title: "",
                           picker: self.picker,
                           items: UIColor.VDSColor.allCases)
    }()
    
    lazy var dropShadow2DarkColorPickerSelectorView = {
        PickerSelectorView(title: "",
                           picker: self.picker,
                           items: UIColor.VDSColor.allCases)
    }()
    
    lazy var viewLightColorPickerSelectorView = {
        PickerSelectorView(title: "",
                           picker: self.picker,
                           items: UIColor.VDSColor.allCases)
    }()
    
    lazy var viewDarkColorPickerSelectorView = {
        PickerSelectorView(title: "",
                           picker: self.picker,
                           items: UIColor.VDSColor.allCases)
    }()
    
    var spacer: CGFloat = 0 {
        didSet {
            spacings.forEach{ $0.constant = spacer }
        }
    }

    var viewPadding: CGFloat = 0 {
        didSet {
            componentConstraints.topConstraint?.constant = viewPadding
            componentConstraints.leadingConstraint?.constant = viewPadding
            componentConstraints.trailingConstraint?.constant = -viewPadding
            componentConstraints.bottomConstraint?.constant = -viewPadding
        }
    }

    var spacings = [NSLayoutConstraint]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let label1 = Label().with { $0.text = "View 1"; $0.textAlignment = .center}
        let label2 = Label().with { $0.text = "View 2"; $0.textAlignment = .center}
        let label3 = Label().with { $0.text = "View 3"; $0.textAlignment = .center}

        component.addSubview(label1)
        label1.pinToSuperView()
        
        secondView.addSubview(label2)
        label2.pinToSuperView()
        
        thirdView.addSubview(label3)
        label3.pinToSuperView()
        
        let wrapper = UIView.makeWrapperWithConstraints(for: component, isTrailing: false)
        componentWrapper = wrapper.view
        componentConstraints = wrapper.container
        
        contentTopView.addSubview(secondView)
        contentTopView.addSubview(thirdView)
        contentTopView.addSubview(componentWrapper)

        component.width(viewSize).height(viewSize)
        secondView.width(viewSize).height(viewSize)
        thirdView.width(viewSize).height(viewSize)

        componentWrapper.pinTop().pinLeading()
        secondView.pinTop()
        thirdView.pinLeading().pinBottom()
        
        secondView.pinTrailingLessThanOrEqualTo(contentTopView.trailingAnchor)
        secondView.pinBottomLessThanOrEqualTo(contentTopView.bottomAnchor)
        thirdView.pinTrailingLessThanOrEqualTo(contentTopView.trailingAnchor)
        
        spacings.append(thirdView.pinTop(anchor: componentWrapper.bottomAnchor)!)
        spacings.append(secondView.pinLeading(anchor: componentWrapper.trailingAnchor)!)

        viewPadding = 10
        spacer = 10
        
        component.setNeedsUpdate()
        
        setupPicker()
        setupModel()
        updateView()
    }
    
    override func showDebug(show: Bool) {
        super.showDebug(show: show)
        component.debugBorder(show: false)
        componentWrapper.debugBorder(show: show, color: .green)
        secondView.debugBorder(show: show, color: .green)
        thirdView.debugBorder(show: show, color: .green)
    }
        
    override func setupForm(){
        super.setupForm()
        formStackView.title = "Screen Settings"
        addFormRow(label: "Surface", view: surfacePickerSelectorView)
        addFormRow(label: "Space Between 1,2,3", view: viewSpacerRange)

        let form1 = FormSection()
        form1.title = "View 1 Settings"
        form1.addFormRow(label: "All ", view: viewPaddingRange)
        form1.addFormRow(label: "Padding", view: viewPaddingRange)
        form1.addFormRow(label: "Corner Radius", view: viewRadiusRange)
        form1.addFormRow(label: "Light", view: viewLightColorPickerSelectorView)
        form1.addFormRow(label: "Dark", view: viewDarkColorPickerSelectorView)
        
        let form2 = FormSection()
        form2.title = "View 1 Shadow Settings"
        form2.addFormRow(label: "Show", view: .makeWrapper(for: showShadow))
        form2.addFormRow(label: "Shawdow Light", view: dropShadowLightColorPickerSelectorView)
        form2.addFormRow(label: "Shawdow Dark", view: dropShadowDarkColorPickerSelectorView)
        form2.addFormRow(label: "Radius (Blur)", view: radiusRange)
        form2.addFormRow(label: "Width (OffSet X)", view: offsetXRange)
        form2.addFormRow(label: "Height (Offset Y)", view: offsetYRange)
        form2.addFormRow(label: "Opacity", view: opacityRange)

        let form3 = FormSection()
        form3.title = "View 1 Shadow 2 Settings"
        form3.addFormRow(label: "Show", view: .makeWrapper(for: showShadow2))
        form3.addFormRow(label: "Shawdow Light", view: dropShadow2LightColorPickerSelectorView)
        form3.addFormRow(label: "Shawdow Dark", view: dropShadow2DarkColorPickerSelectorView)
        form3.addFormRow(label: "Radius (Blur)", view: radiusRange2)
        form3.addFormRow(label: "Width (OffSet X)", view: offsetXRange2)
        form3.addFormRow(label: "Height (Offset Y)", view: offsetYRange2)
        form3.addFormRow(label: "Opacity", view: opacityRange2)


        append(section: form1)
        append(section: form2)
        append(section: form3)

        //shadow1
        showShadow.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
            self?.component.showShadow = slider.isOn
            self?.updateView()
        }).store(in: &subscribers)
        
        opacityRange.maximumValue = 1.0
        opacityRange.minimumValue = 0.0
        opacityRange.value = 1.0
        opacityRange.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
            self?.component.opacityRange = CGFloat(slider.value)
            self?.updateView()
        }).store(in: &subscribers)
        
        radiusRange.maximumValue = 20.0
        radiusRange.minimumValue = 0.0
        radiusRange.value = 2.0
        radiusRange.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
            self?.component.radiusRange = CGFloat(slider.value)
            self?.updateView()
        }).store(in: &subscribers)

        offsetXRange.maximumValue = 20
        offsetXRange.minimumValue = -20
        offsetXRange.value = 2.0
        offsetXRange.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
            self?.component.offsetXRange = CGFloat(slider.value)
            self?.updateView()
        }).store(in: &subscribers)
        
        offsetYRange.maximumValue = 20
        offsetYRange.minimumValue = -20
        offsetYRange.value = 2.0
        offsetYRange.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
            self?.component.offsetYRange = CGFloat(slider.value)
            self?.updateView()
        }).store(in: &subscribers)
                      
        //shadow2
        showShadow2.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
            self?.component.showShadow2 = slider.isOn
            self?.updateView()
        }).store(in: &subscribers)
        
        opacityRange2.maximumValue = 1.0
        opacityRange2.minimumValue = 0.0
        opacityRange2.value = 1.0
        opacityRange2.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
            self?.component.opacityRange2 = CGFloat(slider.value)
            self?.updateView()
        }).store(in: &subscribers)
        
        radiusRange2.maximumValue = 20.0
        radiusRange2.minimumValue = 0.0
        radiusRange2.value = 2.0
        radiusRange2.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
            self?.component.radiusRange2 = CGFloat(slider.value)
            self?.updateView()
        }).store(in: &subscribers)

        offsetXRange2.maximumValue = 20
        offsetXRange2.minimumValue = -20
        offsetXRange2.value = 2.0
        offsetXRange2.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
            self?.component.offsetXRange2 = CGFloat(slider.value)
            self?.updateView()
        }).store(in: &subscribers)
        
        offsetYRange2.maximumValue = 20
        offsetYRange2.minimumValue = -20
        offsetYRange2.value = 2.0
        offsetYRange2.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
            self?.component.offsetYRange2 = CGFloat(slider.value)
            self?.updateView()
        }).store(in: &subscribers)
        
        //view
        viewPaddingRange.maximumValue = 50.0
        viewPaddingRange.minimumValue = 0.0
        viewPaddingRange.value = 2.0
        viewPaddingRange.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
            self?.viewPadding = CGFloat(slider.value)
            self?.updateView()
        }).store(in: &subscribers)
        
        viewRadiusRange.maximumValue = Float(viewSize / 2)
        viewRadiusRange.minimumValue = 0
        viewRadiusRange.value = 8.0
        viewRadiusRange.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
            self?.component.viewRadiusRange = CGFloat(slider.value)
            self?.updateView()
        }).store(in: &subscribers)
        
        viewSpacerRange.maximumValue = 50
        viewSpacerRange.minimumValue = 0
        viewSpacerRange.value = 10.0        
        viewSpacerRange.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
            self?.spacer = CGFloat(slider.value)
        }).store(in: &subscribers)
                
        dropShadowLightColorPickerSelectorView.text = component.shadowLightColor.rawValue
        dropShadowDarkColorPickerSelectorView.text = component.shadowDarkColor.rawValue
        dropShadow2LightColorPickerSelectorView.text = component.shadowLightColor2.rawValue
        dropShadow2DarkColorPickerSelectorView.text = component.shadowDarkColor2.rawValue
        viewLightColorPickerSelectorView.text = component.viewLightColor.rawValue
        viewDarkColorPickerSelectorView.text = component.viewDarkColor.rawValue
        surfacePickerSelectorView.text = component.surface.rawValue

        showShadow.isOn = component.showShadow
        showShadow2.isOn = component.showShadow2
    }
    
    func setupModel() {
        //setup UI
        

    }
    
    override func updateView() {
        secondView.backgroundColor = .red
        thirdView.backgroundColor = .purple
    }
    
    func setupPicker(){

        surfacePickerSelectorView.onPickerDidSelect = {  [weak self] item in
            self?.contentTopView.backgroundColor = item.color
            self?.updateView()
        }
                
        dropShadowDarkColorPickerSelectorView.onPickerDidSelect = {  [weak self] item in
            self?.component.shadowDarkColor = item
        }
        
        dropShadowLightColorPickerSelectorView.onPickerDidSelect = {  [weak self] item in
            self?.component.shadowLightColor = item
        }

        dropShadow2DarkColorPickerSelectorView.onPickerDidSelect = {  [weak self] item in
            self?.component.shadowDarkColor2 = item
        }
        
        dropShadow2LightColorPickerSelectorView.onPickerDidSelect = {  [weak self] item in
            self?.component.shadowLightColor2 = item
        }
        viewLightColorPickerSelectorView.onPickerDidSelect = {  [weak self] item in
            self?.component.viewLightColor = item
        }

        viewDarkColorPickerSelectorView.onPickerDidSelect = {  [weak self] item in
            self?.component.viewDarkColor = item
        }
    }
}

public class ShadowView: View {

    public var viewLightColor: UIColor.VDSColor = .paletteGray65 { didSet { setNeedsUpdate() }}
    public var viewDarkColor: UIColor.VDSColor = .backgroundPrimaryLight { didSet { setNeedsUpdate() }}

    public var viewRadiusRange: CGFloat = 8.0 { didSet { setNeedsUpdate() }}

    private var shadowLayer1: CALayer = CALayer()
    public var showShadow: Bool = true { didSet { setNeedsUpdate() }}
    public var opacityRange: CGFloat = 1.0 { didSet { setNeedsUpdate() }}
    public var offsetXRange: CGFloat = 2.0 { didSet { setNeedsUpdate() }}
    public var offsetYRange: CGFloat = 2.0 { didSet { setNeedsUpdate() }}
    public var radiusRange: CGFloat = 2.0 { didSet { setNeedsUpdate() }}
    public var shadowLightColor: UIColor.VDSColor = .backgroundPrimaryDark { didSet { setNeedsUpdate() }}
    public var shadowDarkColor: UIColor.VDSColor = .backgroundPrimaryLight { didSet { setNeedsUpdate() }}

    private var shadowLayer2: CALayer = CALayer()
    public var showShadow2: Bool = false { didSet { setNeedsUpdate() }}
    public var opacityRange2: CGFloat = 1.0 { didSet { setNeedsUpdate() }}
    public var offsetXRange2: CGFloat = 2.0 { didSet { setNeedsUpdate() }}
    public var offsetYRange2: CGFloat = 2.0 { didSet { setNeedsUpdate() }}
    public var radiusRange2: CGFloat = 2.0 { didSet { setNeedsUpdate() }}
    public var shadowLightColor2: UIColor.VDSColor = .backgroundPrimaryDark { didSet { setNeedsUpdate() }}
    public var shadowDarkColor2: UIColor.VDSColor = .backgroundPrimaryLight { didSet { setNeedsUpdate() }}

    public override func setup() {
        super.setup()
        width(constant: 100)
        height(constant: 100)
        
        // Add shadow layers as sublayers of the view's layer
        layer.insertSublayer(shadowLayer1, at: 0)
        layer.insertSublayer(shadowLayer2, at: 0)
    }
    
    public override func updateView() {
        super.updateView()
        let viewColor = SurfaceColorConfiguration(viewLightColor.uiColor, viewDarkColor.uiColor).getColor(surface)
        backgroundColor = viewColor
        shadowLayer1.backgroundColor = viewColor.cgColor
        shadowLayer2.backgroundColor = viewColor.cgColor
        shadowLayer1.isHidden = !showShadow
        shadowLayer2.isHidden = !showShadow2
        setNeedsLayout()
        layoutIfNeeded()
    }
    
    
    public override func layoutSubviews() {
        super.layoutSubviews()
        
        let dropshadowColor = SurfaceColorConfiguration(shadowLightColor.uiColor, shadowDarkColor.uiColor).getColor(surface)
        let dropshadowColor2 = SurfaceColorConfiguration(shadowLightColor2.uiColor, shadowDarkColor2.uiColor).getColor(surface)
        layer.cornerRadius = CGFloat(viewRadiusRange)
        layer.masksToBounds = false
        
        // Update shadow layers frames to match the view's bounds
        shadowLayer1.frame = bounds
        shadowLayer2.frame = bounds

        shadowLayer1.cornerRadius = CGFloat(viewRadiusRange)
        shadowLayer1.shadowColor =  dropshadowColor.cgColor
        shadowLayer1.shadowOpacity = Float(opacityRange)
        shadowLayer1.shadowOffset = .init(width: CGFloat(offsetXRange), height: CGFloat(offsetYRange))
        shadowLayer1.shadowRadius = CGFloat(radiusRange)
        
        shadowLayer2.cornerRadius = CGFloat(viewRadiusRange)
        shadowLayer2.shadowColor = dropshadowColor2.cgColor
        shadowLayer2.shadowOpacity = Float(opacityRange2)
        shadowLayer2.shadowOffset = .init(width: CGFloat(offsetXRange2), height: CGFloat(offsetYRange2))
        shadowLayer2.shadowRadius = CGFloat(radiusRange2)
    }
}
