import json
from utils.base import APIView, get_offset_count
from utils.logger import error_logger


class ProductListView(APIView):

    def get_brand_infos(self, product_ids):
        brand_infos = self.rpc['neptune/commodity/brand/products_brand_info'](product_ids=product_ids).unwrap()

        brand_product_dict = {str(obj.get('product_id')): obj for obj in brand_infos} if brand_infos else {}
        return brand_product_dict

    def get_category_infos(self, product_ids):
        category_infos = self.rpc['neptune/commodity/category/products_category_info'](product_ids=product_ids).unwrap()
        ret = {}
        if not category_infos:
            return ret
        for obj in category_infos:
            product_id = obj.get('product_id')
            if ret.get(str(product_id)):
                ret.get(str(product_id)).append(obj)
            else:
                ret[str(product_id)] = [obj]
        return ret

    def get_effect_infos(self, product_ids):
        effect_infos = self.rpc['neptune/commodity/effect/products_effect_info'](product_ids=product_ids).unwrap()
        ret = {}
        if not effect_infos:
            return ret
        for obj in effect_infos:
            product_id = obj.get('product_id')
            if ret.get(str(product_id)):
                ret.get(str(product_id)).append(obj)
            else:
                ret[str(product_id)] = [obj]
        return ret

    def get_classify_infos(self, product_ids):
        classify_infos = self.rpc['neptune/commodity/classify/infos'](product_ids=product_ids).unwrap()
        ret = {}
        if not classify_infos:
            return ret
        for obj in classify_infos:
            product_id = obj.get('product_id')
            if ret.get(str(product_id)):
                ret.get(str(product_id)).append(obj)
            else:
                ret[str(product_id)] = [obj]
        return ret

    def get(self, request):
        offset, count = get_offset_count(request)
        id_ = request.GET.get('id', None)
        cn_name = request.GET.get('cn_name', None)
        en_name = request.GET.get('en_name', None)
        alias = request.GET.get('alias', None)
        is_online = request.GET.get('is_online', None)
        has_area = request.GET.get('has_area', None)
        has_brand = request.GET.get('has_brand', None)
        has_image = request.GET.get('has_image', None)
        brand_id = request.GET.get('brand_id', None)
        classify_id = request.GET.get('classify_id', None)
        category_id = request.GET.get('category_id', None)
        price_low = request.GET.get('price_low', None)
        price_high = request.GET.get('price_high', None)
        grade_low = request.GET.get('grade_low', None)
        grade_high = request.GET.get('grade_high', None)
        comment_nums_low = request.GET.get('comment_nums_low', None)
        comment_nums_high = request.GET.get('comment_nums_high', None)
        effect_name = request.GET.get('effect_name', None)
        sorted_condition = request.GET.get('sorted_condition', None)
        effect_id = request.GET.get('effect_id', None)

        data = self.rpc['neptune/commodity/product/list'](
            offset=offset, count=count, id_=id_, cn_name=cn_name, en_name=en_name, alias=alias, is_online=is_online,
            has_area=has_area, has_brand=has_brand, has_image=has_image, brand_id=brand_id, classify_id=classify_id,
            category_id=category_id, price_low=price_low, price_high=price_high, grade_low=grade_low, grade_high=grade_high,
            comment_nums_low=comment_nums_low, comment_nums_high=comment_nums_high, effect_name=effect_name,
            sorted_condition=sorted_condition, effect_id=effect_id, is_fuzzy=True).unwrap()

        product_ids = [obj.get('id') for obj in data]
        brand_product_dict = self.get_brand_infos(product_ids)
        category_product_dict = self.get_category_infos(product_ids)
        effect_product_dict = self.get_effect_infos(product_ids)
        classify_product_dict = self.get_classify_infos(product_ids)

        for obj in data:
            product_id = obj.get('id')
            obj['brand_info'] = {
                'id': brand_product_dict.get(str(product_id)).get('id'),
                'cn_name': brand_product_dict.get(str(product_id)).get('cn_name')} if brand_product_dict.get(str(product_id)) else ''
            obj['category_infos'] = [{'id': obj.get('id'), 'cn_name': obj.get('cn_name')}
                                     for obj in category_product_dict.get(str(product_id))] if category_product_dict.get(str(product_id)) else []
            obj['effect_infos'] = [{'id': obj.get('id'), 'cn_name': obj.get('cn_name')}
                                   for obj in effect_product_dict.get(str(product_id))] if effect_product_dict.get(str(product_id)) else []
            obj['classify_infos'] = [{'id': obj.get('id'), 'cn_name': obj.get('cn_name')}
                                     for obj in classify_product_dict.get(str(product_id))] if classify_product_dict.get(str(product_id)) else []

            obj.pop('norms')
            obj.pop('country')
            obj.pop('platform')

        count = self.rpc['neptune/commodity/product/count'](
            id_=id_, cn_name=cn_name, en_name=en_name, alias=alias, is_online=is_online, has_area=has_area, has_brand=has_brand,
            has_image=has_image, brand_id=brand_id, category_id=category_id, classify_id=classify_id, price_low=price_low,
            price_high=price_high, grade_low=grade_low, grade_high=grade_high, comment_nums_low=comment_nums_low,
            comment_nums_high=comment_nums_high, effect_name=effect_name, effect_id=effect_id, is_fuzzy=True).unwrap()
        result = {
            'list': data,
            'total': count,
        }
        return result


class ProductInfoView(APIView):

    def get_category_infos(self, product_id):
        category_infos = self.rpc['neptune/commodity/category/infos'](product_id=product_id).unwrap()
        if not category_infos:
            return []
        return [{'id': obj.get('id'), 'cn_name': obj.get('cn_name')} for obj in category_infos]

    def get_effect_infos(self, product_id):
        effect_infos = self.rpc['neptune/commodity/effect/infos'](product_id=product_id).unwrap()
        if not effect_infos:
            return []
        return [{'id': obj.get('id'), 'cn_name': obj.get('cn_name')} for obj in effect_infos]

    def get(self, request):
        id_ = request.GET.get('id')

        data = self.rpc['neptune/commodity/product/info'](id_=id_).unwrap()
        data.pop('norms')
        data.pop('country')
        data.pop('platform')

        brand_info = self.rpc['neptune/commodity/brand/infos'](product_id=id_).unwrap()
        data['brand_info'] = {'id': brand_info[0].get('id'), 'cn_name': brand_info[0].get('cn_name')} if brand_info else {}
        classify_infos = self.rpc['neptune/commodity/classify/infos'](product_ids=[id_]).unwrap()
        data['classify_infos'] = [{'id': obj.get('id'), 'cn_name': obj.get('cn_name')} for obj in classify_infos]
        data['category_infos'] = self.get_category_infos(id_)
        data['effect_infos'] = self.get_effect_infos(id_)

        return data


class ProductCreateView(APIView):

    def post(self, request):
        cn_name = request.POST.get('cn_name', None)
        en_name = request.POST.get('en_name', None)
        alias = request.POST.get('alias', None)
        image = request.POST.get('image', None)
        norms = request.POST.get('norms', None)
        grade = request.POST.get('grade', None)
        price = request.POST.get('price', None)
        country = request.POST.get('country', None)
        description = request.POST.get('description', None)
        comment_nums = request.POST.get('comment_nums', None)
        classify_ids = json.loads(request.POST.get('classify_ids', '[]'))
        category_ids = json.loads(request.POST.get('category_ids', '[]'))
        effect_ids = json.loads(request.POST.get('effect_ids', '[]'))
        is_online = request.POST.get('is_online')
        brand_id = request.POST.get('brand_id')
        period_of_use = request.POST.get('period_of_use') or 0

        if not cn_name or not image:
            return r'缺少参数'

        data = self.rpc['neptune/commodity/product/create'](
            cn_name=cn_name, en_name=en_name, alias=alias, image=image, norms=norms, grade=grade, price=price,
            country=country, description=description, comment_nums=comment_nums, classify_ids=classify_ids,
            category_ids=category_ids, effect_ids=effect_ids, is_online=is_online, brand_id=brand_id,
            period_of_use=period_of_use
        ).unwrap()

        return data


class ProductUpdateView(APIView):

    def post(self, request):
        id_ = request.POST.get('id')
        cn_name = request.POST.get('cn_name', None)
        en_name = request.POST.get('en_name', None)
        alias = request.POST.get('alias', None)
        image = request.POST.get('image', None)
        norms = request.POST.get('norms', None)
        grade = request.POST.get('grade', None)
        price = request.POST.get('price', None)
        country = request.POST.get('country', None)
        description = request.POST.get('description', None)
        comment_nums = request.POST.get('comment_nums', None)
        classify_ids = json.loads(request.POST.get('classify_ids', '[]'))
        category_ids = json.loads(request.POST.get('category_ids', '[]'))
        effect_ids = json.loads(request.POST.get('effect_ids', '[]'))
        is_online = request.POST.get('is_online')
        brand_id = request.POST.get('brand_id')
        period_of_use = request.POST.get('period_of_use', 0) or 0

        if not id_:
            return r'缺少参数'

        data = self.rpc['neptune/commodity/product/update'](
            id_=id_, cn_name=cn_name, en_name=en_name, alias=alias, image=image, norms=norms, grade=grade, price=price,
            country=country, description=description, comment_nums=comment_nums, classify_ids=classify_ids,
            category_ids=category_ids, effect_ids=effect_ids, is_online=is_online, brand_id=brand_id,
            period_of_use=period_of_use).unwrap()

        return data


class ProductSearchView(APIView):

    def post(self, request):
        name = request.POST.get('name')

        if not name:
            return r'缺少参数'

        data = self.rpc['neptune/commodity/product/search'](name=name, is_fuzzy=True).unwrap()

        return data
