from datetime import datetime as dt
import logging
import os

import simplematrixbotlib as botlib

from goals.db import Data, pretty_print


SERVER = os.environ.get('MATRIX_SERVER')
BOT_NAME = os.environ.get('GOAL_BOT')
BOT_PWD = os.environ.get('GOAL_BOT_PWD')

DATE_FORMAT = '%Y-%m-%d'

def today():
    return dt.now().strftime(DATE_FORMAT)

creds = botlib.Creds(SERVER, BOT_NAME, BOT_PWD)
bot = botlib.Bot(creds)
PREFIX = '!goal'

logger = logging.getLogger(__name__)
logging.basicConfig(filename='goals.log', encoding='utf-8', level=logging.DEBUG)
logging.getLogger('nio').setLevel(logging.WARNING)

async def do_goal(match):
    '''
    Prefix: !goal

    Synax:
        !goal COMMAND ARGS

    Commands:
      help - show this help
      add - add a goal
      add-task ID - add a task under the goal specified by ID
      list - list incomplete goals
      list-all - list everything
      print ID - print a goal and all tasks
      print-vision ID - print a vision and all goals
      done ID - mark task done by ID
      goal-done ID - mark goal done by ID
      set-vision GOAL_ID VISION_ID - associate GOAL_ID with VISION_ID
      visions - list incomplete visions

    '''

    try:

        if match.command('setup'):
            result = Data().setup()
            return [result]

        if match.command('add'):
            new = ' '.join(match.args()[1:])
            result = Data().add_goal(new)
            return [f'Goal added with id {result}']

        if match.command('list'):
            goals = Data().get_all_goals()
            results = ['Goals list...']
            for goal in goals:
                results.append(str(goal))
            return results

        if match.command('add-task'):
            goal_id = int(match.args()[1])
            new = ' '.join(match.args()[2:])
            result = Data().add_task(goal_id=goal_id, name=new)
            return [f'Added task with id {result}']

        if match.command('add-vision'):
            new = ' '.join(match.args()[1:])
            result = Data().add_vision(new)
            return [f'Vision added with id {result}']

        if match.command('print'):
            goal_id = int(match.args()[1])
            logger.debug(f'Searching for goal {goal_id}...')
            goal,tasks = Data().get_goal(goal_id)
            results = pretty_print(goal, tasks)
            return results


        if match.command('print-vision'):
            get_id = int(match.args()[1])
            vision,goals = Data().get_vision(get_id)
            results = pretty_print(vision, goals)
            return results

        if match.command('goal-done'):
            goal_id = int(match.args()[1])
            logger.debug(f'Searching for goal {goal_id}...')
            Data().complete_goal(goal_id)
            goal,tasks = Data().get_goal(goal_id)
            results = pretty_print(goal, tasks)
            return results
        

        if match.command('done'):
            task_id = int(match.args()[1])
            goal_id = Data().complete_task(task_id)
            goal,tasks = Data().get_goal(goal_id)
            results = pretty_print(goal, tasks)
            return results

        if match.command('list-all'):
            goals = Data().get_all_goals()
            results = ['Everything is...']
            for goal in goals:
                _,tasks = Data().get_goal(goal.id)
                details = pretty_print(goal, tasks)
                results += details
            return results

        if match.command('visions'):
            items = Data().get_all_visions()
            results = ['Visions are']
            if not items:
                results.append('-- No current visions --')

            for item in items:
                results.append(item)
            return results


        if match.command('set-vision'):
            goal_id = int(match.args()[1])
            vision_id = int(match.args()[1])
            Data().assign_vision(goal_id, vision_id)
            vision,goals = Data().get_vision(vision_id)
            results = pretty_print(vision, goals)
            return results

        return [do_goal.__doc__]
    except Exception as ex:
        return ['Ye cannot get ye flask.']

@bot.listener.on_message_event
async def goals(room, message):
    match = botlib.MessageMatch(room, message, bot, PREFIX)

    if not match.is_not_from_this_bot() and match.prefix():
        return

    if match.prefix():
        result_lines = await do_goal(match)
        for line in result_lines:
            await bot.api.send_text_message(
                room.room_id, str(line))


bot.run()

