import json

from flask import request
from flask_wtf import FlaskForm
from wtforms import Field, ValidationError, Form

from src.libs.error import APIException, FormException


class BaseForm(FlaskForm):
    """基础方法"""

    def validate_(self):
        """表单验证"""
        if request.method == 'GET':
            if self.validate() is False:
                message = ''
                for key in self.errors:
                    message = message + '%s:%s' % (key, self.errors[key][0]) + ','
                raise APIException(code=500, message=message)
            else:
                return self
        else:
            if self.validate_on_submit() is False:
                message = ''
                for key in self.errors:
                    message = message + '%s:%s' % (key, self.errors[key][0]) + ','
                raise APIException(code=500, message=message)
            else:
                return self


class RequestBaseForm(Form):
    # 解析请求参数
    def __init__(self):
        if "application/json" in request.headers.get("Content-Type"):
            data = request.get_json(silent=True)
            args = request.args.to_dict()
            super(RequestBaseForm, self).__init__(data=data, **args)
        else:
            data = request.form.to_dict()
            args = request.args.to_dict()
            super(RequestBaseForm, self).__init__(data=data, **args)

    # 对验证错误的参数抛出异常
    def validate_(self):
        valid = super(RequestBaseForm, self).validate()
        if not valid:
            message = ''
            for key in self.errors:
                message = key+message +'--'+ '%s' % (self.errors[key][0]) + ','
            raise APIException(code=500, message=message)

        return self


class JsonField(Field):
    """验证json类型数据字段"""

    def process_formdata(self, value):
        """验证数据类型"""
        data = value

        if not isinstance(data, (dict, list)) and '[' not in data and '{' not in data:
            raise ValidationError('value to json error')
        if isinstance(data, (dict, list)):
            self.data = data
        else:
            try:
                self.data = json.loads(data)
            except BaseException:
                raise ValidationError('value to json error')
