# coding=utf-8
import traceback
import datetime
import time
from django.db import transaction
from django.conf import settings
from django.db.models import Q,Sum
from rest_framework.decorators import action
from rest_framework_jwt.views import ObtainJSONWebToken,VerifyJSONWebToken,RefreshJSONWebToken
from rest_framework.serializers import ValidationError

from utils.custom_modelviewset import CustomModelViewSet
from utils import response_error, response_ok
from .serializers import TenantJWTSerializer
from utils.permission import IsTenantUser, IsAdministratorUser
from .models import Tenant, Pay, Invoice
from apps.admin.tenant.serializers import TenantSerializer
from apps.admin.tenant.filters import TenantFilter
from apps.log.models import BizLog
from apps.tenant.config.models import Config
from utils.exceptions import CustomError
from apps.base import Formater
from apps.WechatApplet.models import WechatApplet
from apps.tenant.serializers import PaySerializer,InvoiceSerializer
from apps.tenant.filters import InvoiceFilter
from rest_framework.views import APIView


class TenantLoginView(ObtainJSONWebToken):
    serializer_class = TenantJWTSerializer

    def post(self, request, *args, **kwargs):
        try:
            ser = self.serializer_class(data=request.data)
            ser.request = request
            if ser.is_valid(raise_exception=True):
                return response_ok(ser.validated_data)
        except ValidationError as e:
            return response_error(e.detail['error'][0])


class TenantVerifyTokenView(VerifyJSONWebToken):
    def post(self, request, *args, **kwargs):
        try:
            ser = self.serializer_class(data=request.data)
            if ser.is_valid(raise_exception=True):
                return response_ok({'token': ser.validated_data['token']})
        except ValidationError as e:
            return response_error(u'登录状态失效，请重新登录[' + e.detail['error'][0] + ']')


class TenantRefreshTokenView(RefreshJSONWebToken):
    def post(self, request, *args, **kwargs):
        try:
            ser = self.serializer_class(data=request.data)
            if ser.is_valid(raise_exception=True):
                return response_ok({'token': ser.validated_data['token']})
        except ValidationError as e:
            return response_error(u'登录状态失效，请重新登录[' + e.detail['error'][0] + ']')

class CompanyViewSet(CustomModelViewSet):
    permission_classes = [IsAdministratorUser,]
    queryset = Tenant.objects.filter(delete=False)
    serializer_class = TenantSerializer

    def filter_queryset(self, queryset):
        queryset = queryset.filter(id=self.request.user.employee.tenant.id)
        f = TenantFilter(self.request.GET, queryset=queryset)
        return f.qs

    @action(methods=['post'], detail=True)
    def update_company(self,request,pk):
        name = request.POST.get('name')
        tel = request.POST.get('tel')
        Tenant.objects.filter(id=pk).update(name=name,tel=tel)
        BizLog.objects.addnew(self.request.user.employee.tenant, self.request.user, BizLog.INSERT, u'修改企业联系人，id=%s' % pk, request.POST)
        return response_ok()

    @action(methods=['get'], detail=True)
    def get_code(self, request, pk):
        pay_channel = request.GET.get('pay_channel')
        pay_edition = request.GET.get('pay_edition') # edition_1_1_year
        amount = Config.getIntValue(pay_edition)
        if amount:
            amount = Formater.formatAmount(amount)
            editions = pay_edition.split('_')
            edition_year = '{},{}'.format(editions[1],editions[2],)
        else:
            raise CustomError('续费金额错误')

        try:
            with transaction.atomic():
                Pay.objects.filter(tenant=request.user.employee.tenant, amount__isnull=True).delete()
                if int(pay_channel) == Pay.WECHAT:
                    line_data = Pay.wechatPay(request.user, pk ,amount, edition_year)
                elif int(pay_channel) == Pay.ALIPAY:
                    line_data = Pay.alipayPay(request.user, pk ,amount, edition_year)
                else:
                    raise CustomError('请选择正确的支付方式!')
                data = {
                    'id': line_data.id,
                    'qrcode': line_data.qrcode
                }
            return response_ok(data)
        except CustomError as e:
            return response_error(str(e))
        except Exception as e:
            traceback.print_exc()
            return response_error(u'支付失败', request)

    @action(methods=['get'], detail=True)
    def get_wxapp_code(self, request, pk):
        try:
            tenant = Tenant.objects.filter(id=pk).first()
            if tenant:
                company_no = tenant.company_no
            else:
                raise CustomError('获取企业信息失败，请刷新重试！')
            if not tenant.wxapp_img:
                applet = WechatApplet.objects.filter(authorizer_appid=settings.WEAPP['appid']).first()
                filename = applet.getWXAppCode(company_no)
                tenant.wxapp_img = "{0}{1}".format(settings.MEDIA_URL,filename)
                tenant.save()

            return response_ok(tenant.wxapp_img)
        except CustomError as e:
            return response_error(str(e))
        except Exception as e:
            traceback.print_exc()
            return response_error(u'支付失败', request)

    @action(methods=['get'], detail=True)
    def confirm_pay(self, request, pk):
        pay_id = request.GET.get('pay_id')
        try:
            with transaction.atomic():
                payment = Pay.objects.filter(id=int(pay_id)).first()
                if not payment:
                    raise CustomError(u'无法找到付款单')
                if payment.status == Pay.WAIT:
                    raise CustomError(u'暂无付款信息，请付款')
                if payment.status == Pay.CONFIRM:
                    raise CustomError(u'已确认付款')
                payment.payConfirm(payment.pay_no)

        except CustomError as e:
            return response_error(str(e))
        except Exception as e:
            traceback.print_exc()
            return response_error(u'验证失败', request)
        return response_ok()

    @action(methods=['get'], detail=True)
    def get_renew_record(self, request, pk):
        payment = Pay.objects.filter(tenant_id=pk)
        data = PaySerializer(payment, many=True).data
        return response_ok(data)

class InvoiceDataView(APIView):
    permission_classes = [IsTenantUser, ]

    def get(self, request):
        tenant = request.user.employee.tenant
        start_date = (datetime.datetime.now() - datetime.timedelta(days=90)).strftime('%Y-%m-%d')
        pay = Pay.objects.filter(invoice__isnull=True, create_time__gte=start_date,
                                 tenant=tenant, status__in=[Pay.PAY, Pay.CONFIRM]).aggregate(amount=Sum('amount'))
        data = {
            'invoice_name': "",
            'tax_no': "",
            'company_address': "",
            'phone_no': "",
            'deposit_bank': "",
            'bank_account': "",
            'invoice_sum': "",
            'consignee': "",
            'consignee_tel': "",
            'consignee_address': "",
        }
        try:
            if not pay['amount']:
                raise CustomError('最近3个月内，暂无发票可申请!')

            invoice = Invoice.objects.filter(tenant=tenant).order_by('-id').first()

            if invoice:
                data = {
                    'invoice_name': invoice.invoice_name,
                    'tax_no': invoice.tax_no,
                    'company_address': invoice.company_address,
                    'phone_no': invoice.phone_no,
                    'deposit_bank': invoice.deposit_bank,
                    'bank_account': invoice.bank_account,
                    'invoice_sum': Formater.formatAmountShow(pay['amount']),
                    'consignee': invoice.consignee,
                    'consignee_tel': invoice.consignee_tel,
                    'consignee_address': invoice.company_address,
                }
            else:
                data['invoice_sum'] = Formater.formatAmountShow(pay['amount'])
        except CustomError as e:
            return response_error(str(e))
        except Exception as e:
            return response_error(str(e))
        return response_ok(data)

class InvoiceViewSet(CustomModelViewSet):
    permission_classes = [IsTenantUser, ]
    queryset = Invoice.objects.filter()
    serializer_class = InvoiceSerializer

    def filter_queryset(self, queryset):
        queryset = queryset.filter(tenant=self.request.user.employee.tenant)
        f = InvoiceFilter(self.request.GET, queryset=queryset)
        return f.qs

    def perform_destroy(self, instance):
        #删除
        if instance.tenant != self.request.user.employee.tenant:
            raise CustomError(u'禁止跨企业操作！')
        super(InvoiceViewSet, self).perform_destroy(instance)
