from rest_framework import serializers, status
from django.contrib.auth import authenticate
from django.utils import timezone
from datetime import timedelta
from api.models.access_token import AccessToken
from api.views.admin.base import AdminApiBase
from api.validator import BaseValidator
from api.utils import decrypt_aes_128_cbc, encrypt_aes_128_cbc, log_critical_error, get_exception_detail, \
    get_add_new_data
from rest_framework.exceptions import ValidationError
from api.models.role import Role
from api.models.role_permission import RolePermission
from api.translation import __

class ChangePassword(AdminApiBase):
    def validate_request(self,request):
        rules = {
            "old_password": "required",
            "new_password": "required",
            "new_password_confirmation": "required",
        }

        # if need rename field, can put here
        attribute = {
            # "email": __("attr.email"),
        }

        validator = BaseValidator(request.data,rules,attribute)
        error = validator.validate()
        if error:
            raise ValidationError(error)

        # custom error after basic validation
        if request.data.get("new_password") != request.data.get('new_password_confirmation'):
            raise ValidationError({
                    "error":__('validation.not_match',field=__("attr.new_password"),confirm_field=__("attr.new_password_confirmation")),
                    "errors": {"new_password":__("validation.not_match",field=__("attr.new_password"),confirm_field=__("attr.new_password_confirmation")),}
                })

    def post(self, request):
        # Validate input
        try:
            self.validate_request(request)
            user = request.user
            encrypted_old_password = request.data.get('old_password')
            try:
                old_password = decrypt_aes_128_cbc(encrypted_old_password)
            except Exception:
                raise ValidationError ({
                    "error":__('validation.invalid_format'),
                    "errors": {"old_password":__("validation.invalid_format")}
                })

            # self.validate_request(request)
            encrypted_new_password = request.data.get('new_password')
            try:
                new_password = decrypt_aes_128_cbc(encrypted_new_password)
            except Exception:
                raise ValidationError ({
                    "error":__('validation.invalid_format'),
                    "errors": {"new_password":__("validation.invalid_format")}
                })

            if not user.check_password(old_password):
                raise ValidationError({
                    "error": __('validation.old_password_incorrect'),
                    "errors": {"old_password": __("validation.old_password_incorrect")}
                })
            user.set_password(new_password)
            user.save()

            response = {

            }

            return self.api_response(data=response)
        except ValidationError as e:
            first_message = e.detail['error']
            errors = e.detail['errors']
            return self.api_response(error=first_message,errors=errors,code=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            e_details = get_exception_detail(e)
            log_critical_error(user_id=None,descr=e_details['descr'],url=e_details['url'],trace=e_details['trace'])
            return self.api_response(error=__("message.internal_server_error"),code=status.HTTP_500_INTERNAL_SERVER_ERROR)