# coding=utf-8
from rest_framework.views import APIView
from rest_framework.decorators import action
import traceback
from django.db import transaction
from rest_framework.serializers import ValidationError
from rest_framework import generics
from rest_framework_extensions.cache.decorators import cache_response
from utils.default_key_constructor import UpdatedAtKeyBit
from rest_framework_extensions.key_constructor.bits import PaginationKeyBit, RetrieveSqlQueryKeyBit, ListSqlQueryKeyBit, QueryParamsKeyBit
from rest_framework_extensions.key_constructor.constructors import DefaultKeyConstructor
from utils.permission import isLogin, permission_required, check_permission
from utils.custom_modelviewset import CustomModelViewSet
from utils import response_ok, response_error
from apps.log.models import BizLog
from .serializers import *
from .filters import CommodityFilter
from django.contrib.auth import get_user_model
User = get_user_model()
from apps.base import Formater
from utils.exceptions import CustomError

class CommodityViewSet(CustomModelViewSet):
    permission_classes = [isLogin, ]
    queryset = Commodity.objects.filter()
    serializer_class = CommoditySerializer

    @permission_required('commodity.view_commodity')
    def filter_queryset(self, queryset):
        queryset = queryset.filter(create_user=self.request.user)
        f = CommodityFilter(self.request.GET, queryset=queryset)
        return f.qs

    @permission_required('commodity.add_commodity')
    def perform_create(self, serializer):
        super(CommodityViewSet, 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('commodity.add_commodity')
    def perform_update(self, serializer):
        super(CommodityViewSet, 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)

    @action(methods=['post'], detail=True)
    def upload_image(self, request, pk):
        type = request.POST.get('type')
        banner_img = request.FILES.get('banner_img')
        # type=main,上传主图。type=list，上传列表图
        try:
            with transaction.atomic():
                instance = self.get_object()
                upload = Upload.objects._addnew(banner_img)
                if upload:
                    if type == 'upload_main':
                        if instance.main_image_id:
                            img = Upload.objects.filter(id=instance.main_image_id).first()
                            img.del_images()
                        instance.main_image_id = upload.id
                    elif type == 'upload_list':
                        if instance.list_image_id:
                            img = Upload.objects.filter(id=instance.list_image_id).first()
                            img.del_images()
                        instance.list_image_id = upload.id
                    instance.save()
                    return response_ok(upload.id)
                return response_error('上传失败，请重新上传！')
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))

    @action(methods=['post'], detail=True)
    def upload_detail_img(self, request, pk):
        # 上传详情、参数图片
        type = request.POST.get('type')
        try:
            with transaction.atomic():
                instance = self.get_object()
                for i in range(10):
                    file = request.data.get('file{}'.format(i))
                    if file:
                        upload = Upload.objects._addnew(file)
                        if type == 'upload_detail':
                            CommodityImages.objects.create(product_id=instance.id,
                                                           type=CommodityImages.DETAILS,
                                                           image_id=upload.id)
                        elif type == 'upload_param':
                            CommodityImages.objects.create(product_id=instance.id,
                                                           type=CommodityImages.PARAMETER,
                                                           image_id=upload.id)
                        if not upload:
                            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 query_detail_img(self, request, pk):
        #查看 详情、参数图片
        type = request.POST.get('type')
        instance = self.get_object()
        data = []

        commodity_images = CommodityImages.objects.filter(product_id=instance.id)
        if type == 'upload_detail':
            commodity_images = commodity_images.filter(type=CommodityImages.DETAILS)

        for commodity_image in commodity_images:
            image = Upload.objects.filter(id=commodity_image.image_id).first()
            image_path = image.get_path()
            commodity_image_item = {
                'id': commodity_image.id,
                'name': commodity_image.name,
                'src': image_path,
            }
            data.append(commodity_image_item)
        return response_ok(data)

class DeleteCommodityImageView(APIView):
    permission_classes = [isLogin,]

    def post(self, request, *args, **kwargs):
        #商品图片 删除
        id = request.GET.get('id')
        try:
            instance = CommodityImages.getById(id)
            image = Upload.objects.filter(id=instance.image_id).first()
            with transaction.atomic():
                instance.delete()
                image.del_images()
        except CustomError as e:
            return response_error(e.get_error_msg())
        except Exception as e:
            return response_error(str(e))
        return response_ok()

class WxCommodityUpdatedAtKeyBit(UpdatedAtKeyBit):
    key = "wx_commodity_updated_at"

class WxCommodityKeyConstructor(DefaultKeyConstructor):
    # 列表缓存key生成器
    list_sql = ListSqlQueryKeyBit()
    pagination = PaginationKeyBit()
    updated_at = WxCommodityUpdatedAtKeyBit()

class WxCommodityView(generics.ListAPIView):
    permission_classes = [ ]
    queryset = Commodity.objects.filter(status=settings.ONLINE)
    serializer_class = WxCommoditySerizlizer

    # @cache_response(key_func=WxCommodityKeyConstructor())
    def list(self, request, *args, **kwargs):
        return super(WxCommodityView, self).list(request, *args, **kwargs)

    def filter_queryset(self, queryset):
        queryset = queryset.filter()
        f = CommodityFilter(self.request.GET, queryset=queryset)
        return f.qs


class WxCommodityDetailUpdatedAtKeyBit(UpdatedAtKeyBit):
    key = "wx_commodity_detail_updated_at"

class WxCommodityDetailKeyConstructor(DefaultKeyConstructor):
    # 明细缓存key生成器
    retrieve_sql = RetrieveSqlQueryKeyBit()
    # pagination = PaginationKeyBit()
    updated_at = WxCommodityDetailUpdatedAtKeyBit()

class WxCommodityDetailView(generics.RetrieveAPIView):
    permission_classes = [ ]
    queryset = Commodity.objects.filter(status=settings.ONLINE)
    serializer_class = WxCommodityDetailsSerializer

    # @cache_response(key_func=WxCommodityDetailKeyConstructor())
    def retrieve(self, request, *args, **kwargs):
        # 商品详情
        instance = self.get_object()
        serializer = WxCommodityDetailsSerializer(instance, context={'request': request})
        return response_ok(serializer.data)
