//
//  FavouriteController.swift
//  Home
//
//  Created by Richard Kuckovsky on 21.4.17.
//  Copyright © 2017 Richard Kuckovsky. All rights reserved.
//

import UIKit
import Charts


class FavouriteSensorCellController: UITableViewCell {
    
    @IBOutlet weak var lbl_name: UILabel!
    @IBOutlet weak var lbl_value: UILabel!
    @IBOutlet weak var vw_chart: LineChartView!
    @IBOutlet weak var lbl_room: UILabel!
    
    var data = [Double]()
}

class FavouriteSwitchCellController: UITableViewCell {
    
    var switchDelegate: switchCellDelegate?
    
    @IBOutlet weak var lbl_room: UILabel!
    @IBOutlet weak var switch_label: UILabel!
    @IBOutlet weak var `switch`: UISwitch!
    @IBAction func switch_touch(_ sender: Any) {
        if let delegate = switchDelegate {
            delegate.switchCellTapped(index: (sender as AnyObject).tag, value: self.switch.isOn) { (done: Bool) -> Void in
                if(!done) {
                    self.switch.isOn = !self.switch.isOn
                }
            }
        }

    }

}

class FavouriteSliderCellController: UITableViewCell {
    
    var sliderDelegate: sliderCellDelegate?
    
    @IBOutlet weak var lbl_name: UILabel!
    @IBOutlet weak var lbl_room: UILabel!
    @IBOutlet weak var slider: UISlider!
    @IBAction func slider_action(_ sender: Any) {
        if let delegate = sliderDelegate {
            print((sender as AnyObject).tag)
            delegate.sliderCellTapped(index: (sender as AnyObject).tag, value: Int(self.slider.value)) { (done: Bool) -> Void in
                
            }
        }
    }
    
}

class FavouriteTermostatCellController: UITableViewCell {
    
    @IBOutlet weak var lbl_name: UILabel!
    @IBOutlet weak var lbl_room: UILabel!
    @IBOutlet weak var lbl_temp: UILabel!
    @IBOutlet weak var img_temp: UIImageView!

}

class FavouriteTableController: UITableViewController, switchCellDelegate, sliderCellDelegate, buttonCellDelegate, colorCellDelegate {
    
    var names = [String]()
    var outputs = [outputsType]()
    var sensors = [sensorsType]()
    var sections = [String]()
    
    let selectedCellHeight: CGFloat = 144.0
    let unselectedCellHeight: CGFloat = 44.0
    var selectedCellIndexPath: NSIndexPath?
    
    var sensors_selected = [Bool]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.outputs = []
        self.sensors = []
        var ids = [Int]()
        for room in rooms {
            for output in room.outputs {
                if(favourite_outputs.contains(output.id)) {
                    self.outputs.append(output)
                    ids.append(output.id)
                }
            }
            for sensor in room.sensors {
                if(favourite_sensors.contains(sensor.id)) {
                    self.sensors.append(sensor)
                }
            }
        }
        
        for _ in sensors {
            sensors_selected.append(false)
        }
        
        sections.removeAll()
        if(sensors.count > 0) {
            sections.append("sensors")
        }
        if(outputs.count > 0) {
            sections.append("outputs")
        }
        
        tableView.reloadData()
        
        SocketIOManager.sharedInstance.outputUpdate(ids: ids) { (id, value, temp) -> Void in
            
            let index = ids.index(of: id)!
            let room_index = self.outputs[index].room_index
            let output_index = self.outputs[index].output_index
            
            
            let indexPath : IndexPath = NSIndexPath(row: index, section: self.sections.index(of: "outputs")!) as IndexPath
            
            if(rooms[room_index].outputs[output_index].type == "switch") {
                let cell = self.tableView.cellForRow(at: indexPath) as! FavouriteSwitchCellController
                if(value == 0) {
                    cell.switch.setOn(false, animated: true)
                    rooms[room_index].outputs[output_index].value = 0
                } else {
                    cell.switch.setOn(true, animated: true)
                    rooms[room_index].outputs[output_index].value = 1
                }
            } else if(rooms[room_index].outputs[output_index].type == "termostat") {
                
                let cell = self.tableView.cellForRow(at: indexPath) as! FavouriteTermostatCellController
                if(value == 1) {
                    cell.img_temp.tintColor = UIColor(red: 1, green: 100/255, blue: 100/255, alpha: 1)
                } else {
                    cell.img_temp.tintColor = UIColor(red: 85/255, green: 85/255, blue: 85/255, alpha: 1)
                }
                cell.lbl_temp.text = String(temp) + "°C"
                
                rooms[room_index].outputs[output_index].value = value
                self.outputs[indexPath.row].value = value
                
            } else if(rooms[room_index].outputs[output_index].type == "slider") {
                
                let cell = self.tableView.cellForRow(at: indexPath) as! FavouriteSliderCellController
                cell.slider.setValue(Float(value), animated: true)
                rooms[room_index].outputs[output_index].value = value
                
            }
        }
        
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        SocketIOManager.sharedInstance.dismissOutputUpdate()
    }

    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return sections.count
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        if(sections[section] == "sensors") {
            return sensors.count
        } else if(sections[section] == "outputs") {
            return outputs.count
        }
        return 0
    }
    
    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        var title = ""
        
        if(sections[section] == "sensors") {
            title = "Senzory"
        } else if(sections[section] == "outputs") {
            title = "Výstupy"
        }
        
        return title
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var return_cell = UITableViewCell()

        if(sections[indexPath.section] == "sensors") {
            
            let cell = tableView.dequeueReusableCell(withIdentifier: "sensor") as! FavouriteSensorCellController
            
            
            if sensors_selected[indexPath.row] {
                cell.vw_chart.isHidden = false
            } else {
                cell.vw_chart.isHidden = true
            }
            
            cell.lbl_name.text = sensors[indexPath.row].name
            if(sensors[indexPath.row].type == "request") {
                cell.lbl_value.text = String(sensors[indexPath.row].value) + " " + sensors[indexPath.row].unit
            } else {
                if(sensors[indexPath.row].value < 30) {
                    cell.lbl_value.text = "pred 30 sekundami"
                } else if(sensors[indexPath.row].value < 60) {
                    cell.lbl_value.text = "pred minútou"
                } else if(sensors[indexPath.row].value < 120) {
                    cell.lbl_value.text = "pred 2 minútami"
                } else if(sensors[indexPath.row].value < 300) {
                    cell.lbl_value.text = "pred 5 minútami"
                } else if(sensors[indexPath.row].value < 900) {
                    cell.lbl_value.text = "pred 15 minútami"
                } else if(sensors[indexPath.row].value < 1800) {
                    cell.lbl_value.text = "pred 30 minútami"
                } else if(sensors[indexPath.row].value < 3600) {
                    cell.lbl_value.text = "pred hodinou"
                } else if(sensors[indexPath.row].value < 86400) {
                    cell.lbl_value.text = "dnes"
                } else if(sensors[indexPath.row].value < 172800) {
                    cell.lbl_value.text = "včera"
                } else {
                    cell.lbl_value.text = "viac ako 2 dni"
                }
                
            }
            
            cell.vw_chart.chartDescription?.text = ""
            cell.vw_chart.noDataText = "Niesu dostupné žiadne dáta"
            cell.vw_chart.backgroundColor = UIColor(red:255/255, green:255/255,blue:255/255,alpha:0)
            
            cell.vw_chart.xAxis.drawAxisLineEnabled = false
            cell.vw_chart.xAxis.drawLimitLinesBehindDataEnabled = false
            cell.vw_chart.xAxis.gridColor = UIColor(red:220/255, green:220/255,blue:220/255,alpha:1)
            cell.vw_chart.xAxis.gridLineWidth = 0.2
            cell.vw_chart.xAxis.drawGridLinesEnabled = true
            cell.vw_chart.xAxis.drawLabelsEnabled = true
            cell.vw_chart.xAxis.labelPosition = .bottomInside
            cell.vw_chart.xAxis.avoidFirstLastClippingEnabled = true
            
            if(sensors[indexPath.row].type == "request") {
                cell.vw_chart.leftAxis.axisMinimum = 10
                cell.vw_chart.leftAxis.axisMaximum = 30
            } else {
                cell.vw_chart.leftAxis.axisMinimum = 0
            }
            cell.vw_chart.leftAxis.removeAllLimitLines()
            cell.vw_chart.leftAxis.drawZeroLineEnabled = false
            cell.vw_chart.leftAxis.zeroLineWidth = 0
            cell.vw_chart.leftAxis.drawTopYLabelEntryEnabled = false
            cell.vw_chart.leftAxis.drawAxisLineEnabled = false
            cell.vw_chart.leftAxis.drawGridLinesEnabled = false
            cell.vw_chart.leftAxis.drawLabelsEnabled = false
            cell.vw_chart.leftAxis.drawLimitLinesBehindDataEnabled = false
            
            if(sensors[indexPath.row].type == "request") {
                cell.vw_chart.rightAxis.axisMinimum = 10
                cell.vw_chart.rightAxis.axisMaximum = 30
            } else {
                cell.vw_chart.rightAxis.axisMinimum = 0
            }
            cell.vw_chart.rightAxis.removeAllLimitLines()
            cell.vw_chart.rightAxis.drawZeroLineEnabled = false
            cell.vw_chart.rightAxis.drawTopYLabelEntryEnabled = true
            cell.vw_chart.rightAxis.drawAxisLineEnabled = false
            cell.vw_chart.rightAxis.drawGridLinesEnabled = false
            cell.vw_chart.rightAxis.drawLabelsEnabled = false
            cell.vw_chart.rightAxis.labelPosition = .insideChart
            cell.vw_chart.rightAxis.drawLimitLinesBehindDataEnabled = false
            cell.vw_chart.legend.enabled = false
            cell.vw_chart.minOffset = 0
            
            
            cell.vw_chart.scaleYEnabled = false
            cell.vw_chart.scaleXEnabled = false
            cell.vw_chart.pinchZoomEnabled = false
            cell.vw_chart.doubleTapToZoomEnabled = false
            
            cell.vw_chart.animate(yAxisDuration: 1.5, easingOption: .easeInOutQuart)
            
            let colors = [UIColor.red, UIColor.black, UIColor.blue, UIColor.brown, UIColor.cyan, UIColor.darkGray, UIColor.gray, UIColor.green, UIColor.lightGray, UIColor.magenta, UIColor.orange, UIColor.purple, UIColor.yellow]
            
            
            let gradColors = [colors[sensors[indexPath.row].color].cgColor, UIColor.clear.cgColor]
            let colorLocations:[CGFloat] = [0.0, 1.0]
            
            
            var dataEntries: [BarChartDataEntry] = []
            
            let date = Date()
            let calendar = Calendar.current
            let actual_hour = calendar.component(.hour, from: date)-1
            var xaxis = [String]()
            for i in 0 ..< cell.data.count {
                
                xaxis.append(String(((actual_hour + i < 24) ? (actual_hour + i) : (actual_hour + i-24))))
                let dataEntry = BarChartDataEntry(x: Double(i), y: Double(cell.data[i]))
                dataEntries.append(dataEntry)
            }
            
            cell.vw_chart.xAxis.valueFormatter = IndexAxisValueFormatter(values: xaxis)
            
            let chartDataSet = LineChartDataSet(values: dataEntries, label: "")
            chartDataSet.drawCirclesEnabled = false
            //chartDataSet.drawSteppedEnabled = true
            
            if(sensors[indexPath.row].type == "request") {
                chartDataSet.mode = .cubicBezier
            } else {
                chartDataSet.mode = .stepped
            }
            chartDataSet.drawFilledEnabled = true
            //chartDataSet.setDrawHighlightIndicators(false)
            
            chartDataSet.drawHorizontalHighlightIndicatorEnabled = false
            chartDataSet.highlightColor = UIColor(red:220/255, green:220/255,blue:220/255,alpha:1)
            chartDataSet.setColor(colors[sensors[indexPath.row].color].withAlphaComponent(0.5))
            chartDataSet.fillColor = NSUIColor(red: 255/255, green: 0/255, blue: 0/255, alpha: 1)
            
            
            //chartDataSet
            let chartData = LineChartData(dataSet: chartDataSet)
            
            if let gradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: gradColors as CFArray, locations: colorLocations) {
                chartDataSet.fill = Fill(linearGradient: gradient, angle: -90.0)
            }
            chartData.setDrawValues(false)
            chartData.setValueTextColor(NSUIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1))
            cell.vw_chart.data = chartData
            
            
            cell.lbl_room.text = rooms[sensors[indexPath.row].room_index].name
            
            return_cell = cell
            
        } else if(sections[indexPath.section] == "outputs") {
            
            if(outputs[indexPath.row].type == "switch") {
                let cell = tableView.dequeueReusableCell(withIdentifier: "switch") as! FavouriteSwitchCellController
                
                if cell.switchDelegate == nil {
                    cell.switchDelegate = self
                }
                
                cell.switch_label.text = outputs[indexPath.row].name
                cell.lbl_room.text = rooms[outputs[indexPath.row].room_index].name
                
                
                if(outputs[indexPath.row].value == 0) {
                    cell.switch.setOn(false, animated: false)
                } else {
                    cell.switch.setOn(true, animated: false)
                }
                cell.switch.tag = indexPath.row
                
                return_cell = cell
            } else if(outputs[indexPath.row].type == "termostat") {
                
                let cell = tableView.dequeueReusableCell(withIdentifier: "termostat") as! FavouriteTermostatCellController

                if(outputs[indexPath.row].value == 1) {
                    cell.img_temp.tintColor = UIColor(red: 1, green: 100/255, blue: 100/255, alpha: 1)
                } else {
                    cell.img_temp.tintColor = UIColor(red: 85/255, green: 85/255, blue: 85/255, alpha: 1)
                }
                cell.lbl_name.text = outputs[indexPath.row].name
                cell.lbl_temp.text = String(describing: outputs[indexPath.row].temp) + "°C"
                cell.lbl_room.text = rooms[outputs[indexPath.row].room_index].name
                
                return_cell = cell
                
            }  else if(outputs[indexPath.row].type == "slider") {
                let cell = tableView.dequeueReusableCell(withIdentifier: "slider") as! FavouriteSliderCellController
                
                
                if cell.sliderDelegate == nil {
                    cell.sliderDelegate = self
                }
                cell.slider.maximumValue = Float(outputs[indexPath.row].max_value)
                cell.slider.minimumValue = Float(outputs[indexPath.row].min_value)
                cell.slider.value = Float(outputs[indexPath.row].value)
                
                cell.lbl_name.text = outputs[indexPath.row].name
                cell.lbl_room.text = rooms[outputs[indexPath.row].room_index].name
                cell.slider.tag = indexPath.row
                
                return_cell = cell
            }
        }
        
        
    return return_cell
    }
    
    
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
    {
        if(sections[indexPath.section] == "sensors") {
            
            if (self.sensors_selected[indexPath.row]) {
                
                return selectedCellHeight
            }
        }
        return unselectedCellHeight
    }
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        if(sections[indexPath.section] == "sensors") {
            
            self.sensors_selected[indexPath.row] = !self.sensors_selected[indexPath.row]
            
            tableView.beginUpdates()
            tableView.endUpdates()
            
            if (self.sensors_selected[indexPath.row]) {
                // This ensures, that the cell is fully visible once expanded
                tableView.scrollToRow(at: indexPath, at: .none, animated: true)
            }
            
            SocketIOManager.sharedInstance.getTempGraph(id: self.sensors[indexPath.row].id, completionHandler: { (temps) in
                
                let cell = tableView.dequeueReusableCell(withIdentifier: "sensor", for: indexPath) as! FavouriteSensorCellController
                cell.vw_chart.isHidden = !self.sensors_selected[indexPath.row]
                cell.data = temps
                tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.fade)
                
            })
        }
        
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        if(segue.identifier == "termostat") {
            if let DestinationController = segue.destination as? TermostatViewController {
                
                let indexPath : NSIndexPath = self.tableView.indexPathForSelectedRow! as NSIndexPath
                
                DestinationController.output = outputs[indexPath.row]
                DestinationController.indexPath = indexPath
                DestinationController.origin = "favourite"
            }
        }
    }
    
    
    
    internal func switchCellTapped(index: Int, value: Bool, completionHandler: @escaping (_ status: Bool) -> Void) {
        var value_int : Int
        if(value) {
            value_int = self.outputs[index].max_value
        } else {
            value_int = self.outputs[index].min_value
        }
        SocketIOManager.sharedInstance.changeOutput(output: self.outputs[index], value: value_int) { (status) -> Void in
            completionHandler(status)
        }
    }
    
    internal func sliderCellTapped(index: Int, value: Int, completionHandler: @escaping (_ status: Bool) -> Void) {
        SocketIOManager.sharedInstance.changeOutput(output: self.outputs[index], value: value) { (status) -> Void in
            completionHandler(status)
        }
    }
    
    internal func buttonCellTapped(index: Int, value: Int) {
        SocketIOManager.sharedInstance.changeOutput(output: self.outputs[index], value: value) { (messageInfo) -> Void in
            print(messageInfo)
        }
    }
    
    internal func colorCellTapped(index: Int, value: Int) {
        SocketIOManager.sharedInstance.changeOutput(output: self.outputs[index], value: value) { (messageInfo) -> Void in
            print(messageInfo)
        }
    }
    
}
