# coding=utf-8
from rest_framework.views import APIView
from django.db.models import Q
import traceback
import datetime
from django.db import transaction
from rest_framework.serializers import ValidationError
from django.utils import timezone
from rest_framework.decorators import action
from utils.permission import isLogin, permission_required, check_permission
from utils.custom_modelviewset import CustomModelViewSet
from utils import response_ok, response_error
from utils.exceptions import CustomError
from apps.log.models import BizLog
from apps.option.models import Option
from apps.option.serializers import OptionComboboxSerializer
from .models import ReportCustomer, NewCustomer, Review, NewCustomerRemind
from .serializers import ReportCustomerSerializer, NewCustomerSerializer, ReviewSerializer
from .filters import ReportCustomerFilter, NewCustomerFilter, ReviewFilter
from django.contrib.auth import get_user_model
from apps.order.models import ProgressDetails
from apps.order.serializers import Order, OrderSerializer
from apps.upload.models import Upload
from apps.account.models import OfficeStoreUser

User = get_user_model()


class ReportCustomerViewSet(CustomModelViewSet):
    permission_classes = [isLogin]
    queryset = ReportCustomer.objects.filter()
    serializer_class = ReportCustomerSerializer

    @permission_required('customer.view_report_customer')
    def filter_queryset(self, queryset):
        queryset = queryset.filter(
            Q(store_id__in=self.request.user.get_manager_range()) |
            Q(create_user=self.request.user))
        f = ReportCustomerFilter(self.request.GET, queryset=queryset)
        return f.qs

    @permission_required('customer.add_report_customer')
    def perform_create(self, serializer):
        super(ReportCustomerViewSet, self).perform_create(serializer)
        instance = serializer.instance
        validated_data = serializer.validated_data
        BizLog.objects.addnew(self.request.user, BizLog.INSERT,
                              u'添加客户报备[%s]，id=%d' % (instance.name, instance.id), validated_data)

    @permission_required('customer.add_report_customer')
    def perform_update(self, serializer):
        super(ReportCustomerViewSet, self).perform_update(serializer)
        instance = serializer.instance
        validated_data = serializer.validated_data
        BizLog.objects.addnew(self.request.user, BizLog.UPDATE,
                              u'修改客户报备[%s]，id=%d' % (instance.name, instance.id), validated_data)

    @permission_required('customer.delete_report_customer')
    def perform_destroy(self, instance):
        BizLog.objects.addnew(self.request.user, BizLog.DELETE,
                              u'删除客户报备[%s]，id=%d' % (instance.name, instance.id))
        super(ReportCustomerViewSet, self).perform_destroy(instance)

    @action(methods=['post'], detail=True)
    def dispatch_customer(self, request, pk):
        check_permission(request, 'customer.check_report_customer')
        # 报备客户审核 分配
        user_id = request.POST.get('user')
        try:
            with transaction.atomic():
                instance = ReportCustomer.objects.filter(id=pk).first()
                if not instance:
                    raise CustomError('当前客户报备信息有误,请刷新重试！')
                instance.check_user = self.request.user

                instance.report_status = ReportCustomer.CHECKED
                instance.check_time = timezone.now()
                instance.save()
                BizLog.objects.addnew(request.user, BizLog.INSERT,
                                      u'分配客户报备[%s],id=%d' % (instance.name, instance.id))
                # 创建潜客跟踪表
                stage_progress = Option.objects.filter(type=Option.STAGE_PROGRESS, enable=True).order_by('sort').first()
                if not stage_progress.track_day:
                    raise CustomError('当前阶段，没有设置跟踪天数！')
                next_time = (timezone.now() + datetime.timedelta(days=stage_progress.track_day)).strftime('%Y-%m-%d')

                customer = NewCustomer.objects.create(report_customer=instance,
                                                      track_user_id=user_id, stage_progress=stage_progress,
                                                      create_user=instance.create_user, store=instance.store,
                                                      name=instance.name, tel=instance.tel, village=instance.village,
                                                      address=instance.address, source=instance.source,
                                                      notes=instance.notes,next_time=next_time,
                                                      )
                projects = instance.project.all()
                for project in projects:
                    customer.project.add(project.id)
                NewCustomerRemind.objects.create(customer=customer, next_time=next_time, remind_user_id=user_id,)
                # 根据分配人所在店面，创建内部跟踪提醒
                remind_users = request.user.get_remind_users()
                #  把next_time用当前日期加上5天
                next_time = (timezone.now() + datetime.timedelta(days=5)).strftime('%Y-%m-%d')
                for remind_user in remind_users:
                    NewCustomerRemind.objects.create(customer=customer, next_time=next_time, remind_user_id=remind_user,
                                                     is_employee=False)
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))
        return response_ok()

    @action(methods=['post'], detail=True)
    def sign_hit(self, request, pk):
        check_permission(request, 'customer.check_report_customer')
        # 报备客户标记撞单
        try:
            with transaction.atomic():
                instance = ReportCustomer.objects.filter(id=pk).first()
                if not instance:
                    raise CustomError('当前客户报备信息有误,请刷新重试！')
                instance.check_user = self.request.user

                instance.report_status = ReportCustomer.REPEAT_REPORT
                instance.check_time = timezone.now()
                instance.save()
                BizLog.objects.addnew(request.user, BizLog.INSERT,
                                      u'标记客户[%s]为撞单,id=%d' % (instance.name, instance.id))

        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))
        return response_ok()


class ReportCustomerDictView(APIView):
    permission_classes = [isLogin]

    def get(self, request):
        source = Option.objects.filter(type=Option.CUSTOMER_SOURCE, enable=True)
        project = Option.objects.filter(type=Option.CATEGORY, enable=True)
        serializer_source = OptionComboboxSerializer(source, many=True)
        serializer_project = OptionComboboxSerializer(project, many=True)

        return response_ok({
            'source': serializer_source.data,
            'project': serializer_project.data,
        })


class UserDictView(APIView):
    permission_classes = [isLogin]

    def get(self, request):
        store = request.user.store
        office_user_id = OfficeStoreUser.objects.filter(store=store).values('office_user_id')
        if not store:
            return response_error('当前账号未绑定门店，禁止分配客户！')
        users = User.objects.filter(Q(store=store) | Q(id__in=office_user_id)).values('id', 'name')
        users = [{'value': user['id'], 'lable': user['name']} for user in users]
        return response_ok(users)


class NewCustomerViewSet(CustomModelViewSet):
    permission_classes = [isLogin, ]
    queryset = NewCustomer.objects.filter()
    serializer_class = NewCustomerSerializer

    @permission_required('customer.view_new_customer')
    def filter_queryset(self, queryset):
        queryset = queryset.filter(
            Q(store_id__in=self.request.user.get_manager_range()) |
            Q(create_user=self.request.user) |
            Q(track_user=self.request.user)
        )
        f = NewCustomerFilter(self.request.GET, queryset=queryset)
        return f.qs

    def paginate_queryset(self, queryset):
        if self.paginator is None or self.request.GET.get('export'):
            return None
        return self.paginator.paginate_queryset(queryset, self.request, view=self)

    @action(methods=['post'], detail=True)
    def add_review(self, request, pk):
        # 添加跟踪报告
        check_permission(request, 'customer.add_review')
        description = request.POST.get('description')
        instruction = request.POST.get('instruction')
        is_entry = request.POST.get('is_entry') == '1'
        is_giveup = request.POST.get('is_giveup') == '1'
        next_time = request.POST.get('next_time')

        try:
            with transaction.atomic():
                instance = NewCustomer.objects.filter(id=pk).first()
                if not instance:
                    raise CustomError('当前客户信息有误,请刷新重试！')
                data = {
                    'customer': instance.id,
                    'store': instance.store.id,
                    'create_user': request.user.id,
                    'description': description,
                    'instruction': instruction or None,
                    'is_entry': is_entry,
                    'is_giveup': is_giveup,
                }
                serializer = ReviewSerializer(data=data)
                if serializer.is_valid(raise_exception=True):
                    serializer.save()

            sort = 1
            track_day = 1
            try:
                sort = int(instance.stage_progress.sort)
                track_day = int(instance.stage_progress.track_day)
            except:
                pass
            # 预定客户，sort排序大于1，提交跟踪报告此字段为空
            if sort > 1 or not next_time:
                next_time = (timezone.now() + datetime.timedelta(days=track_day)).strftime('%Y-%m-%d')
            data = {
                'next_time':next_time,
                'end_time':timezone.now(),
                'status':NewCustomer.NORMAL,
            }

            NewCustomerRemind.objects.filter(customer=instance,remind_user=request.user).update(next_time=next_time)
            # 如果客户已放弃，再次跟踪后自动改成正常客户，同时工单状态改成正常
            if instance.status == NewCustomer.ABANDONED:
                Order.objects.filter(customer=instance).update(status=Order.NORMAL)
            ser = self.serializer_class(instance, data=data, partial=True)
            if ser.is_valid(raise_exception=True):
                ser.save()

        except ValidationError as e:
            traceback.print_exc()
            return response_error('数据格式有误')
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))
        return response_ok()

    @action(methods=['post'], detail=True)
    def add_order(self, request, pk):
        # 更新订单进度
        check_permission(request, 'order.update_order_process')
        stage_progress = request.POST.get('stage_progress')
        notes = request.POST.get('notes')

        try:
            with transaction.atomic():
                instance = NewCustomer.objects.filter(id=pk).first()
                if not instance:
                    raise CustomError('当前客户信息有误,请刷新重试！')
                order = Order.objects.filter(customer=instance).first()
                if order:
                    if order.stage_progress.end_stage:
                        raise CustomError('当前客户订单进度已到最后阶段，请勿重复更新！')
                    if order.status == Order.WAIT_DISPATCH:
                        raise CustomError('当前客户订单等待分配中，请勿重复更新！')
                    data = {
                        'status': Order.WAIT_DISPATCH,
                        'stage_progress': stage_progress,
                    }
                    ser = OrderSerializer(order, data=data, partial=True)
                    if ser.is_valid(raise_exception=True):
                        ser.save()
                else:
                    data = {
                        'status': Order.WAIT_DISPATCH,
                        'stage_progress_id': stage_progress,
                        'customer': instance,
                        'service_user': instance.track_user,
                        'store': instance.store,
                        'notes': instance.notes,
                    }
                    order = Order.objects.create(**data)
                    order.no = order.get_no()
                    order.save()
                    projects = instance.project.all()
                    for project in projects:
                        order.project.add(project.id)
                # 创建订单流程,保存图片
                user = request.user
                operation = u'更新进度为：{}'.format(order.stage_progress.name)
                progress_details = ProgressDetails.objects.create(order=order, user=user, operation=operation,
                                                                  notes=notes)
                for i in range(6):
                    file = request.data.get('file{}'.format(i))
                    if file:
                        upload = Upload.objects._addnew(instance.store, progress_details, user, file)
                        if not upload:
                            return response_error('上传失败，请重新上传！')

        except ValidationError as e:
            traceback.print_exc()
            return response_error('数据格式有误')
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))
        return response_ok()

    @action(methods=['post'], detail=True)
    def inner_review(self, request , pk):
        #内部跟踪
        description = request.POST.get('description')
        next_time = request.POST.get('next_time')
        is_copy = request.POST.get('is_copy') == '1'

        try:
            with transaction.atomic():
                instance = NewCustomer.objects.filter(id=pk).first()
                if not instance:
                    raise CustomError('客户信息有误，请刷新重试！')
                data = {
                    'customer': instance.id,
                    'store': instance.store.id,
                    'create_user': request.user.id,
                    'description': description,
                    'is_copy': is_copy,
                }
                serializer = ReviewSerializer(data=data)
                if serializer.is_valid(raise_exception=True):
                    serializer.save()
                NewCustomerRemind.objects.filter(customer=instance, remind_user=request.user).update(next_time=next_time)

        except ValidationError as e:
            traceback.print_exc()
            return response_error('数据格式有误')
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))
        return response_ok()

    @action(methods=['post'], detail=True)
    def again_dispatch(self, request, pk):
        #重新分配
        check_permission(request, 'customer.again_dispatch')
        track_user_id = request.POST.get('track_user')
        try:
            with transaction.atomic():
                instance = NewCustomer.objects.filter(id=pk).first()
                if not instance:
                    raise CustomError('客户信息有误，请刷新重试！')
                old_track_user = instance.track_user
                if not instance.stage_progress.track_day:
                    raise CustomError('当前阶段，没有设置跟踪天数！')
                next_time = (timezone.now() + datetime.timedelta(days=instance.stage_progress.track_day)).strftime('%Y-%m-%d')

                instance.track_user_id = track_user_id
                instance.next_time = next_time
                instance.save()
                #  把原跟踪人提醒更新为新的跟踪人
                NewCustomerRemind.objects.filter(customer=instance, remind_user=old_track_user).update(
                                            next_time=next_time,remind_user=track_user_id)
                BizLog.objects.addnew(request.user, BizLog.INSERT,
                                      u'重新分配客户经理[%s]为%s，id=%d' % (instance.name,track_user_id, instance.id))

        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))
        return response_ok()


class StageCountView(APIView):
    permission_classes = [isLogin]

    @permission_required('customer.view_new_customer')
    def get(self, request):
        type = request.query_params.get('type') or 'user'
        id = request.query_params.get('id') or request.user.id
        data = []
        stage_progress = Option.objects.filter(type=Option.STAGE_PROGRESS, enable=True).order_by('sort').values('id','name')
        time_now = timezone.now().strftime('%Y-%m-%d')
        for stage in stage_progress:
            # 查询正常状态客户
            reminds = NewCustomerRemind.objects.filter(customer__stage_progress=stage['id'], customer__status=NewCustomer.NORMAL)
            if type == 'store':
                reminds = reminds.filter(customer__store_id=id, is_employee=True)
            elif type == 'user':
                reminds = reminds.filter(remind_user_id=id)
            elif type == 'agent':
                reminds = reminds.filter(customer__store__agent_id=id, is_employee=True)
            elif type == 'general_agent':
                reminds = reminds.filter(customer__store__agent__general_agent_id=id, is_employee=True)

            # new_customers = NewCustomer.objects.filter(
            #     Q(track_user=user) |
            #     Q(track_user__store_id__in=request.user.get_manager_range()),
            #     stage_progress=stage['id'])

            stage_count = {
                'stage_id': stage['id'],  # 阶段id
                'stage': stage['name'],  # 阶段名称
                'total_count': reminds.count(),  # 总人数
                'today_count': reminds.filter(next_time=time_now).count(),  # 今日人数
                'overdue_count': reminds.filter(next_time__lt=time_now).count()  # 逾期人数
            }
            data.append(stage_count)
        return response_ok(data)


class GetReviewViewSet(CustomModelViewSet):
    permission_classes = [isLogin]
    queryset = Review.objects.filter()
    serializer_class = ReviewSerializer

    @permission_required('customer.view_new_customer')
    def filter_queryset(self, queryset):
        # 过滤记录中是否抄送业务员
        if len(self.request.user.get_manager_range()) == 0:
            queryset = queryset.filter(is_copy=True)
        f = ReviewFilter(self.request.GET, queryset=queryset)
        return f.qs


class ReviewViewSet(CustomModelViewSet):
    permission_classes = [isLogin]
    queryset = Review.objects.filter()
    serializer_class = ReviewSerializer

    @permission_required('customer.check_review')
    def filter_queryset(self, queryset):
        queryset = queryset.filter(store_id__in=self.request.user.get_manager_range())
        f = ReviewFilter(self.request.GET, queryset=queryset)
        return f.qs

    @action(methods=['post'], detail=True)
    def track_review(self, request, pk):
        check_permission(request, 'customer.check_review')
        # 跟踪审核
        check_status = request.POST.get('check_status')
        check_comment = request.POST.get('check_comment')
        next_time = request.POST.get('next_time')
        try:
            with transaction.atomic():
                instance = Review.objects.filter(id=pk).first()
                if int(check_status) == Review.KEEPUP:
                    instance.check_user = request.user
                    instance.check_status = check_status
                    instance.check_comment = check_comment
                    instance.check_time = timezone.now()
                    instance.save()
                if int(check_status) == Review.ABANDON:
                    instance.check_user = request.user
                    instance.check_status = check_status
                    instance.check_comment = check_comment
                    instance.check_time = timezone.now()
                    instance.save()
                    instance.customer.status = NewCustomer.ABANDONED
                    # 如果客户已下单，把工单状态改成放弃
                    Order.objects.filter(customer=instance.customer).update(status=Order.ABANDONED)
                instance.customer.next_time = next_time
                instance.customer.save()
                NewCustomerRemind.objects.filter(customer=instance.customer, remind_user=instance.customer.track_user).update(next_time=next_time)
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))
        return response_ok()


class ListCountView(APIView):
    permission_classes = [isLogin]

    def get(self, request):
        report_customer_count = ReportCustomer.objects.filter(Q(store_id__in=request.user.get_manager_range()) |
                                                              Q(create_user=request.user),
                                                              report_status=ReportCustomer.NOT_CHECKED).count()
        review_count = Review.objects.filter(store_id__in=request.user.get_manager_range(),
                                             check_status=Review.DEFAULT).count()
        order_count = Order.objects.filter(Q(store_id__in=request.user.get_manager_range()) |
                                           Q(service_user=request.user) |
                                           Q(customer__create_user=request.user), status=Order.WAIT_DISPATCH).count()

        data ={
            'report_customer_count': report_customer_count,  # 报备审核数量
            'review_count': review_count,  # 跟踪审核数量
            'order_count': order_count,  # 进度审核数量
        }
        return response_ok(data)