# coding: utf-8
from __future__ import absolute_import, print_function, unicode_literals
from django.core.management import BaseCommand
from django.db import connection
from django.db.models import Avg, Q

from api.models import ServiceComment, Service, Doctor, Hospital


class Command(BaseCommand):
    def handle(self, *args, **kwargs):
        self.set_effect_comment()
        self.calc_service_score()
        self.calc_tag_cache()
        self.calc_doctor_score()
        self.calc_hospital_score()

    def set_effect_comment(self):
        cursor = connection.cursor()
        cursor.execute('select service_item_id, user_id from api_servicecomment '
                       'WHERE service_item_id is not NULL '
                       'group by service_id, service_item_id, user_id;')
        row = cursor.fetchall()

        for r in row:
            comments = ServiceComment.objects.filter(service_item_id=r[0],
                                                     user_id=r[1]).filter(Q(content='')
                                                                          | Q(default_rating=True))
            i = 0
            for comment in comments.iterator():
                if i == 0:
                    comment.is_effect = True
                else:
                    comment.is_effect = False
                comment.save(update_fields=['is_effect'])
                print(str(comment.id) + ' finish')

    def calc_service_score(self):
        ss = Service.objects.filter(is_online=True)
        for s in ss.iterator():
            try:
                comments = s.servicecomment_set.filter(is_effect=True).aggregate(op_avg=Avg('operation_effect'),
                                                                                 doc_avg=Avg('doctor_attitude'),
                                                                                 hos_avg=Avg('hospital_env'),
                                                                                 rating_avg=Avg('rating'))
                print(comments)
                s.hospital_env_rating = round(comments['hos_avg'], 1) if comments['hos_avg'] else 0
                s.operation_effect_rating = round(comments['op_avg'], 1) if comments['op_avg'] else 0
                s.doctor_attitude_rating = round(comments['doc_avg'], 1) if comments['doc_avg'] else 0
                s.rating = round(comments['rating_avg'], 1) if comments['rating_avg'] else 0
                s.save(update_fields=['hospital_env_rating', 'operation_effect_rating',
                                      'doctor_attitude_rating', 'rating'])
                print(s.id)
            except:
                continue

    def calc_tag_cache(self):
        from api.tasks.period_task import calc_service_avg_score
        calc_service_avg_score()

    def calc_doctor_score(self):
        doctors = Doctor.objects.all()
        for doctor in doctors.iterator():
            try:
                scores = doctor.services.filter(is_online=True).exclude(Q(rating=0) | Q(hospital_env_rating=0)
                                                                        | Q(doctor_attitude_rating=0)
                                                                        | Q(operation_effect_rating=0)).aggregate(
                    op_avg=Avg('operation_effect_rating'),
                    doc_avg=Avg('doctor_attitude_rating'),
                    hos_avg=Avg('hospital_env_rating'),
                    rating_avg=Avg('rating'))
                doctor.rate = round(scores['rating_avg'], 1)
                doctor.effect_rating = round(scores['op_avg'], 1)
                doctor.attitude_rating = round(scores['doc_avg'], 1)
                doctor.env_rating = round(scores['hos_avg'], 1)
                doctor.save(update_fields=['rate', 'effect_rating',
                                           'attitude_rating', 'env_rating'])
                print(doctor.id)
            except:
                continue

    def calc_hospital_score(self):
        hospitals = Hospital.objects.all()
        for hospital in hospitals.iterator():
            try:
                doctors = Doctor.objects.filter(hospital=hospital, is_online=True)
                scores = Service.objects.filter(is_online=True,
                                                doctor__in=doctors).exclude(Q(rating=0)
                                                                            | Q(hospital_env_rating=0)
                                                                            | Q(doctor_attitude_rating=0)
                                                                            | Q(operation_effect_rating=0)).aggregate(
                        op_avg=Avg('operation_effect_rating'),
                        doc_avg=Avg('doctor_attitude_rating'),
                        hos_avg=Avg('hospital_env_rating'),
                        rating_avg=Avg('rating'))
                hospital.rate = round(scores['rating_avg'], 1)
                hospital.effect_rating = round(scores['op_avg'], 1)
                hospital.attitude_rating = round(scores['doc_avg'], 1)
                hospital.env_rating = round(scores['hos_avg'], 1)
                hospital.save(update_fields=['rate', 'effect_rating', 'attitude_rating', 'env_rating'])
            except:
                continue


