import json

from django.db import transaction

from origin.models import Disk
from origin.models import DiskFlow
from origin.models import DiskHistory

from domain.dataset import DataSet
from django.core.paginator import Paginator


class DiskModel(DataSet):
    model = Disk

    @classmethod
    def config(cls):
        cfg = {
            "all": {
                "在库": {"value": 1, "flag": True},
                "在途": {"value": 2, "flag": True},
                "丢失": {"value": 3, "flag": True},
                "报废": {"value": 4, "flag": True}
            },
            "add": {
                "在库": {"value": 1, "flag": True},
                "在途": {"value": 2, "flag": False},
                "丢失": {"value": 3, "flag": True},
                "报废": {"value": 4, "flag": True}},
            "edit": {
                "在库": {"value": 1, "flag": True},
                "在途": {"value": 2, "flag": False},
                "丢失": {"value": 3, "flag": True},
                "报废": {"value": 4, "flag": True}
            }
         }
        return cfg

    @classmethod
    def add(cls, fields):
        cls.model.objects.create(**fields)
        return

    @classmethod
    def edit(cls, disk_id, fields):
        cls.model.objects.filter(id=int(disk_id)).update(**fields)
        return

    def get_list(self, condition, page=1, size=10):
        query_set = self.model.objects.filter(**condition).order_by("-update_time")
        pager = Paginator(query_set, size)
        disks = pager.get_page(page)
        count = pager.count
        result = list()
        for disk in disks:
            disk_flow = DiskFlow.objects.filter(disk_id=disk.id).first()
            result.append({
                "id": disk.id,
                "sn": disk.sn,
                "brief": disk.brief,
                "status": disk.status,
                "action": disk.action(),
                "user1": disk_flow.user1 if disk_flow else "",
                "out_brief": disk_flow.out_brief if disk_flow else "",
                "out_time": disk_flow.out_time if disk_flow else "",
                "ems_out_no": disk_flow.ems_out_no if disk_flow else "",
                "consignee": disk_flow.consignee if disk_flow else "",
                "in_time": disk_flow.in_time if disk_flow else "",
                "ems_in_no": disk_flow.ems_in_no if disk_flow else "",
                "comment": disk_flow.comment if disk_flow else "",
                "update_time": disk_flow.update_time.strftime("%Y-%m-%d %H:%M:%S") if disk_flow else ""
            })
        return result, count

    def search(self, sn, status, user1, out_time, page=1, size=10):
        condition = dict()
        if sn:
            condition["sn__istartswith"] = str(sn)
        if status:
            condition["status"] = int(status)
        if user1:
            condition["flow__user1__istartswith"] = str(user1)
        if out_time:
            condition["flow__out_time__lte"] = str(out_time)
        return self.get_list(condition, page, size)


class DiskHistoryModel(DataSet):
    model = DiskHistory

    @classmethod
    def add(cls, disk_id, flow):
        cls.model.objects.create(disk_id=disk_id, flow=flow)

    def search(self, disk_id, page, size):
        query_set = self.model.objects.filter(disk_id=disk_id).order_by("-create_time")
        pager = Paginator(query_set, size)
        histories = pager.get_page(page)
        result = list()
        for history in histories:
            result.append(history.flow)
        return result


class DiskFlowModel(DataSet):
    model = DiskFlow

    def edit(self, defaults, fields):
        obj, created = self.model.objects.update_or_create(defaults=defaults, **fields)
        return obj, created

    def outbound(self, disk_id, defaults):
        fields = {"disk_id": disk_id}
        with transaction.atomic():
            defaults.update(**{"in_time": None, "ems_in_no": "", "comment": ""})
            obj, _ = self.edit(defaults=defaults, fields=fields)
            # 出库变更磁盘状态为在途
            state = {"status": 2}
            DiskModel.edit(disk_id, state)
        return

    def go_in(self, disk_id, defaults):
        """入库之后完成此次流程追踪，更新到历史流程明细中"""
        fields = {"disk_id": disk_id}
        with transaction.atomic():
            obj, created = self.edit(defaults=defaults, fields=fields)
            if obj and not created:
                DiskHistoryModel.add(disk_id=disk_id, flow=obj.to_dict())
                # 入变更磁盘状态为在库
                state = {"status": 1}
                DiskModel.edit(disk_id, state)
        return



