# Import the necessary components from flask_restx
from flask_restx import Namespace, Resource, Model, fields

# Import the BrandService from your application's services module
from app.services.brand_service import BrandService

from flask_jwt_extended import create_access_token, create_refresh_token, jwt_required, get_jwt_identity, get_jwt, decode_token

# Create a Flask-RESTx namespace named 'brands' with a description
brand_namespace = Namespace('brands', description='Brand-related operations')

# Define a model for a Brand resource using field s
brand_model = Model('Brand', {
    'name': fields.String(required=True, description='Name of the brand'),
    'description': fields.String(description='A brief description of the brand'),
    # Add more fields as needed to describe the Brand resource.
})

# # Define a resource for handling a list of brands and creating a new brand
@brand_namespace.route('/list')
class BrandListResource(Resource):
    # @jwt_required() # Ensure the request is protected by a valid JWT access token
    @brand_namespace.marshal_list_with(brand_model)
    # @brand_namespace.marshal_with(brand_model, code=200)
    def get(self):
        """Get a list of all brands"""
        try:
            # Retrieve a list of all brands using the BrandService
            brands = BrandService.get_all_brands()
            return brands
        except Exception as e:
            print(e)
            # Handle any exceptions and return a 500 Internal Server Error
            return {'message': 'An error occurred while retrieving brands', 'error': str(e)}, 500

@brand_namespace.route('/create')
class BrandCreateResource(Resource):
    @brand_namespace.expect(brand_model)
    @brand_namespace.marshal_with(brand_model, code=201)
    def post(self):
        """Create a new brand"""
        try:
            # Parse the request payload as per the brand_model
            args = brand_namespace.payload
            # Create a new brand using the BrandService
            brand = BrandService.create_brand(args)
            return brand, 201
        except Exception as e:
            # Handle any exceptions and return a 500 Internal Server Error
            return {'message': 'An error occurred while creating a brand', 'error': str(e)}, 500

@brand_namespace.route('/delete/<string:brand_id>')
class BrandDeleteResources(Resource):
    @brand_namespace.expect(brand_model)
    def delete(self,brand_id):
        try:

            brand_delete = BrandService.delete_brand(brand_id)
            if brand_delete:
                brand_info = BrandService.get_brand_by_id(brand_id)
                return {"message":f"Brand with '{brand_id}' Deleted Successfully."}, 200
            return {"message":f"Brand with '{brand_id}' Not Found"}

        except Exception as ex:

            return {'message': 'An error occurred while creating a brand', 'error': str(ex)}, 500

@brand_namespace.route("/update/<string:brand_id>")
class BrandUpdateResources(Resource):
    @brand_namespace.expect(brand_model)
    def put(self, brand_id):
        """Update a brand by ID"""
        try:
            # Parse the request payload as per the brand_model
            args = brand_namespace.payload
            # Update the brand by its ID using the BrandService
            brand = BrandService.update_brand(brand_id, args)
            if brand:
                return brand
            # Return a 404 response with a message if the brand is not found
            brand_namespace.abort(404, "Brand not found")
        except Exception as e:
            # Handle any exceptions and return a 500 Internal Server Error
            return {'message': 'An error occurred while updating the brand', 'error': str(e)}, 500


# # Define a resource for handling individual brands by their IDs
# @brand_namespace.route('/<string:brand_id>')
# @brand_namespace.param('brand_id', 'The ID of the brand')
# @brand_namespace.response(404, 'Brand not found')
# class BrandResource(Resource):
#     @brand_namespace.marshal_with(brand_model)
#     def get(self, brand_id):
#         """Get a brand by ID"""
#         try:
#             # Retrieve a brand by its ID using the BrandService
#             brand = BrandService.get_brand_by_id(brand_id)
#             if brand:
#                 return brand
#             # Return a 404 response with a message if the brand is not found
#             brand_namespace.abort(404, "Brand not found")
#         except Exception as e:
#             # Handle any exceptions and return a 500 Internal Server Error
#             return {'message': 'An error occurred while retrieving the brand', 'error': str(e)}, 500

#     @brand_namespace.expect(brand_model)
#     @brand_namespace.marshal_with(brand_model)
#     def put(self, brand_id):
#         """Update a brand by ID"""
#         try:
#             # Parse the request payload as per the brand_model
#             args = brand_namespace.payload
#             # Update the brand by its ID using the BrandService
#             brand = BrandService.update_brand(brand_id, args)
#             if brand:
#                 return brand
#             # Return a 404 response with a message if the brand is not found
#             brand_namespace.abort(404, "Brand not found")
#         except Exception as e:
#             # Handle any exceptions and return a 500 Internal Server Error
#             return {'message': 'An error occurred while updating the brand', 'error': str(e)}, 500

#     def delete(self, brand_id):
#         """Delete a brand by ID"""
#         try:
#             # Delete the brand by its ID using the BrandService
#             success = BrandService.delete_brand(brand_id)
#             if success:
#                 # Return a 204 response (No Content) if the deletion is successful
#                 return '', 204
#             # Return a 404 response with a message if the brand is not found
#             brand_namespace.abort(404, "Brand not found")
#         except Exception as e:
#             # Handle any exceptions and return a 500 Internal Server Error
#             return {'message': 'An error occurred while deleting the brand', 'error': str(e)}, 500
