import datetime
from casexml.apps.case.models import CommCareCaseAction
from corehq.apps.reports.standard.cases.basic import CaseListReport
from corehq.apps.api.es import ReportCaseES
from corehq.apps.reports.generic import GenericTabularReport
from corehq.apps.reports.basic import BasicTabularReport, Column
from corehq.apps.reports.standard import (DatespanMixin,
    ProjectReportParametersMixin, CustomProjectReport)
from corehq.apps.reports.standard.cases.data_sources import CaseDisplay
from corehq.apps.reports.datatables import DataTablesHeader, DataTablesColumn
from corehq.pillows.base import restore_property_dict
from hsph.reports import HSPHSiteDataMixin
from hsph.fields import NameOfCATIField, AllocatedToFilter
from corehq.apps.reports.filters.users import UserTypeFilter
from corehq.apps.reports.filters.dates import DatespanFilter
from couchdbkit_aggregate.fn import mean, unique_count
from casexml.apps.case import const
from dimagi.utils.decorators.memoized import memoized
from dimagi.utils.couch.database import get_db

def short_date_format(date):
    return date.strftime('%d-%b')


def username(key, report):
    return report.usernames[key[0]]


def datestring_minus_days(datestring, days):
    date = datetime.datetime.strptime(datestring[:10], '%Y-%m-%d')
    return (date - datetime.timedelta(days=days)).isoformat()


def date_minus_11_days(couchkey):
    return couchkey + [datestring_minus_days(couchkey[0], 11)]


def date_minus_14_days(couchkey):
    return couchkey + [datestring_minus_days(couchkey[0], 14)]


class CATIPerformanceReport(CustomProjectReport, ProjectReportParametersMixin,
                            DatespanMixin, BasicTabularReport):
    name = "CATI Performance Report"
    slug = "cati_performance"
    field_classes = (UserTypeFilter, DatespanFilter, NameOfCATIField)
            
    filter_group_name = "CATI"
    
    couch_view = "hsph/cati_performance_report_old"
    
    default_column_order = (
        'catiName',
        'followedUp',
        'noFollowUpAfter4Days',
        'transferredToManager',
        'transferredToField',
        'notClosedOrTransferredAfter13Days',
        'workingDaysUniqueCount',
        'followUpTime',
        'followUpTimeMean'
    )

    catiName = Column(
        "Name of CATI", calculate_fn=username)

    followedUp = Column(
        "No. of Births Followed Up", key='followedUp')

    noFollowUpAfter4Days = Column(
        "No. of Cases with No Follow Up for 4 Days",
        key='noFollowUpAfter4Days',
        endkey_fn=date_minus_11_days)

    transferredToManager = Column(
        "Transferred to Call Center Manager", key='transferredToManager')

    transferredToField = Column(
        "Transferred to Field", key='transferredToField')

    notClosedOrTransferredAfter13Days = Column(
        "CATI Timed Out", key='notClosedOrTransferredAfter13Days',
        endkey_fn=date_minus_14_days)

    workingDaysUniqueCount = Column(
        "No. of Working Days", key='workingDays', reduce_fn=unique_count)

    followUpTime = Column(
        "Total Follow Up Time", key='followUpTime')

    followUpTimeMean = Column(
        "Average Follow Up Time", key='followUpTime', reduce_fn=mean)

    @property
    def start_and_end_keys(self):
        return ([self.datespan.startdate_param_utc],
                [self.datespan.enddate_param_utc])

    @property
    def keys(self):
        for user in self.users:
            yield [user['user_id']]


class HSPHCaseDisplay(CaseDisplay):
    
    @property
    def region(self):
        try:
            return self.report.get_region_name(self.case['region_id'])
        except AttributeError:
            return ""

    @property