from django.db import models
from django.utils import timezone
from datetime import datetime
from io import StringIO
import csv

class Member(models.Model):
    '''
    Member model represets one member on the registry
    '''

    first_name = models.CharField(max_length=127)
    last_name = models.CharField(max_length=127)
    email = models.EmailField()
    POR = models.CharField(max_length=255) # place of residence
    AYY = models.BooleanField(default=False)
    jas = models.BooleanField(default=False)
    created = models.DateTimeField(default=timezone.now)
    paid = models.DateTimeField(default=datetime.fromtimestamp(0))
    
    def get_dict(self):
        return {
            'id':self.id,
            'first_name':self.first_name,
            'last_name':self.last_name,
            'email':self.email,
            'POR':self.POR,
            'AYY':self.AYY,
            'jas':self.jas,
            'created':date2str(self.created),
            'paid':date2str(self.paid),
        }

    @classmethod
    def create_from_dict(cls,d):
        mbr = cls()
        mbr.update_from_dict(d)
        return mbr

    def update_from_dict(self,d):
        dmap = {
            'first_name': reverseMap('first_name'),
            'last_name': reverseMap('last_name'),
            'email': reverseMap('email'),
            'POR': reverseMap('POR'),
            'AYY': reverseMap('AYY'),
            'jas': reverseMap('jas'),
            'paid': reverseMap('paid',str2date),
        }
        for k,v in d.items():
            try:
                self.__setattr__(dmap[k].key,dmap[k].parser(v))
            except KeyError:
                pass
        self.save()
    @classmethod
    def import_csv(cls, csv_string):
        reader = csv.reader(StringIO(csv_string.strip()))
        response = {"status": "success", "errors": []};
        try:
            data = list(reader)
        except ValueError:
            return {"status": "failure", "errors": ["could not parse csv file"]}
        for row in data:
            try:
                obj = cls.objects.create(
                    first_name=row[0],
                    last_name=row[1],
                    email=row[2],
                    POR=row[3],
                    AYY=row[4].lower() in ['yes','y','1','true',"kyllä", "khyl"],
                    jas=row[5].lower() in ['yes','y','1','true',"kyllä", "khyl"],
                    paid = timezone.now()
                )
                print("added obj {}".format(obj))
            except:
                response["status"] = "failure"
                response["errors"].append("failure adding item {}".format(", ".join(row)))
        
        return response 

    def __str__(self):
        return "{} {}".format(self.first_name, self.last_name)

class MemberRequest(models.Model):
    member = models.ForeignKey(Member)

    def get_dict(self):
        return {
                'id': self.id,
                'member': self.member.get_dict(),
        }

def date2str(date):
    '''
    Convert date to a standard date string
    '''
    if date is None:
        return None
    return date.strftime("%Y-%m-%d %H:%M:%S")

def str2date(s):
    return datetime.strptime(s,"%Y-%m-%d %H:%M:%S")

class reverseMap:
    def __init__(self, key, parser=lambda x:x):
        self.key = key
        self.parser = parser

