
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rest_framework.exceptions import ParseError
from django.conf import settings
from openpyxl import load_workbook, Workbook
from django.db import transaction
# Create your views here.

from .models import Article, Material, Source, Threshold, CompanyInfo, ChildrenCompany
from .serializers import ArticelSerializer, ArticelListSerializer, MaterialSerializer, SourceSerializer, ThresholdSerializer, PathSerializer, CompanyInfoSerializer, ChildrenCompanySerializer
from utils.custom import CommonPagination
class ArticleViewSet(ModelViewSet):
    """
    文章：增删改查
    """
    perms_map = [
        {'get': '*'}, {'post': 'article_create'},
        {'put': 'article_update'}, {'delete': 'article_delete'}]
    queryset = Article.objects.filter(is_delete=0).all()
    serializer_class = ArticelSerializer
    pagination_class = CommonPagination
    filter_backends = [DjangoFilterBackend,SearchFilter, OrderingFilter]
    search_fields = ['title','content', 'types']
    ordering_fields = ['title','update_time']
    ordering = ['-is_top', '-update_time']
    filterset_fields = ['type']

    def get_serializer_class(self):
        if self.action=='list':
            return ArticelListSerializer
        else:
            return ArticelSerializer
    
    @action(methods=['put'], detail=True, url_name='top_article', perms_map=[{'*':'top_article'}])
    def top(self, request, *args, **kwargs):
        '''
        置顶文章
        '''
        instance = self.get_object()
        instance.is_top = False if instance.is_top else True
        instance.save()
        return Response(status=status.HTTP_200_OK)


class ConpamyInfoViewSet(ModelViewSet):
    """
    父公司：增删改查
    """
    perms_map = [
        {'get': '*'}, {'post': 'article_create'},
        {'put': 'article_update'}, {'delete': 'article_delete'}]
    queryset = CompanyInfo.objects.filter(is_delete=0).all()
    serializer_class = CompanyInfoSerializer
    pagination_class = CommonPagination
    filter_backends = [DjangoFilterBackend,SearchFilter, OrderingFilter]
    search_fields = ['company_name']
    ordering_fields = ['update_time']
    ordering = ['-sum_points']


class ChildrenCompanyViewSet(ModelViewSet):
    """
    子公司：增删改查
    """
    perms_map = [
        {'get': '*'}, {'post': 'article_create'},
        {'put': 'article_update'}, {'delete': 'article_delete'}]
    queryset = ChildrenCompany.objects.filter(is_delete=0).all()
    serializer_class = ChildrenCompanySerializer
    pagination_class = CommonPagination
    filter_backends = [DjangoFilterBackend,SearchFilter, OrderingFilter]
    filterset_fields = ['parent_company']
    ordering_fields = ['update_time']
    ordering = ['-update_time']


class MaterialViewSet(ModelViewSet):
    """
    资料：增删改查
    """
    perms_map = [
        {'get': '*'}, {'post': 'material_create'},
        {'put': 'material_update'}, {'delete': 'material_delete'}]
    queryset = Material.objects.filter(is_delete=0)
    serializer_class = MaterialSerializer
    pagination_class = CommonPagination
    filter_backends = [DjangoFilterBackend,SearchFilter, OrderingFilter]
    search_fields = ['name','description']
    ordering_fields = ['update_time', 'down_count']
    ordering = ['sort', '-down_count']
    filterset_fields = ['type', 'name', 'cate']

    @action(methods=['get'], detail=True, url_name='down_material', perms_map=[{'*':'down_material'}])
    def down(self, request, *args, **kwargs):
        '''
        下载资料
        '''
        instance = self.get_object()
        instance.down_count = instance.down_count + 1
        instance.save()
        return Response({'path':instance.path, 'down_count':instance.down_count})
    

class SourceViewSet(ModelViewSet):
    perms_map = [
        {'get': '*'}, {'post': 'threshold_update'},
        {'put': 'threshold_update'}, {'delete': 'threshold_update'}]
    queryset = Source.objects.filter(is_delete=0)
    pagination_class = CommonPagination
    filter_backends = [DjangoFilterBackend,SearchFilter, OrderingFilter]
    serializer_class = SourceSerializer
    search_fields = ['name','author']
    filterset_fields = ['name', 'author', 'publish_year']


class ThresholdViewSet(ModelViewSet):
    perms_map = [
    {'get': 'threshold_view'}, {'post': 'threshold_update'},
    {'put': 'threshold_update'}, {'delete': 'threshold_update'}]
    queryset = Threshold.objects.filter(is_delete=0)
    serializer_class = ThresholdSerializer
    pagination_class = CommonPagination
    filter_backends = [DjangoFilterBackend,SearchFilter, OrderingFilter]
    search_fields = ['chinese_name','cas', 'compound_cate', 'odor_type']
    filterset_fields = ['source', 'compound_cate']

    @action(methods=['post'], detail=False, perms_map=[{'post':'threshold_update'}], serializer_class=PathSerializer)
    @transaction.atomic
    def daoru(self, request, *args, **kwargs):
        '''导入excel

        导入excel
        '''
        data = request.data
        sr = PathSerializer(data=data)
        sr.is_valid(raise_exception=True)
        vdata = sr.validated_data
        self.handle_xlsx(vdata['path'])
        return Response()
    
    def handle_xlsx(self, path):
        full_path = settings.BASE_DIR + path
        if not path.endswith('.xlsx'):
            raise ParseError('请提供xlsx格式文件')
        wb = load_workbook(full_path, data_only=True)
        # 先导入来源
        source_sheet = wb.get_sheet_by_name('来源表')
        i = 3
        sources_dict = {}
        while source_sheet[f'c{i}'].value:
            item = {}
            item['name'] = source_sheet[f'c{i}'].value
            item['author'] = source_sheet[f'd{i}'].value
            try:
                item['publish_year'] = int(source_sheet[f'e{i}'].value)
            except BaseException:
                pass
            source, is_created = Source.objects.get_or_create(defaults=item, name=item['name'])
            sources_dict[str(source_sheet[f'a{i}'].value)] = source
            i = i + 1
        # self.handle_other_sheet(wb, '醇类', sources_dict)
        # self.handle_other_sheet(wb, '醛类', sources_dict)
        # self.handle_other_sheet(wb, '酸类', sources_dict)
        # self.handle_other_sheet(wb, '酯类', sources_dict)
        # self.handle_other_sheet(wb, '酮类', sources_dict)
        # self.handle_other_sheet(wb, '醚类', sources_dict)
        # self.handle_other_sheet(wb, '酚类', sources_dict)
        # self.handle_other_sheet(wb, '苯系物', sources_dict)
        # self.handle_other_sheet(wb, '卤代烃', sources_dict)
        self.handle_other_sheet(wb, '烷烃类', sources_dict)
        self.handle_other_sheet(wb, '烯烃类', sources_dict)
        self.handle_other_sheet(wb, '硫化物', sources_dict)
        self.handle_other_sheet(wb, '胺类', sources_dict)
        self.handle_other_sheet(wb, '其他', sources_dict)

    def handle_other_sheet(self, wb: Workbook, name, sources_dict):
        sheet = wb.get_sheet_by_name(name)
        i = 2
        early_name = ''
        early_cas = ''
        while sheet[f'b{i}'].value:
            item = {}
            chinese_name = sheet[f'a{i}'].value
            if chinese_name:
                early_name = chinese_name
            else:
                chinese_name = early_name
            item['chinese_name'] = chinese_name
            ppm = sheet[f'b{i}'].value
            if isinstance(ppm, str):
                if '<' in ppm or '＜' in ppm:
                    item['ppm_sign'] = '<'
                elif '>' in ppm or '＞'in ppm:
                    item['ppm_sign'] = '>'
                ppm = float(ppm.replace('>', '').replace('<', '').replace('＞', '').replace('＜', ''))
            item['ppm'] = ppm
            mass = sheet[f'c{i}'].value
            if isinstance(mass, str):
                if '<' in mass or '＜' in mass:
                    item['mass_sign'] = '<'
                elif '>' in mass or '＞'in mass:
                    item['mass_sign'] = '>'
                mass = float(mass.replace('>', '').replace('<', '').replace('＞', '').replace('＜', ''))
            item['mass'] = mass
            item['molecular'] = sheet[f'd{i}'].value
            cas = sheet[f'e{i}'].value
            if cas:
                early_cas = cas
            else:
                cas = early_cas
            item['cas'] = cas
            item['odor_type'] = sheet[f'f{i}'].value
            item['threshold_type'] = sheet[f'g{i}'].value
            item['source'] = sources_dict[str(sheet[f'h{i}'].value)]
            item['compound_cate'] = name
            Threshold.objects.get_or_create(defaults=item, 
                                                                       chinese_name=chinese_name,
                                                                       ppm=ppm, mass=mass)
            i = i + 1
