# -*- coding: utf-8 -*-
from django.urls import reverse
from django.utils import timezone, timesince
from django.utils.translation import gettext as _

from core.models import DiaperChange, Feeding, Sleep, TummyTime
from datetime import timedelta


def get_objects(date, child=None):
    """
    Create a time-sorted dictionary of all events for a child.
    :param date: a DateTime instance for the day to be summarized.
    :param child: Child instance to filter results for (no filter if `None`).
    :returns: a list of the day's events.
    """
    min_date = date
    max_date = date.replace(hour=23, minute=59, second=59)
    events = []

    _add_diaper_changes(min_date, max_date, events, child)
    _add_feedings(min_date, max_date, events, child)
    _add_sleeps(min_date, max_date, events, child)
    _add_tummy_times(min_date, max_date, events, child)

    events.sort(key=lambda x: x['time'], reverse=True)

    return events


def _add_tummy_times(min_date, max_date, events, child=None):
    instances = TummyTime.objects.filter(
        start__range=(min_date, max_date)).order_by('-start')
    if child:
        instances = instances.filter(child=child)
    for instance in instances:
        details = []
        if instance.milestone:
            details.append(instance.milestone)
        edit_link = reverse('core:tummytime-update', args=[instance.id])
        events.append({
            'time': timezone.localtime(instance.start),
            'event': _('%(child)s started tummy time!') % {
                'child': instance.child.first_name
            },
            'details': details,
            'edit_link': edit_link,
            'model_name': instance.model_name,
            'type': 'start'
        })
        events.append({
            'time': timezone.localtime(instance.end),
            'event': _('%(child)s finished tummy time.') % {
                'child': instance.child.first_name
            },
            'details': details,
            'edit_link': edit_link,
            'duration': timesince.timesince(instance.start, now=instance.end),
            'model_name': instance.model_name,
            'type': 'end'
        })


def _add_sleeps(min_date, max_date, events, child=None):
    instances = Sleep.objects.filter(
        start__range=(min_date, max_date)).order_by('-start')
    if child:
        instances = instances.filter(child=child)
    for instance in instances:
        details = []
        if instance.notes:
            details.append(instance.notes)
        edit_link = reverse('core:sleep-update', args=[instance.id])
        events.append({
            'time': timezone.localtime(instance.start),
            'event': _('%(child)s fell asleep.') % {
                'child': instance.child.first_name
            },
            'details': details,
            'edit_link': edit_link,
            'model_name': instance.model_name,
            'type': 'start'
        })
        events.append({
            'time': timezone.localtime(instance.end),
            'event': _('%(child)s woke up.') % {
                'child': instance.child.first_name
            },
            'details': details,
            'edit_link': edit_link,
            'duration': timesince.timesince(instance.start, now=instance.end),
            'model_name': instance.model_name,
            'type': 'end'
        })


def _add_feedings(min_date, max_date, events, child=None):
    # Ensure first feeding has a previous.
    yesterday = min_date - timedelta(days=1)
    prev_start = None

    instances = Feeding.objects.filter(
        start__range=(yesterday, max_date)).order_by('start')
    if child:
        instances = instances.filter(child=child)
    for instance in instances:
        details = []
        if instance.notes:
            details.append(instance.notes)
        time_since_prev = None
        if prev_start:
            time_since_prev = \
                timesince.timesince(prev_start, now=instance.start)
        prev_start = instance.start
        if instance.start < min_date:
            continue
        edit_link = reverse('core:feeding-update', args=[instance.id])
        if instance.amount:
            details.append(_('Amount: %(amount).0f') % {
                'amount': instance.amount,
            })
        events.append({
            'time': timezone.localtime(instance.start),
            'event': _('%(child)s started feeding.') % {
                'child': instance.child.first_name
            },
            'details': details,
            'edit_link': edit_link,
            'time_since_prev': time_since_prev,
            'model_name': instance.model_name,
            'type': 'start'
        })
        events.append({
            'time': timezone.localtime(instance.end),
            'event': _('%(child)s finished feeding.') % {
                'child': instance.child.first_name
            },
            'details': details,
            'edit_link': edit_link,
            'duration': timesince.timesince(instance.start, now=instance.end),
            'model_name': instance.model_name,
            'type': 'end'
        })


def _add_diaper_changes(min_date, max_date, events, child):
    instances = DiaperChange.objects.filter(
        time__range=(min_date, max_date)).order_by('-time')
    if child:
        instances = instances.filter(child=child)
    for instance in instances:
        contents = []
        if instance.wet:
            contents.append('💧wet')
        if instance.solid:
            contents.append('💩solid')
        details = [_('Contents: %(contents)s') % {
            'contents': ', '.join(contents),
        }]
        if instance.notes:
            details.append(instance.notes)
        events.append({
            'time': timezone.localtime(instance.time),
            'event': _('%(child)s had a diaper change.') % {
                'child': instance.child.first_name
            },
            'details': details,
            'edit_link': reverse('core:diaperchange-update',
                                 args=[instance.id]),
            'model_name': instance.model_name
        })