import datetime
import time
import sys
import echo_serial.serial_controller as EchoSerial
import echo_db.database as EchoDB
import _thread

class AirConditioner:

    @staticmethod
    def handle_action(device, action, data):
        actionData = device['actions'][action]
        collection = EchoDB.EchoDB.database['Devices']

        # Check if a thread is using the blinds, if so return.
        if device['status'] == "busy":
            return {'status': 'failed', 'message': 'Air Conditioner is being controlled by Echo, Please wait till finished.'}, 200

        if action == "on":

            if device['status'] == "on":
                return {'status': 'failed', 'message': 'Air conditioning is already on!'}, 200

            # Update Database
            collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'status': 'on' }})

            EchoSerial.EchoSerial.send_commmand(device, "power")
            return {'status': 'success', 'message': actionData['message']}, 200
        
        if action == "off":

            if device['status'] == "off":
                return {'status': 'failed', 'message': 'Air conditioning is already off!'}, 200

            EchoSerial.EchoSerial.send_commmand(device, "power")

            # Update Database
            collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'status': 'off' }})
            return {'status': 'success', 'message': actionData['message']}, 200

        if action == "set_fan_speed":
            selected_speed = data

            if selected_speed == {}:
                return {'status': 'failed', 'message': 'Please select a speed!'}, 200

            if selected_speed == device['fan_speed']:
                return {'status': 'failed', 'message': 'Fan speed already set to requested speed!'}, 200

            if device['status'] == "off":
                return {'status': 'failed', 'message': 'Air Conditioner must be on to change fan speeds!'}, 200

            EchoSerial.EchoSerial.send_commmand(device, "fanspeed")

            if device['fan_speed'] == "low":
                # We just put the speed to high
                collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'fan_speed': 'high' }})

            if device['fan_speed'] == "high":
                # We just put the speed to high
                collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'fan_speed': 'low' }})

            return {'status': 'success', 'message': actionData['message']}, 200

        if action == "set_mode":
            selected_mode = data

            if selected_mode == {}:
                return {'status': 'failed', 'message': 'Please select a mode!'}, 200

            if device['status'] == "off":
                return {'status': 'failed', 'message': 'Air Conditioniner must be on to change modes!'}, 200
            
            # Update Database
            collection = EchoDB.EchoDB.database['Devices']
            collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'status': 'busy' }})

            # Start thread because this action has waiting functions
            _thread.start_new_thread(AirConditioner.handleSetMode, ("Main Handle Set Mode Thread", 2, device, selected_mode))
            return {'status': 'success', 'message': actionData['message']}, 200
        
        if action == "set_temperature":
            selected_temperature = data

            if selected_temperature == {}:
                return {'status': 'failed', 'message': 'Please select a temperature!'}, 200

            if device['status'] == "off":
                return {'status': 'failed', 'message': 'Air Conditioning must be on to change target temperatures!'}, 200

            new_selected_temperature = int(selected_temperature)
            
            # Update Database
            collection = EchoDB.EchoDB.database['Devices']
            collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'status': 'busy' }})

            # Start thread because this action has waiting functions
            _thread.start_new_thread(AirConditioner.handleSetTemperature, ("Main Handle Set Temperature Thread", 2, device, new_selected_temperature))
            return {'status': 'success', 'message': actionData['message']}, 200

    @staticmethod
    def handleSetTemperature(threadName, delay, device, temperature):
        print('Started Air Conditioner Set Termperature Thread!')

        if device['target_temperature'] == temperature:
            # Update Database
            collection = EchoDB.EchoDB.database['Devices']
            collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'status': 'on' }})
            print('Exiting Air Conditioner Set Termperature Thread!')
            sys.exit()

        if temperature > device['target_temperature']:
            temperature_direction = "up"
            new_temperature_degrees = temperature - device['target_temperature']
        
        if temperature < device['target_temperature']:
            temperature_direction = "down"
            new_temperature_degrees = device['target_temperature'] - temperature
        
        # Plus one to init temp change on ac
        for x in range(new_temperature_degrees + 1):
            EchoSerial.EchoSerial.send_commmand(device, temperature_direction)
            time.sleep(.3)

        # Update Database
        collection = EchoDB.EchoDB.database['Devices']
        collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'status': 'on', 'target_temperature': temperature }})
        print('Exiting Air Conditioner Set Termperature Thread!')
    
    @staticmethod
    def handleSetMode(threadName, delay, device, mode):
        print('Started Air Conditioner Set Mode Thread!')

        if device['mode'] == mode:
            # Update Database
            collection = EchoDB.EchoDB.database['Devices']
            collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'status': 'on' }})
            print('Exiting Air Conditioner Set Mode Thread!')
            sys.exit()

        # Goto base Pos (cooling)
        if device['mode'] == "cooling":
            #Do nothing, already in cooling mode (base pos)
            pass

        if device['mode'] == "dehumidifying":
            # switch 2 times
            EchoSerial.EchoSerial.send_commmand(device, "mode")
            time.sleep(.3)
            EchoSerial.EchoSerial.send_commmand(device, "mode")
            time.sleep(.3)
        
        if device['mode'] == "blowing":
            # switch 1 time
            EchoSerial.EchoSerial.send_commmand(device, "mode")
            time.sleep(.3)
        
        # Do nothing, base pos is cooling
        if mode == "cooling":
            pass
        
        if mode == "dehumidifying":
            # switch 1 time
            EchoSerial.EchoSerial.send_commmand(device, "mode")
            time.sleep(.3)
        
        if mode == "blowing":
            # switch 2 times
            EchoSerial.EchoSerial.send_commmand(device, "mode")
            time.sleep(.3)
            EchoSerial.EchoSerial.send_commmand(device, "mode")
            time.sleep(.3)

        # Update Database
        collection = EchoDB.EchoDB.database['Devices']
        collection.update_one({'uuid': device['uuid']}, {"$set": { 'last_used': datetime.datetime.now(), 'status': 'on', 'mode': mode }})
        print('Exiting Air Conditioner Set Mode Thread!')