from __future__ import unicode_literals

import csv
import io
import json
import logging
import math
import os
from collections import OrderedDict

from django.core.cache import cache
from django.http import Http404
from django.http import HttpResponse
from django.http.response import FileResponse
from django.template.defaultfilters import slugify
from django.utils import translation
from django.utils.translation import get_language_from_request
from django.utils.translation import pgettext
from le_utils.constants import content_kinds

from .models import ContentSessionLog
from .models import ContentSummaryLog
from kolibri.core.auth.models import Facility
from kolibri.core.content.models import ChannelMetadata
from kolibri.core.content.models import ContentNode
from kolibri.core.utils.csv import open_csv_for_writing
from kolibri.utils import conf


logger = logging.getLogger(__name__)

CSV_EXPORT_FILENAMES = {
    "session": "{}_{}_content_session_logs.csv",
    "summary": "{}_{}_content_summary_logs.csv",
}


def cache_channel_name(obj):
    channel_id = obj["channel_id"]
    key = "{id}_ChannelMetadata_name".format(id=channel_id)
    channel_name = cache.get(key)
    if channel_name is None:
        try:
            channel_name = ChannelMetadata.objects.get(id=channel_id)
        except ChannelMetadata.DoesNotExist:
            channel_name = ""
        cache.set(key, channel_name, 60 * 10)
    return channel_name


def cache_content_title(obj):
    content_id = obj["content_id"]
    key = "{id}_ContentNode_title".format(id=content_id)
    title = cache.get(key)
    if title is None:
        node = ContentNode.objects.filter(content_id=content_id).first()
        if node:
            title = node.title
        else:
            title = ""
        cache.set(key, title, 60 * 10)
    return title


mappings = {
    "channel_name": cache_channel_name,
    "content_title": cache_content_title,
    "time_spent": lambda x: "{:.1f}".format(round(x["time_spent"], 1)),
    "progress": lambda x: "{:.4f}".format(math.floor(x["progress"] * 10000.0) / 10000),
}

labels = OrderedDict(
    (
        ("user__facility__name", "Facility name"),
        ("user__username", "Username"),
        ("channel_id", "Channel id"),
        ("channel_name", "Channel name"),
        ("content_id", "Content id"),
        ("content_title", "Content title"),
        ("start_timestamp", "Time of first interaction"),
        ("end_timestamp", "Time of last interaction"),
        ("completion_timestamp", "Time of completion"),
        ("time_spent", "Time Spent (sec)"),
        ("progress", "Progress (0-1)"),
        ("kind", "Content kind"),
    )
)


def map_object(obj):
    mapped_obj = {}
    for header, label in labels.items():
        if header in mappings:
            mapped_obj[label] = mappings[header](obj)
        elif header in obj: