# coding=utf-8
from django.utils import timezone
from django.conf import settings
from django.db import models

from apps.log.models import BizLog
from apps.tenant import tenant_log
from apps.tenant.models import Tenant
from apps.upload.models import Upload
from utils.exceptions import CustomError
from apps.tenant.option.models import Option
from utils.format import strftime, strfsecond
from apps.account.models import User
from apps.tenant.device.models import DeviceModel


class RepairOrder(models.Model):
    REPAIR_ORDER = 1
    INSPECTION_ORDER = 2
    ORDER_TYPE = (
        (REPAIR_ORDER, '报修工单'),
        (INSPECTION_ORDER, '巡检转报修工单')
    )
    NOT_CHECKED = 1
    CHECKED = 2
    DISPATCH = 3
    HANG_UP = 4
    TURN_EMPLOYEE = 5
    FINISH = 6
    APPRAISE = 7
    INVALID = 8
    CANCEL_HANG_UP = 9
    REPAIR_STATUS_CHOICES = (
        (NOT_CHECKED, '待审核'),
        (CHECKED, '已审核，待派单'),
        (DISPATCH, '已派单'),
        (HANG_UP, '已挂起'),
        (TURN_EMPLOYEE, '转单'),
        (FINISH, '已完工,待评价'),
        (APPRAISE, '已评价'),
        (INVALID, '作废'),
        (CANCEL_HANG_UP, '取消挂起'),
    )
    no = models.CharField(max_length=50, verbose_name='单号', blank=True)
    tenant = models.ForeignKey(Tenant, verbose_name=u'租户', on_delete=models.PROTECT, blank=True)
    device = models.ForeignKey(DeviceModel, verbose_name='设备', on_delete=models.PROTECT, blank=True, null=True)
    device_name = models.CharField(max_length=100, verbose_name='设备名称')
    device_address = models.CharField(max_length=200, verbose_name='设备地址')
    fault_des = models.CharField(max_length=200, verbose_name='故障描述')
    repair_type = models.ForeignKey(Option, verbose_name='报修类型', on_delete=models.PROTECT)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u"报修人员", on_delete=models.PROTECT,
                             editable=False)
    name = models.CharField(max_length=11, verbose_name='报修人员')
    tel = models.CharField(max_length=11, verbose_name='报修电话')
    repair_users = models.ManyToManyField(settings.AUTH_USER_MODEL, verbose_name='维修人员', related_name='repair_users')
    status = models.PositiveSmallIntegerField(choices=settings.REPAIR_STATUS_CHOICES, verbose_name=u'状态',
                                              default=settings.NOT_CHECKED)
    order_type = models.PositiveSmallIntegerField(choices=ORDER_TYPE, verbose_name=u'工单类型',
                                                  default=REPAIR_ORDER)
    images = models.ManyToManyField(Upload, verbose_name='图片', blank=True)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    delete = models.BooleanField(verbose_name='删除', default=False)

    class Meta:
        db_table = 'repair_order'
        verbose_name = '报修工单'
        ordering = ['-create_time']
        index_together = (
            'status',
            'create_time',
        )
        default_permissions = ()
        permissions = [
            ('browse_repair_order', u'查看'),
            ('add_repair_order', u'添加'),
            ('delete_repair_order', u'删除'),
            ('check_repair_order', u'审核'),
            ('invalid_repair_order', u'作废'),
            ('dispatch_repair_order', u'派工'),
            ('rob_repair_order', u'抢单'),
            ('finish_repair_order', u'完工'),
        ]

    def get_no(self):
        now = timezone.now()
        no = '%s%d-%s' % ('BX', self.tenant.id, now.strftime('%Y%m%d%H%M%S'))
        return no

    def get_full_name(self):
        return self.device_address

    @staticmethod
    def get_instance_by_id(id, tenant):
        try:
            id = int(id)
        except:
            raise CustomError('无效的报修单ID')
        instance = RepairOrder.objects.filter(pk=id, tenant=tenant, delete=False).first()
        if not instance:
            raise CustomError('未找到对应的报修工单')
        return instance

    def hange_up_repair_order(self, user, reason):
        # 挂起
        if not self.status == settings.DISPATCH:
            raise CustomError('当前报修工单不允许挂起！')

        user_ids = self.repair_users.all()
        if user not in user_ids:
            raise CustomError('非主修人员操作，禁止操作！')

        self.status = settings.HANG_UP
        self.save()
        RepairOrderRecord.objects.create(repair_order=self, status=settings.HANG_UP, user=user, notes=reason)
        tenant_log(user.employee, BizLog.INSERT, u'挂起报修工单[%s],id=%d' % (self.no, self.id))

    def cancel_hange_up_repair_order(self, user):
        # 取消挂起
        if not self.status == settings.HANG_UP:
            raise CustomError('当前报修工单非挂起状态！')

        user_ids = self.repair_users.all()
        if user not in user_ids:
            raise CustomError('非主修人员操作，禁止操作！')
        self.status = settings.DISPATCH
        self.save()
        RepairOrderRecord.objects.create(repair_order=self, status=settings.CANCEL_HANG_UP, user=user)
        tenant_log(user.employee, BizLog.INSERT, u'取消挂起报修工单[%s],id=%d' % (self.no, self.id))

    def check_repair_order(self, user):
        # 审核
        if self.status > settings.NOT_CHECKED:
            raise CustomError('当前报修工单状态已审核！')

        self.status = settings.CHECKED
        self.save()
        RepairOrderRecord.objects.create(repair_order=self, status=settings.CHECKED, user=user)
        tenant_log(user.employee, BizLog.INSERT, u'审核报修工单[%s],id=%d' % (self.no, self.id))

    def dispatch_repair_order(self, user, dispacth_users):
        self.status = settings.DISPATCH
        self.repair_users.add(dispacth_users)
        self.save()
        # 记录操作
        RepairOrderRecord.objects.create(repair_order=self, status=settings.DISPATCH, user=user,
                                         repair_users=dispacth_users)

    def invalid(self, user):
        # 作废
        if self.status == settings.NOT_CHECKED:
            raise CustomError('当前报修工单状态未审核，不能进行作废！')
        if self.status > settings.APPRAISE:
            raise CustomError('该报修单已作废！')
        self.status = settings.INVALID
        self.save()
        # 记录操作
        RepairOrderRecord.objects.create(repair_order=self, status=settings.INVALID, user=user)
        tenant_log(user.employee, BizLog.UPDATE, u'作废报修工单[%s],id=%d' % (self.no, self.id))

    def finish_order(self, user, notes, images):
        # 完工
        self.status = settings.FINISH
        self.save()

        # 记录操作
        repair_order_record = RepairOrderRecord.objects.create(repair_order=self, status=settings.FINISH, user=user,
                                                               notes=notes)
        for image in images:
            repair_order_record.images.add(image)
        repair_order_record.save()


class RepairOrderRecord(models.Model):
    repair_order = models.ForeignKey(RepairOrder, verbose_name='报修工单', on_delete=models.PROTECT,
                                     related_name='repair_order_record')
    status = models.PositiveSmallIntegerField(choices=settings.REPAIR_STATUS_CHOICES, verbose_name=u'状态',
                                              default=settings.NOT_CHECKED)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u"操作人", on_delete=models.PROTECT,
                             editable=False)
    notes = models.CharField(max_length=500, verbose_name='备注', null=True)
    repair_users = models.CharField(max_length=500, verbose_name='维修人员', null=True)
    operation_time = models.DateTimeField(verbose_name='操作时间', auto_now_add=True)

    class Meta:
        db_table = 'repair_order_record'
        verbose_name = '维修工单记录'
        ordering = ['operation_time']
        default_permissions = ()

    def get_records(self, order_id):
        dict = {
            'status': self.status,
            'status_text': settings.REPAIR_STATUS_CHOICES[self.status - 1][1],
            'operation_time': strftime(self.operation_time),
        }
        user_name = self.user.employee.name
        if self.status == settings.NOT_CHECKED:
            dict['no'] = self.repair_order.no
            dict['desc'] = u'下单人：{}-{}'.format(self.repair_order.name, self.repair_order.tel)
            dict['tel'] = self.repair_order.tel
        elif self.status == settings.CHECKED:
            dict['desc'] = u'审核人：{}'.format(user_name)
        elif self.status == settings.DISPATCH:
            user_ids = self.repair_users.split(',') or []
            repair_users = User.objects.filter(id__in=user_ids).values('employee__name', 'employee__tel', )
            e_name = [u'{0}-{1}'.format(e['employee__name'], e['employee__tel']) for e in repair_users]
            if str(self.user.id) in user_ids:
                desc = u'维修工【{0}】接单'.format(','.join(e_name))
                if self.repair_order.order_type == RepairOrder.INSPECTION_ORDER:
                    desc = u'维修工【{0}】巡检转维修接单'.format(','.join(e_name))
            else:
                desc = u'【{0}】派单给维修工【{1}】'.format(user_name, ','.join(e_name))
            dict['desc'] = desc
            dict['employees'] = [{'name': e['employee__name'], 'tel': e['employee__tel']} for e in repair_users]
        elif self.status == settings.HANG_UP:
            dict['desc'] = u'挂起原因：{}'.format(self.notes)
        elif self.status == settings.FINISH:
            dispatch_time = RepairOrderRecord.objects.filter(repair_order_id=order_id,
                                                             status=settings.DISPATCH).order_by(
                'operation_time').first()
            diff_time = self.operation_time - dispatch_time.operation_time

            hang_up = RepairOrderRecord.objects.filter(repair_order_id=order_id, status=settings.HANG_UP).first()
            if hang_up:
                cancel_hang_up = RepairOrderRecord.objects.filter(repair_order_id=order_id,
                                                                  status=settings.CANCEL_HANG_UP).first()
                # 挂起时间
                hang_up_time = cancel_hang_up.operation_time - hang_up.operation_time
                diff_time = diff_time - hang_up_time

            desc = u'维修工【{0}】完工，共用时：{1}天{2}'.format(user_name, diff_time.days, strfsecond(diff_time.seconds))
            dict['desc'] = desc
            order_finish = RepairOrderFinish.objects.filter(repair_order=order_id).first()
            dict['fault_cause'] = order_finish.fault_cause.name
            dict['content'] = order_finish.content
            dict['images'] = []
            images = order_finish.images.all()
            for img in images:
                dict['images'].append(
                    {
                        'url': img.picture
                    }
                )
        elif self.status == settings.TURN_EMPLOYEE:
            user_ids = self.repair_users.split(',') or []
            e_name = User.objects.filter(id__in=user_ids).values('employee__name', 'employee__tel', )
            e_name = [e['employee__name'] + '-' + e['employee__tel'] for e in e_name]
            desc = u'【{0}】转单给维修工【{1}】'.format(user_name, ','.join(e_name))
            dict['desc'] = desc

        elif self.status == settings.APPRAISE:
            comment = RepairOrderComment.objects.filter(repair_order_id=order_id).first()
            if comment:
                dict['desc'] = u'评价内容：{0}'.format(comment.content)
                dict['start'] = comment.start
        else:
            dict['desc'] = ''
        return dict


class RepairOrderComment(models.Model):
    repair_order = models.ForeignKey(RepairOrder, verbose_name='报修工单', on_delete=models.PROTECT,
                                     related_name='repair_order_comment')
    content = models.CharField(max_length=200, verbose_name='评价内容')
    user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u"评价人", on_delete=models.PROTECT,
                             editable=False)
    start = models.PositiveSmallIntegerField(verbose_name='评分', default=5)
    create_time = models.DateTimeField(verbose_name='评价时间', auto_now_add=True)

    class Meta:
        db_table = 'repair_order_comment'
        verbose_name = '维修工单评价'
        default_permissions = ()


class RepairOrderFinish(models.Model):
    repair_order = models.ForeignKey(RepairOrder, verbose_name='报修工单', on_delete=models.PROTECT)
    fault_cause = models.ForeignKey(Option, verbose_name=u'故障原因', on_delete=models.PROTECT)
    quality_date = models.DateField(verbose_name=u'质保到期', null=True)
    content = models.CharField(verbose_name=u'完工内容', max_length=500, null=True)
    images = models.ManyToManyField(Upload, verbose_name='图片', blank=True)

    class Meta:
        db_table = 'repair_order_finish'
        verbose_name = '维修完工'
        ordering = ['-id']
        default_permissions = ()
