import random
from django.db import models
from django.utils.timezone import now, localtime
import datetime
from utils import const
import utils



class Recipe(models.Model):
  name = models.CharField(max_length=128)
  recipe_type = models.CharField(max_length=32,
                                 default=const.RECIPE_TYPE_MEAT)
  note = models.TextField(null=True)
  rate = models.IntegerField(default=0)
  difficulty = models.IntegerField(default=0)

  def serialize(self, verbose=False):
    data = {
      'id': self.id,
      'name': self.name,
      'recipe_type': self.recipe_type,
    }
    if verbose:
      data.update({
        'difficulty': self.difficulty,
        'rate': self.rate,
        'note': self.note,
      })

    return data


class DailyRecipe(models.Model):
  recipes = models.ManyToManyField(Recipe)
  date = models.DateField()
  meal_type = models.CharField(
    max_length=32,
    default=const.DAILY_RECIPE_MEAL_TYPE_SUPPER,)

  def generate_recipe(self, prev_recipes=None, ignore_prev=False):
    if not prev_recipes:
      prev_recipes = []
    if ignore_prev:
      prev_recipes = []

    recipes = []
    retry = 5

    # meat
    for x in range(0,2):
      while True:
        recipe = Recipe.objects.filter(
          recipe_type=const.RECIPE_TYPE_MEAT,
        ).order_by('?').first()
        if recipe and recipe.id not in recipes and recipe.id not in prev_recipes:
          recipes.append(recipe.id)
          break
        else:
          retry -= 1
        if retry <= 0:
          retry = 5
          break

    # vegetable
    for x in range(0, 1):
      while True:
        recipe = Recipe.objects.filter(
          recipe_type=const.RECIPE_TYPE_VEGETABLE,
        ).order_by('?').first()
        if recipe and recipe.id not in recipes and recipe.id not in prev_recipes:
          recipes.append(recipe.id)
          break
        else:
          retry -= 1
        if retry <= 0:
          retry = 5
          break

    # soup
    if random.randint(0,2):
      recipe = Recipe.objects.filter(
        recipe_type=const.RECIPE_TYPE_SOUP,
      ).order_by('?').first()
      # if recipe not in recipes and recipe not in prev_recipes:
      if recipe:
        recipes.append(recipe.id)

    self.recipes.set(Recipe.objects.filter(id__in=recipes))

  def serialize(self):
    data = {
      const.RECIPE_TYPE_MEAT: [],
      const.RECIPE_TYPE_VEGETABLE: [],
      const.RECIPE_TYPE_SOUP: [],
    }
    for key_, value_ in data.items():
      for recipe in self.recipes.filter(
          recipe_type=key_).order_by('id'):
        value_.append(recipe.serialize())

    date = now()
    date = date.replace(year=self.date.year, month=self.date.month,
                        day=self.date.day, hour=0, minute=0)
    data['date'] = utils.timestamp_of(utils.day_start(date))
    data['id'] = self.id
    return data

  @classmethod
  def get_week_recipe_data(cls):
    today = localtime()
    week_start = (today - datetime.timedelta(days=today.weekday())).date()
    week_end = week_start + datetime.timedelta(days=6)
    daily_recipes = cls.objects.filter(
      date__gte=week_start,
      date__lte=week_end,
    ).order_by('date')
    data = [{}] * (7 - len(daily_recipes))

    for daily_recipe in daily_recipes:
      data.append(daily_recipe.serialize())
    return data
