# coding=utf8
import json
import datetime
import itertools

from django.contrib.auth.models import User
from django.db import models, connections
from django.utils import timezone
from gm_types.gaia import HOT_SEARCH_JUMP_TYPE, SEARCH_TAB_TYPE, SEARCH_ACTIVITY_TYPE
from django.forms.models import model_to_dict
from api.tool.log_tool import logging_exception


def grouper(iterable, size):
    it = iter(iterable)
    while True:
        chunk = tuple(itertools.islice(it, size))
        if not chunk:
            return
        yield chunk

def gen_update_sql(obj):
    meta = obj._meta
    pk_field = meta.get_field(meta.pk.name)
    db_table = meta.db_table
    conditions = '{pk} = %s'.format(pk=pk_field.column)
    fields = [(f.column, f.attname) for f in meta.concrete_fields if not f.primary_key]
    values = ', '.join(['%s = %s' % (f[0], '%s') for f in fields])
    fields.append((pk_field.column, pk_field.attname))
    update_sql = 'update {db_table} set {values} where {conditions}'.format(db_table=db_table, values=values, conditions=conditions)
    return update_sql, fields

def bulk_update(objs, batch_size=100, using='default'):
    bool = False;
    if not objs:
        return bool
    connection = connections[using]
    try:
        with connection.cursor() as cursor:
            update_sql, fields = gen_update_sql(objs[0])
            params = []
            for objs_batch in grouper(objs, batch_size):
                params[:] = []
                for obj in objs_batch:
                    _item = list()
                    for f in fields:
                        _v = getattr(obj, f[1])
                        if 'extract_config' in f and _v:
                            _item.append(json.dumps(_v))
                        else:
                            if isinstance(_v, unicode):
                                _v.encode('UTF-8')
                            _item.append(_v)
                        params.append(_item)
                cursor.executemany(update_sql, params)
                connection.commit()
        bool = True
    except Exception as e:
        logging_exception()
    finally:
        connection.close()
    return bool

class ALSearchRank(models.Model):
    # read only database
    class Meta:
        verbose_name = u'搜索词'
        db_table = 'al_search_rank'
    query = models.CharField(verbose_name=u'搜索词', max_length=128)
    search_cnt = models.IntegerField(verbose_name=u'搜索量')
    update_date = models.DateTimeField(verbose_name=u'更新时间', auto_now_add=True)


class SearchHotWords(models.Model):
    """
    master database
    """
    class Meta:
        verbose_name = u'外显搜索词'
        db_table = 'api_hot_search_words'

    keywords = models.CharField(verbose_name=u'搜索词', max_length=128)
    alias_name = models.CharField(verbose_name=u'搜索词别名', max_length=128)
    extract_config = models.CharField(verbose_name=u'额外配置', max_length=400)
    create_time = models.DateTimeField(verbose_name=u'创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name=u'更新时间', auto_now_add=True)
    is_delete = models.BooleanField(verbose_name=u'是否删除', auto_created=False)
    sorted = models.IntegerField(verbose_name=u'排序', auto_created=0)
    gm_url = models.CharField(verbose_name=u'更美URL', max_length=128)
    jump_type = models.CharField(u'跳转类型', max_length=3, choices=HOT_SEARCH_JUMP_TYPE,
                                 default=HOT_SEARCH_JUMP_TYPE.NORMAL)

    @property
    def format_dict(self):
        res = model_to_dict(self)
        if self.extract_config:
            res.update({'extract_config': json.loads(self.extract_config)})
        res.update({
            'create_time': self.create_time.strftime("%Y-%m-%d %H:%M:%S") if isinstance(self.create_time, datetime.datetime) else self.create_time,
            'update_time': self.update_time.strftime("%Y-%m-%d %H:%M:%S")}) if isinstance(self.update_time, datetime.datetime) else self.update_time
        return res

    @classmethod
    def batch_update(cls, data):
        objs = list()
        for item in data:
            _current_item = cls()
            for k, v in item.items():
                if k == 'extract_config':
                    _current_item.__setattr__(k, json.dumps(v))
                _current_item.__setattr__(k, v)
            objs.append(_current_item)
        count = bulk_update(objs)
        return count


class SearchActivity(models.Model):
    class Meta:
        verbose_name = u'hera后台搜索活动配置'
        db_table = 'api_search_activity'

    title = models.CharField(verbose_name=u'活动标题', max_length=128)
    image = models.CharField(verbose_name=u'活动图片', max_length=128, default='')
    jump_url = models.CharField(verbose_name=u'活动跳转', max_length=128, default='')
    sub_title = models.CharField(verbose_name=u'活动副标题', max_length=128, default='')
    tab = models.IntegerField(verbose_name=u'对应搜索tab', choices=SEARCH_TAB_TYPE, default=SEARCH_TAB_TYPE.ALL)
    keywords = models.CharField(verbose_name=u'搜索词', max_length=128, db_index=True)
    style = models.IntegerField(verbose_name=u'活动样式', choices=SEARCH_ACTIVITY_TYPE, default=0)
    is_online = models.BooleanField(default=False)
    start_time = models.DateTimeField()
    end_time = models.DateTimeField()
    operator = models.ForeignKey(User, verbose_name=u'操作人')
    update_time = models.DateTimeField(default=timezone.now())
    create_time = models.DateTimeField(auto_now_add=True)


class SearchSubActivity(models.Model):
    class Meta:
        verbose_name = u'hera后台搜索子活动配置'
        db_table = 'api_search_sub_activity'

    activity = models.ForeignKey(SearchActivity, verbose_name=u'关联主配置')
    title = models.CharField(verbose_name=u'子活动标题', max_length=128, default='')
    image = models.CharField(verbose_name=u'子活动图片', max_length=128, default='')
    jump_url = models.CharField(verbose_name=u'子活动跳转', max_length=128, default='')
