from datetime import datetime as dt
import logging
import os

import simplematrixbotlib as botlib

from .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')

def get_bot():
    creds = botlib.Creds(SERVER, BOT_NAME, BOT_PWD)
    return botlib.Bot(creds)

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

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

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
      extra.help - show extended help
      add - add a goal
      task ID - add a task under the goal specified by ID
      close.goal ID - mark goal done by ID
      done ID - mark task done by ID
      list - list incomplete goals
      print GOAL_ID - print a goal and all tasks
    '''
    ex_help = '''
      add.vision - add a new vision (collection of goals)
      close.vision ID - mark vision as complete by ID
      list.all - list everything
      print.vision ID - print a vision and all goals
      set.vision GOAL_ID VISION_ID- associate GOAL_ID with VISION_ID
      visions - list incomplete visions
      list.done - list completed goals
      visionless - list goals with no set vision
    '''

    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('list.done'):
        goals = Data().get_done_goals()
        results = ['# Completed Goals...']
        for goal in goals:
            results.append(str(goal))
        return results

    if match.command('task'):
        new = ' '.join(match.args()[1:])
        goal_id  = Data().quick_add_task(new)
        goal,tasks = Data().get_goal(goal_id)
        results = pretty_print(goal, tasks)
        return results

    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'):
        if len(match.args()) > 1:
            goal_id = int(match.args()[1])
        else:
            goal_id = Data()._get_pref_goal_id()

        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('close.goal'):
        goal_id = int(match.args()[1])
        vision_id = Data().complete_goal(goal_id)
        vision,goals = Data().get_vision(vision_id)
        results = pretty_print(vision, goals)
        return results

    if match.command('close.vision'):
        vision_id = int(match.args()[1])
        Data().complete_vision(vision_id)
        vision,goals = Data().get_vision(vision_id)
        results = pretty_print(vision, goals)
        return results

    if match.command('done'):
        ids = match.args()[1:]
        for task_id in ids:
            goal_id = Data().complete_task(int(task_id))
        # Print the goal of the last closed task
        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']
        if not items:
            results.append('-- No current visions --')

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

    if match.command('visionless'):
        items = Data().visionless()
        results = ['# Goals with no vision']
        if not items:
            results.append('-- No visionless goals --')

        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()[2])
        Data().assign_vision(goal_id=goal_id, vision_id=vision_id)
        vision,goals = Data().get_vision(vision_id)
        results = pretty_print(vision, goals)
        return results


    if match.command('rename'):
        goal_id = int(match.args()[1])
        name = ' '.join(match.args()[2:])
        Data().rename_goal(goal_id=goal_id, name=name)
        goal,tasks = Data().get_goal(goal_id)
        results = pretty_print(goal, tasks)
        return results

    if match.command('extra.help'):
        return [ex_help]

    # Help text
    return [do_goal.__doc__]

async def goal_bot(room, message, bot):
    match = botlib.MessageMatch(room, message, bot, PREFIX)

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

    try:
        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))
    except Exception as ex:
        line ='Ye cannot get ye flask.'
        await bot.api.send_text_message(
                    room.room_id, str(line))
        await bot.api.send_text_message(
                    room.room_id, str(ex))
 

