__author__ = 'algol'

import cherrypy
from jinja2 import Environment, PackageLoader
import memin.core as mc
from configparser import ConfigParser


class Menu:
    def __init__(self):
        self.menu = [
            {'name': 'Главная', 'link': '/'},
            {'name': 'Персоны', 'link': '/persons'},
            {'name': 'Залы', 'link': '/classrooms'},
            {'name': 'Занятия', 'link': '/lessons'},
            {'name': 'Типы платежей', 'link': '/payment_types'}
        ]


class FrontendBase:
    def __init__(self):
        self.env = Environment(loader=PackageLoader('memin', 'templates'))
        self.menu = Menu()

    def get_template(self, template_name='index.html'):
        return self.env.get_template(template_name)


class Main(FrontendBase):

    def __init__(self):
        super().__init__()

    @staticmethod
    def checkPassword(realm, username, password):
        c = ConfigParser()
        c.read('config.ini')
        users = {k: c['users'][k].strip("'") for k in c['users']}
        if password == users.get(username, None):
            return True
        return False

    @cherrypy.expose
    def index(self, name=''):
        return self.get_template('index.html').render(nick=name,
                                                      title='Main page',
                                                      h1='Главная страница',
                                                      menu=self.menu.menu
                                                      )

    @cherrypy.expose
    def halt(self):
        cherrypy.engine.exit()

    @cherrypy.expose
    def persons(self):
        return self.get_template('persons.html').render(
            title='Main page',
            h1='Персоны',
            menu=self.menu.menu,
            table_title='Персоны',
            url_prefix='person',
            ptypes=str({a.pk_value: a.name for a in mc.PaymentType.get_all()}),
            classrooms=str({a.pk_value: a.name for a in mc.Classroom.get_all()}),
            lessons=str({a.pk_value: a.name for a in mc.Lesson.get_all()})
        )

    @cherrypy.expose
    def payment_types(self):
        return self.get_template('payment_types.html').render(
            title='Типы платежей',
            h1='Типы платежей',
            menu=self.menu.menu,
            table_title='Типы платежей',
            url_prefix='ptype'
        )

    @cherrypy.expose
    def classrooms(self):
        return self.get_template('classrooms.html').render(
            title='Залы для занятий',
            h1='Залы для занятий',
            menu=self.menu.menu,
            table_title='список залов',
            url_prefix='classroom'
        )

    @cherrypy.expose
    def lessons(self):
        return self.get_template('lessons.html').render(
            title='Занятия',
            h1='Занятия',
            menu=self.menu.menu,
            table_title='Список занятий',
            url_prefix='lesson'
        )


class MeminCrud(FrontendBase):
    def __init__(self):
        super().__init__()

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def list(self, **args):
        raise Exception("Not implemented yet")

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def create(self, **args):
        raise Exception("Not implemented yet")

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def update(self, **args):
        raise Exception("Not implemented yet")

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def delete(self, **args):
        raise Exception("Not implemented yet")


class Person(MeminCrud):
    def __init__(self):
        super().__init__()

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def list(self, **args):
        prs = mc.Person.get_all()
        persons = [{'PersonID': p.pk_value,
                    'Fname': p.fname,
                    'Lname': p.lname,
                    'Phone': p.phone,
                    'Email': p.email,
                    'InsertDate': p.insert_date
                    } for p in prs]
        res = {'Result': 'OK' if prs else 'ERROR', 'Records': persons, 'Args': args}
        return res

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def create(self, **args):
        p = mc.Person(args['Fname'], args['Lname'], args['Phone'], args['Email'])
        args['PersonID'] = p.save()
        return {'Result': 'OK', 'Record': args}

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def update(self, **args):
        p = mc.Person.load(args['PersonID'])
        p.fname = args['Fname']
        p.lname = args['Lname']
        p.phone = args['Phone']
        p.email = args['Email']
        p.save()
        return {'Result': 'OK'}


class PaymentType(MeminCrud):
    def __init__(self):
        super().__init__()

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def list(self, **args):
        ptypes = mc.PaymentType.get_all()
        res = [{'Name': p.name,
                'Comment': p.comment,
                'PaymentTypeID': p.pk_value} for p in ptypes]
        return {'Result': 'OK' if ptypes else 'ERROR', 'Records': res}

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def create(self, **args):
        pt = mc.PaymentType(args['Name'], args['Comment'])
        args['PaymenTypeID'] = pt.save()
        return {'Result': 'OK', 'Record': args}

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def update(self, **args):
        pt = mc.PaymentType.load(args['PaymentTypeID'])
        pt.name = args['Name']
        pt.comment = args['Comment']
        pt.save()
        return {'Result': 'OK'}

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def delete(self, **args):
        raise Exception("Not implemented yet")


class Classroom(MeminCrud):
    def __init__(self):
        super().__init__()

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def list(self, **args):
        cl = mc.Classroom.get_all()
        res = [{'Name': c.name,
                'Address': c.address,
                'Comment': c.comment,
                'Active': c.active,
                'ClassroomID': c.pk_value} for c in cl]
        return {'Result': 'OK' if cl else 'ERROR', 'Records': res}

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def create(self, **args):
        cl = mc.Classroom(args['Name'],
                          args['Address'],
                          args['Comment'],
                          args['Active'] if 'Active' in args else 0
                          )
        args['ClassroomID'] = cl.save()
        return {'Result': 'OK', 'Record': args}

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def update(self, **args):
        cl = mc.Classroom.load(args['ClassroomID'])
        cl.comment = args['Comment']
        cl.name = args['Name']
        cl.active = args['Active'] if 'Active' in args else 0
        cl.address = args['Address']
        cl.save()
        return {'Result': 'OK'}

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def delete(self, **args):
        raise Exception("Not implemented yet")


class Lesson(MeminCrud):
    def __init__(self):
        super().__init__()

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def list(self, **args):
        lsns = mc.Lesson.get_all()
        res = [{'Name': l.name,
                'Comment': l.comment,
                'Duration': l.duration,
                'LessonID': l.pk_value
                } for l in lsns]
        return {'Result': 'OK' if lsns else 'ERROR', 'Records': res}

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def create(self, **args):
        l = mc.Lesson(args['Name'], args['Duration'], args['Comment'])
        args['LessonID'] = l.save()
        return {'Result': 'OK', 'Record': args}

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def update(self, **args):
        l = mc.Lesson.load(args['LessonID'])
        l.name = args['Name']
        l.comment = args['Comment']
        l.duration = args['Duration']
        l.save()
        return {'Result': 'OK'}

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def delete(self, **args):
        raise Exception("Not implemented yet")


class Payment(MeminCrud):
    def __init__(self):
        super().__init__()

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def list(self, **args):
        pl = mc.Payment.get_all({'PersonID': args['PersonID']})
        res = [{'PersonID': p.person_id,
                'PaymentType': p.payment_type_id,
                'PaymentTypeID': p.payment_type_id,
                'PaymentID': p.pk_value,
                'Amount': p.amount,
                'Date': '-'.join(reversed(p.date.split('.')))
                } for p in pl]
        return {'Result': 'OK' if pl else 'ERROR', 'Records': res}

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def create(self, **args):
        p = mc.Payment(args['PersonID'], args['Amount'], args['PaymentType'])
        args['PaymentID'] = p.save()
        args['Date'] = p.date
        return {'Result': 'OK', 'Record': args}

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def update(self, **args):
        raise Exception("Not implemented yet")

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def delete(self, **args):
        raise Exception("Not implemented yet")


class Visit(MeminCrud):
    def __init__(self):
        super().__init__()

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def list(self, PersonID, **args):
        visits = mc.Visit.get_all({'PersonID': PersonID})
        res = [{'VisitID': a.pk_value,
                'Classroom': a.classroom_id,
                'Lesson': a.lesson_id,
                'Date': '-'.join(reversed(a.date.split('.')))
                } for a in visits]
        return {'Result': 'OK' if visits else 'ERROR', 'Records': res}

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def create(self, **args):
        v = mc.Visit(args['PersonID'], args['Classroom'], args['Lesson'], args['Date'])
        args['VisitID'] = v.save()
        return {'Result': 'OK', 'Record': args}

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def update(self, **args):
        v = mc.Visit.load(args.get('VisitID'))
        if v:
            v.classroom_id = args['Classroom']
            v.lesson_id = args['Lesson']
            v.date = args['Date']
            v.save()
            return {'Result': 'OK'}
        return {'Result': 'ERROR'}

    @cherrypy.expose
    @cherrypy.tools.json_out()
    def delete(self, **args):
        raise Exception("Not implemented yet")
