from flask import Blueprint, request
import logging
from datetime import datetime
from firebase.firebase import Firebase
import pytz 
import utility.function as func
import os
import uuid
import base64
from utility.bucketstorage import Storage
from werkzeug.utils import secure_filename
from google.cloud import storage as gcs_storage
logging.basicConfig(level=logging.INFO)

feature_content_v2 = Blueprint('feature_content_v2', __name__, url_prefix='/feature/content/v2')

fb = Firebase(host=os.environ.get("FIREBASE_HOST"))
timezone = pytz.timezone('Asia/Bangkok')

def _validate_required_fields(data, required_fields):
    """Validate required fields using Function.checkRequestData"""
    error = func.Function.checkRequestData(data, required_fields)
    if error:
        return error
    return None

def _validate_string_field(value, field_name):
    """Validate that a field is a non-empty string"""
    if not value or not isinstance(value, str) or not value.strip():
        return {'status': 'error', 'message': f"{field_name} must be a non-empty string"}, 400
    return None

def _validate_json_field(value, field_name):
    """Validate that a field is a valid JSON object or array"""
    if value is None:
        return {'status': 'error', 'message': f"{field_name} is required"}, 400
    if not isinstance(value, (dict, list)):
        return {'status': 'error', 'message': f"{field_name} must be a valid JSON object or array"}, 400
    try:
        import json
        json.dumps(value)
    except (TypeError, ValueError):
        return {'status': 'error', 'message': f"{field_name} must be valid JSON"}, 400
    return None

def _validate_sms_message(value, field_name='message', is_unicode=False):
    """Validate SMS message text"""
    if value is None:
        return {'status': 'error', 'message': f"{field_name} is required"}, 400
    if not isinstance(value, str) or not value.strip():
        return {'status': 'error', 'message': f"{field_name} must be a non-empty string"}, 400
    
    # SMS length limits
    max_length_unicode = 70  # characters per message for unicode
    max_length_standard = 160  # characters per message for standard
    max_length_total = 1000  # absolute maximum
    
    message_length = len(value)
    
    if message_length > max_length_total:
        return {'status': 'error', 'message': f"{field_name} exceeds maximum length of {max_length_total} characters"}, 400
    
    if is_unicode and message_length > max_length_unicode:
        return {'status': 'error', 'message': f"{field_name} exceeds maximum length of {max_length_unicode} characters for unicode SMS"}, 400
    elif not is_unicode and message_length > max_length_standard:
        return {'status': 'error', 'message': f"{field_name} exceeds maximum length of {max_length_standard} characters for standard SMS"}, 400
    
    return None

def _validate_email_subject(value, field_name='subject'):
    """Validate email subject line"""
    if value is None:
        return {'status': 'error', 'message': f"{field_name} is required"}, 400
    if not isinstance(value, str) or not value.strip():
        return {'status': 'error', 'message': f"{field_name} must be a non-empty string"}, 400
    
    max_length = 200
    if len(value) > max_length:
        return {'status': 'error', 'message': f"{field_name} exceeds maximum length of {max_length} characters"}, 400
    
    return None

def _validate_email_body(value, field_name='body'):
    """Validate email body content"""
    if value is None:
        return {'status': 'error', 'message': f"{field_name} is required"}, 400
    if not isinstance(value, str) or not value.strip():
        return {'status': 'error', 'message': f"{field_name} must be a non-empty string"}, 400
    
    max_length = 100 * 1024  # 100KB
    if len(value) > max_length:
        return {'status': 'error', 'message': f"{field_name} exceeds maximum length of {max_length / 1024}KB"}, 400
    
    return None

def _validate_email_address(value, field_name='email'):
    """Validate email address format"""
    if value is None or value == '':
        return None  # Optional field
    
    if not isinstance(value, str):
        return {'status': 'error', 'message': f"{field_name} must be a string"}, 400
    
    import re
    email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    if not re.match(email_pattern, value.strip()):
        return {'status': 'error', 'message': f"{field_name} must be a valid email address"}, 400
    
    return None

def _get_content_path(property_id, platform, content_id=None):
    """Helper function to generate Firebase path for content"""
    base_path = f"account/{property_id}/content/{platform}"
    if content_id:
        return f"{base_path}/{content_id}"
    return base_path

def _create_content(property_id, platform, name, json_data=None, user_id=None, json_preview=None, 
                   message=None, sender_id=None, unicode=None,
                   subject=None, body=None, from_email=None, from_name=None, is_html=None):
    """Helper function to create content"""
    now = datetime.now(timezone).strftime("%Y-%m-%d %H:%M:%S")
    contentId = func.Function.generate_uuid_from_text(f"{now}_{name}")
    
    base_path = _get_content_path(property_id, platform, contentId)
    fb.db.reference().child(f"{base_path}/name").set(name)
    fb.db.reference().child(f"{base_path}/createdate").set(now)
    fb.db.reference().child(f"{base_path}/lastupdate").set(now)
    
    # Platform-specific fields
    if platform == 'line' or platform == 'facebook':
        if json_data is not None:
            fb.db.reference().child(f"{base_path}/json").set(json_data)
        if json_preview is not None:
            fb.db.reference().child(f"{base_path}/json_preview").set(json_preview)
    elif platform == 'sms':
        if message is not None:
            fb.db.reference().child(f"{base_path}/message").set(message)
        if sender_id is not None:
            fb.db.reference().child(f"{base_path}/sender_id").set(sender_id)
        if unicode is not None:
            fb.db.reference().child(f"{base_path}/unicode").set(unicode)
    elif platform == 'email':
        if subject is not None:
            fb.db.reference().child(f"{base_path}/subject").set(subject)
        if body is not None:
            fb.db.reference().child(f"{base_path}/body").set(body)
        if from_email is not None:
            fb.db.reference().child(f"{base_path}/from_email").set(from_email)
        if from_name is not None:
            fb.db.reference().child(f"{base_path}/from_name").set(from_name)
        if is_html is not None:
            fb.db.reference().child(f"{base_path}/is_html").set(is_html)
    
    if user_id:
        fb.db.reference().child(f"{base_path}/lastupdate_by").set(user_id)
    
    return contentId

def _get_content(property_id, platform, content_id):
    """Helper function to get content"""
    if content_id != 'all':
        content = fb.db.reference().child(_get_content_path(property_id, platform, content_id)).get()
        if not content:
            return None, None
        return [content], None
    else:
        contentData = fb.db.reference().child(_get_content_path(property_id, platform)).get()
        if not contentData:
            return None, 'not_found'
        newListContent = []
        for con in contentData:
            context = contentData[con]
            context['content_id'] = con
            newListContent.append(context)
        return newListContent, None

def _update_content(property_id, platform, content_id, name=None, json_data=None, user_id=None, json_preview=None,
                   message=None, sender_id=None, unicode=None,
                   subject=None, body=None, from_email=None, from_name=None, is_html=None):
    """Helper function to update content"""
    now = datetime.now(timezone).strftime("%Y-%m-%d %H:%M:%S")
    base_path = _get_content_path(property_id, platform, content_id)
    
    # Get existing values if not provided
    if name is None:
        name = fb.db.reference().child(f"{base_path}/name").get()
    
    # Update common fields
    fb.db.reference().child(f"{base_path}/lastupdate").set(now)
    fb.db.reference().child(f"{base_path}/name").set(name)
    
    # Platform-specific fields
    if platform == 'line' or platform == 'facebook':
        if json_data is None:
            json_data = fb.db.reference().child(f"{base_path}/json").get()
        fb.db.reference().child(f"{base_path}/json").set(json_data)
        
        if platform == 'line':
            if json_preview is None:
                json_preview = fb.db.reference().child(f"{base_path}/json_preview").get()
            if json_preview is not None:
                fb.db.reference().child(f"{base_path}/json_preview").set(json_preview)
    elif platform == 'sms':
        if message is None:
            message = fb.db.reference().child(f"{base_path}/message").get()
        if message is not None:
            fb.db.reference().child(f"{base_path}/message").set(message)
        if sender_id is not None:
            fb.db.reference().child(f"{base_path}/sender_id").set(sender_id)
        if unicode is not None:
            fb.db.reference().child(f"{base_path}/unicode").set(unicode)
    elif platform == 'email':
        if subject is None:
            subject = fb.db.reference().child(f"{base_path}/subject").get()
        if subject is not None:
            fb.db.reference().child(f"{base_path}/subject").set(subject)
        
        if body is None:
            body = fb.db.reference().child(f"{base_path}/body").get()
        if body is not None:
            fb.db.reference().child(f"{base_path}/body").set(body)
        
        if from_email is not None:
            fb.db.reference().child(f"{base_path}/from_email").set(from_email)
        if from_name is not None:
            fb.db.reference().child(f"{base_path}/from_name").set(from_name)
        if is_html is not None:
            fb.db.reference().child(f"{base_path}/is_html").set(is_html)
    
    if user_id:
        fb.db.reference().child(f"{base_path}/lastupdate_by").set(user_id)

def _delete_content(property_id, platform, content_id):
    """Helper function to delete content"""
    base_path = _get_content_path(property_id, platform, content_id)
    fb.db.reference().child(base_path).delete()

@feature_content_v2.route('/image/upload',  methods=['POST'])
@feature_content_v2.route('/image/upload/',  methods=['POST'])
def feature_content_image_upload():
    try:
        # Validate content type - support both JPEG and PNG
        allowed_content_types = ['image/jpeg', 'image/jpg', 'image/png']
        if request.content_type not in allowed_content_types:
            return {"status": "error", "message": f"Content-Type must be one of: {', '.join(allowed_content_types)}"}, 400
        
        image_data = request.data
        if not image_data:
            return {"status": "error", 'message': 'No selected image'}, 400
        
        # Validate file size (e.g., max 10MB)
        max_size = 10 * 1024 * 1024  # 10MB
        if len(image_data) > max_size:
            return {"status": "error", 'message': f'Image size exceeds maximum allowed size of {max_size / (1024*1024)}MB'}, 400
        
        now = datetime.now(timezone)
        time_now = int(now.timestamp())
        
        # Determine file extension based on content type
        if request.content_type in ['image/jpeg', 'image/jpg']:
            file_extension = 'jpg'
        elif request.content_type == 'image/png':
            file_extension = 'png'
        else:
            file_extension = 'png'  # default
        
        generate_image_file_name = f"""{uuid.uuid4()}_{time_now}.{file_extension}"""

        try:
            filename = secure_filename(generate_image_file_name)
            gcs_blob_name = f"content/{filename}"

            # Upload to GCS
            storage = Storage(project_id=os.environ.get("GCP_PROJECT"), bucket_name=os.environ.get("GC_BUCKET_NAME"))
            link = storage.upload_from_byte(file_path=gcs_blob_name, image_bytes=image_data)

            if link:
                #Update DB
                return {"status": "ok",'message': 'Image uploaded successfully', 'image_address': link}, 201
            else:
                return {"status": "error",'message': 'Failed to upload image to GCS'}, 500

        except Exception as e:
            logging.info(f"Error processing upload: {e}")
            return {"status": "error",'message': f'An error occurred: {e}'}, 500
        
    
    except Exception as e:
        logging.error(e)
        return {'status': 'error', 'message': str(e)}, 500


@feature_content_v2.route('/line',  methods=['GET','POST', 'PUT', 'DELETE'])
@feature_content_v2.route('/line/',  methods=['GET','POST', 'PUT', 'DELETE'])
def feature_content_route():
    try:
        now = datetime.now(timezone).strftime("%Y-%m-%d %H:%M:%S")
        if request.method == 'POST':
            
            data = request.get_json()
            if not data:
                return {'status': 'error', 'message': 'Request body is required'}, 400
            
            error = _validate_required_fields(data, ['property_id', 'json', 'json_preview', 'name', 'user_id'])
            if error:
                return error
            
            property_id = data.get("property_id")
            name = data.get("name")
            json_data = data.get("json")
            json_preview = data.get("json_preview")
            user_id = data.get("user_id")
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            error = _validate_string_field(name, 'name')
            if error:
                return error
            
            error = _validate_string_field(user_id, 'user_id')
            if error:
                return error
            
            error = _validate_json_field(json_data, 'json')
            if error:
                return error
            
            error = _validate_json_field(json_preview, 'json_preview')
            if error:
                return error
                
            try:
                contentId = _create_content(property_id, 'line', name, json_data, user_id, json_preview)
                return {'status': 'ok', 'message': f'Content {name} was created successfully', "content_id": contentId}, 200
            except Exception as e:
                logging.error(f"Error creating content: {e}")
                return {'status': 'error', 'message': f'Failed to create content: {str(e)}'}, 500

        elif request.method == 'GET':
            data = request.args
            error = _validate_required_fields(data, ['property_id', 'content_id'])
            if error:
                return error
            
            property_id = data.get("property_id")
            content_id = data.get("content_id")
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            if content_id != 'all':
                error = _validate_string_field(content_id, 'content_id')
                if error:
                    return error
            
            try:
                newListContent, error_status = _get_content(property_id, 'line', content_id)
                if error_status == 'not_found':
                    return {'status': 'not_found', 'message': 'No content created'}, 404
                
                if newListContent:
                    content_desc = sorted(newListContent, key=lambda x: x['createdate'], reverse=True)
                    return {'status': 'ok', 'data': content_desc}, 200
                else:
                    return {'status': 'not_found', 'message': "No content was created"}, 404
            except Exception as e:
                logging.error(f"Error getting content: {e}")
                return {'status': 'error', 'message': f'Failed to get content: {str(e)}'}, 500

        elif request.method == 'PUT':

            data = request.get_json()
            if not data:
                return {'status': 'error', 'message': 'Request body is required'}, 400
            
            error = _validate_required_fields(data, ['property_id', 'content_id', 'user_id'])
            if error:
                return error
            
            content_id = data.get("content_id")
            property_id = data.get("property_id")
            user_id = data.get("user_id")
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            error = _validate_string_field(content_id, 'content_id')
            if error:
                return error
            
            error = _validate_string_field(user_id, 'user_id')
            if error:
                return error
            
            name = data.get("name") if 'name' in data else None
            json_data = data.get("json") if 'json' in data else None
            json_preview = data.get("json_preview") if 'json_preview' in data else None
            
            if 'name' in data:
                error = _validate_string_field(name, 'name')
                if error:
                    return error
            
            if 'json' in data:
                error = _validate_json_field(json_data, 'json')
                if error:
                    return error
            
            if 'json_preview' in data:
                error = _validate_json_field(json_preview, 'json_preview')
                if error:
                    return error
            
            try:
                _update_content(property_id, 'line', content_id, name, json_data, user_id, json_preview)
                return {"status": "ok", "message": f"Content {content_id} was updated"}, 200
            except Exception as e:
                logging.error(f"Error updating content: {e}")
                return {'status': 'error', 'message': f'Failed to update content: {str(e)}'}, 500
        
        elif request.method == 'DELETE':
            data = request.get_json()
            if not data:
                return {'status': 'error', 'message': 'Request body is required'}, 400
            
            error = _validate_required_fields(data, ['property_id', 'user_id', 'content_id'])
            if error:
                return error
            
            property_id = data.get("property_id")
            content_id = data.get("content_id")
            user_id = data.get("user_id")
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            error = _validate_string_field(content_id, 'content_id')
            if error:
                return error
            
            error = _validate_string_field(user_id, 'user_id')
            if error:
                return error

            try:
                _delete_content(property_id, 'line', content_id)
                return {'status': 'ok', 'message': f'Content {content_id} was deleted'}, 200
            except Exception as e:
                logging.error(f"Error deleting content: {e}")
                return {'status': 'error', 'message': f'Failed to delete content: {str(e)}'}, 500  

        return {'status': 'error', 'message': 'Method not allowed'}, 405
    
    except Exception as e:
        logging.error(f"Content function error: {e}")
        return {'status': 'error', 'message': str(e)}, 500
    
@feature_content_v2.route('/line/automation',  methods=['GET'])
@feature_content_v2.route('/line/automation/',  methods=['GET'])
def feature_content_line_automation():
    try:
        data = request.args
        error = _validate_required_fields(data, ['property_id', 'content_id'])
        if error:
            return error
        
        property_id = data.get("property_id")
        content_id = data.get("content_id")
        
        error = _validate_string_field(property_id, 'property_id')
        if error:
            return error
        
        error = _validate_string_field(content_id, 'content_id')
        if error:
            return error

        now = datetime.now(timezone).strftime("%Y-%m-%d %H:%M")
        
        try:
            contentAutomations = fb.db.reference().child(f"account/{property_id}/content/line/{content_id}/automations").get()
        except Exception as e:
            logging.error(f"Error fetching content automations: {e}")
            return {'status': 'error', 'message': f'Failed to fetch content automations: {str(e)}'}, 500
        
        if contentAutomations:
            # Loop get name
            from dashboard.genQuery import GenerateQuery
            from utility.cloudsql import CloudSQL
            
            csql = None
            try:
                csql = CloudSQL("asia-southeast1", os.environ.get("INSTANCE_NAME"))
                csql.create_engine(os.environ.get("POSTGRES_USER"), os.environ.get("POSTGRES_PASSWORD"), os.environ.get("POSTGRES_DB"))
                
                listAutomation = []
                for auto in contentAutomations:
                    try:
                        autoName = fb.db.reference().child(f"account/{property_id}/automation/{auto}/name").get()
                    except Exception as e:
                        logging.error(f"Error fetching automation name for {auto}: {e}")
                        autoName = None

                    try:
                        genq = GenerateQuery(property_id=property_id)
                        query = genq.getNextSchedual(automation_id=auto, now=now)
                        result = csql.query(query)
                        nextSchedule = result[0][0].strftime("%Y-%m-%d %H:%M") if result and result[0] and result[0][0] else 'Automation not active'
                    except Exception as e:
                        logging.error(f"Error querying next schedule for automation {auto}: {e}")
                        nextSchedule = 'Error fetching schedule'

                    #Get next push
                    packAuto = {
                        "automation_id": auto,
                        "automation_name": autoName,
                        "next_schedule": nextSchedule
                    }
                    listAutomation.append(packAuto)
                
                return {'status': 'ok', 'data': listAutomation}, 200
            except Exception as e:
                logging.error(f"Error processing automations: {e}")
                return {'status': 'error', 'message': f'Failed to process automations: {str(e)}'}, 500
            finally:
                if csql:
                    try:
                        csql.close()
                    except Exception as e:
                        logging.error(f"Error closing database connection: {e}")
        else:
            return {'status': 'ok', 'message': 'This content not use in any automation flow'}, 200
    except Exception as e:
        logging.error(f"Content automation error: {e}")
        return {'status': 'error', 'message': str(e)}, 500
    

@feature_content_v2.route('/facebook',  methods=['GET','POST', 'PUT', 'DELETE'])
@feature_content_v2.route('/facebook/',  methods=['GET','POST', 'PUT', 'DELETE'])
def feature_content_route_facebook():
    try:
        now = datetime.now(timezone).strftime("%Y-%m-%d %H:%M:%S")
        if request.method == 'POST':
            
            data = request.get_json()
            if not data:
                return {'status': 'error', 'message': 'Request body is required'}, 400
            
            error = _validate_required_fields(data, ['property_id', 'json', 'name'])
            if error:
                return error
            
            property_id = data.get("property_id")
            name = data.get("name")
            json_data = data.get("json")
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            error = _validate_string_field(name, 'name')
            if error:
                return error
            
            error = _validate_json_field(json_data, 'json')
            if error:
                return error
            
            try:
                contentId = _create_content(property_id, 'facebook', name, json_data)
                return {'status': 'ok', 'message': f'Content {name} was created successfully', "content_id": contentId}, 200
            except Exception as e:
                logging.error(f"Error creating content: {e}")
                return {'status': 'error', 'message': f'Failed to create content: {str(e)}'}, 500     
        
        elif request.method == 'GET':
            data = request.args
            error = _validate_required_fields(data, ['property_id', 'content_id'])
            if error:
                return error
            
            property_id = data.get("property_id")
            content_id = data.get("content_id")
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            if content_id != 'all':
                error = _validate_string_field(content_id, 'content_id')
                if error:
                    return error
            
            try:
                newListContent, error_status = _get_content(property_id, 'facebook', content_id)
                if error_status == 'not_found':
                    return {'status': 'not_found', 'message': 'No content created'}, 404
                
                if newListContent:
                    content_desc = sorted(newListContent, key=lambda x: x['createdate'], reverse=True)
                    return {'status': 'ok', 'data': content_desc}, 200
                else:
                    return {'status': 'not_found', 'message': "No content was created"}, 404
            except Exception as e:
                logging.error(f"Error getting content: {e}")
                return {'status': 'error', 'message': f'Failed to get content: {str(e)}'}, 500  
            
        elif request.method == 'PUT':

            data = request.get_json()
            if not data:
                return {'status': 'error', 'message': 'Request body is required'}, 400
            
            error = _validate_required_fields(data, ['property_id', 'content_id'])
            if error:
                return error
            
            content_id = data.get("content_id")
            property_id = data.get("property_id")
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            error = _validate_string_field(content_id, 'content_id')
            if error:
                return error
            
            name = data.get("name") if 'name' in data else None
            json_data = data.get("json") if 'json' in data else None
            
            if 'name' in data:
                error = _validate_string_field(name, 'name')
                if error:
                    return error
            
            if 'json' in data:
                error = _validate_json_field(json_data, 'json')
                if error:
                    return error
            
            try:
                _update_content(property_id, 'facebook', content_id, name, json_data)
                return {"status": "ok", "message": f"Content {content_id} was updated"}, 200
            except Exception as e:
                logging.error(f"Error updating content: {e}")
                return {'status': 'error', 'message': f'Failed to update content: {str(e)}'}, 500    
        
        elif request.method == 'DELETE':
            data = request.get_json()
            if not data:
                return {'status': 'error', 'message': 'Request body is required'}, 400
            
            error = _validate_required_fields(data, ['property_id', 'content_id'])
            if error:
                return error
            
            property_id = data.get("property_id")
            content_id = data.get("content_id")
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            error = _validate_string_field(content_id, 'content_id')
            if error:
                return error

            try:
                _delete_content(property_id, 'facebook', content_id)
                return {'status': 'ok', 'message': f'Content {content_id} was deleted'}, 200
            except Exception as e:
                logging.error(f"Error deleting content: {e}")
                return {'status': 'error', 'message': f'Failed to delete content: {str(e)}'}, 500  

        return {'status': 'error', 'message': 'Method not allowed'}, 405 
        
    except Exception as e:
        logging.error(f"Content function error: {e}")
        return {'status': 'error', 'message': str(e)}, 500

@feature_content_v2.route('/sms',  methods=['GET','POST', 'PUT', 'DELETE'])
@feature_content_v2.route('/sms/',  methods=['GET','POST', 'PUT', 'DELETE'])
def feature_content_route_sms():
    try:
        if request.method == 'POST':
            
            data = request.get_json()
            if not data:
                return {'status': 'error', 'message': 'Request body is required'}, 400
            
            error = _validate_required_fields(data, ['property_id', 'name', 'message', 'user_id'])
            if error:
                return error
            
            property_id = data.get("property_id")
            name = data.get("name")
            message = data.get("message")
            user_id = data.get("user_id")
            sender_id = data.get("sender_id")
            unicode = data.get("unicode", False)
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            error = _validate_string_field(name, 'name')
            if error:
                return error
            
            error = _validate_string_field(user_id, 'user_id')
            if error:
                return error
            
            error = _validate_sms_message(message, 'message', unicode)
            if error:
                return error
            
            if sender_id is not None:
                error = _validate_string_field(sender_id, 'sender_id')
                if error:
                    return error
                
            try:
                contentId = _create_content(property_id, 'sms', name, user_id=user_id, 
                                          message=message, sender_id=sender_id, unicode=unicode)
                return {'status': 'ok', 'message': f'Content {name} was created successfully', "content_id": contentId}, 200
            except Exception as e:
                logging.error(f"Error creating SMS content: {e}")
                return {'status': 'error', 'message': f'Failed to create content: {str(e)}'}, 500

        elif request.method == 'GET':
            data = request.args
            error = _validate_required_fields(data, ['property_id', 'content_id'])
            if error:
                return error
            
            property_id = data.get("property_id")
            content_id = data.get("content_id")
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            if content_id != 'all':
                error = _validate_string_field(content_id, 'content_id')
                if error:
                    return error
            
            try:
                newListContent, error_status = _get_content(property_id, 'sms', content_id)
                if error_status == 'not_found':
                    return {'status': 'not_found', 'message': 'No content created'}, 404
                
                if newListContent:
                    content_desc = sorted(newListContent, key=lambda x: x['createdate'], reverse=True)
                    return {'status': 'ok', 'data': content_desc}, 200
                else:
                    return {'status': 'not_found', 'message': "No content was created"}, 404
            except Exception as e:
                logging.error(f"Error getting SMS content: {e}")
                return {'status': 'error', 'message': f'Failed to get content: {str(e)}'}, 500

        elif request.method == 'PUT':

            data = request.get_json()
            if not data:
                return {'status': 'error', 'message': 'Request body is required'}, 400
            
            error = _validate_required_fields(data, ['property_id', 'content_id', 'user_id'])
            if error:
                return error
            
            content_id = data.get("content_id")
            property_id = data.get("property_id")
            user_id = data.get("user_id")
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            error = _validate_string_field(content_id, 'content_id')
            if error:
                return error
            
            error = _validate_string_field(user_id, 'user_id')
            if error:
                return error
            
            name = data.get("name") if 'name' in data else None
            message = data.get("message") if 'message' in data else None
            sender_id = data.get("sender_id") if 'sender_id' in data else None
            unicode = data.get("unicode") if 'unicode' in data else None
            
            if 'name' in data:
                error = _validate_string_field(name, 'name')
                if error:
                    return error
            
            if 'message' in data:
                is_unicode = unicode if unicode is not None else False
                error = _validate_sms_message(message, 'message', is_unicode)
                if error:
                    return error
            
            if 'sender_id' in data and sender_id is not None:
                error = _validate_string_field(sender_id, 'sender_id')
                if error:
                    return error
            
            try:
                _update_content(property_id, 'sms', content_id, name=name, user_id=user_id,
                              message=message, sender_id=sender_id, unicode=unicode)
                return {"status": "ok", "message": f"Content {content_id} was updated"}, 200
            except Exception as e:
                logging.error(f"Error updating SMS content: {e}")
                return {'status': 'error', 'message': f'Failed to update content: {str(e)}'}, 500
        
        elif request.method == 'DELETE':
            data = request.get_json()
            if not data:
                return {'status': 'error', 'message': 'Request body is required'}, 400
            
            error = _validate_required_fields(data, ['property_id', 'user_id', 'content_id'])
            if error:
                return error
            
            property_id = data.get("property_id")
            content_id = data.get("content_id")
            user_id = data.get("user_id")
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            error = _validate_string_field(content_id, 'content_id')
            if error:
                return error
            
            error = _validate_string_field(user_id, 'user_id')
            if error:
                return error

            try:
                _delete_content(property_id, 'sms', content_id)
                return {'status': 'ok', 'message': f'Content {content_id} was deleted'}, 200
            except Exception as e:
                logging.error(f"Error deleting SMS content: {e}")
                return {'status': 'error', 'message': f'Failed to delete content: {str(e)}'}, 500

        return {'status': 'error', 'message': 'Method not allowed'}, 405 
        
    except Exception as e:
        logging.error(f"Content SMS function error: {e}")
        return {'status': 'error', 'message': str(e)}, 500

@feature_content_v2.route('/email',  methods=['GET','POST', 'PUT', 'DELETE'])
@feature_content_v2.route('/email/',  methods=['GET','POST', 'PUT', 'DELETE'])
def feature_content_route_email():
    try:
        if request.method == 'POST':
            
            data = request.get_json()
            if not data:
                return {'status': 'error', 'message': 'Request body is required'}, 400
            
            error = _validate_required_fields(data, ['property_id', 'name', 'subject', 'body', 'user_id'])
            if error:
                return error
            
            property_id = data.get("property_id")
            name = data.get("name")
            subject = data.get("subject")
            body = data.get("body")
            user_id = data.get("user_id")
            from_email = data.get("from_email")
            from_name = data.get("from_name")
            is_html = data.get("is_html", False)
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            error = _validate_string_field(name, 'name')
            if error:
                return error
            
            error = _validate_string_field(user_id, 'user_id')
            if error:
                return error
            
            error = _validate_email_subject(subject, 'subject')
            if error:
                return error
            
            error = _validate_email_body(body, 'body')
            if error:
                return error
            
            if from_email is not None:
                error = _validate_email_address(from_email, 'from_email')
                if error:
                    return error
            
            if from_name is not None:
                error = _validate_string_field(from_name, 'from_name')
                if error:
                    return error
                
            try:
                contentId = _create_content(property_id, 'email', name, user_id=user_id, 
                                          subject=subject, body=body, from_email=from_email, 
                                          from_name=from_name, is_html=is_html)
                return {'status': 'ok', 'message': f'Content {name} was created successfully', "content_id": contentId}, 200
            except Exception as e:
                logging.error(f"Error creating Email content: {e}")
                return {'status': 'error', 'message': f'Failed to create content: {str(e)}'}, 500

        elif request.method == 'GET':
            data = request.args
            error = _validate_required_fields(data, ['property_id', 'content_id'])
            if error:
                return error
            
            property_id = data.get("property_id")
            content_id = data.get("content_id")
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            if content_id != 'all':
                error = _validate_string_field(content_id, 'content_id')
                if error:
                    return error
            
            try:
                newListContent, error_status = _get_content(property_id, 'email', content_id)
                if error_status == 'not_found':
                    return {'status': 'not_found', 'message': 'No content created'}, 404
                
                if newListContent:
                    content_desc = sorted(newListContent, key=lambda x: x['createdate'], reverse=True)
                    return {'status': 'ok', 'data': content_desc}, 200
                else:
                    return {'status': 'not_found', 'message': "No content was created"}, 404
            except Exception as e:
                logging.error(f"Error getting Email content: {e}")
                return {'status': 'error', 'message': f'Failed to get content: {str(e)}'}, 500

        elif request.method == 'PUT':

            data = request.get_json()
            if not data:
                return {'status': 'error', 'message': 'Request body is required'}, 400
            
            error = _validate_required_fields(data, ['property_id', 'content_id', 'user_id'])
            if error:
                return error
            
            content_id = data.get("content_id")
            property_id = data.get("property_id")
            user_id = data.get("user_id")
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            error = _validate_string_field(content_id, 'content_id')
            if error:
                return error
            
            error = _validate_string_field(user_id, 'user_id')
            if error:
                return error
            
            name = data.get("name") if 'name' in data else None
            subject = data.get("subject") if 'subject' in data else None
            body = data.get("body") if 'body' in data else None
            from_email = data.get("from_email") if 'from_email' in data else None
            from_name = data.get("from_name") if 'from_name' in data else None
            is_html = data.get("is_html") if 'is_html' in data else None
            
            if 'name' in data:
                error = _validate_string_field(name, 'name')
                if error:
                    return error
            
            if 'subject' in data:
                error = _validate_email_subject(subject, 'subject')
                if error:
                    return error
            
            if 'body' in data:
                error = _validate_email_body(body, 'body')
                if error:
                    return error
            
            if 'from_email' in data and from_email is not None:
                error = _validate_email_address(from_email, 'from_email')
                if error:
                    return error
            
            if 'from_name' in data and from_name is not None:
                error = _validate_string_field(from_name, 'from_name')
                if error:
                    return error
            
            try:
                _update_content(property_id, 'email', content_id, name=name, user_id=user_id,
                              subject=subject, body=body, from_email=from_email, 
                              from_name=from_name, is_html=is_html)
                return {"status": "ok", "message": f"Content {content_id} was updated"}, 200
            except Exception as e:
                logging.error(f"Error updating Email content: {e}")
                return {'status': 'error', 'message': f'Failed to update content: {str(e)}'}, 500
        
        elif request.method == 'DELETE':
            data = request.get_json()
            if not data:
                return {'status': 'error', 'message': 'Request body is required'}, 400
            
            error = _validate_required_fields(data, ['property_id', 'user_id', 'content_id'])
            if error:
                return error
            
            property_id = data.get("property_id")
            content_id = data.get("content_id")
            user_id = data.get("user_id")
            
            error = _validate_string_field(property_id, 'property_id')
            if error:
                return error
            
            error = _validate_string_field(content_id, 'content_id')
            if error:
                return error
            
            error = _validate_string_field(user_id, 'user_id')
            if error:
                return error

            try:
                _delete_content(property_id, 'email', content_id)
                return {'status': 'ok', 'message': f'Content {content_id} was deleted'}, 200
            except Exception as e:
                logging.error(f"Error deleting Email content: {e}")
                return {'status': 'error', 'message': f'Failed to delete content: {str(e)}'}, 500

        return {'status': 'error', 'message': 'Method not allowed'}, 405 
        
    except Exception as e:
        logging.error(f"Content Email function error: {e}")
        return {'status': 'error', 'message': str(e)}, 500

@feature_content_v2.route('/email/upload',  methods=['POST'])
@feature_content_v2.route('/email/upload/',  methods=['POST'])
def feature_content_email_upload():
    try:
        data = request.get_json()
        if not data:
            return {'status': 'error', 'message': 'Request body is required'}, 400
        
        # Validate required fields
        error = _validate_required_fields(data, ['property_id', 'file_name', 'file_data'])
        if error:
            return error
        
        property_id = data.get("property_id")
        file_name = data.get("file_name")
        file_data = data.get("file_data")
        folder = data.get("folder", "email")
        
        # Validate property_id
        error = _validate_string_field(property_id, 'property_id')
        if error:
            return error
        
        # Validate file_name
        error = _validate_string_field(file_name, 'file_name')
        if error:
            return error
        
        # Validate file_data (base64 string)
        if not file_data or not isinstance(file_data, str):
            return {'status': 'error', 'message': 'file_data must be a base64 encoded string'}, 400
        
        # Decode base64 to bytes
        try:
            # Handle data URL format (data:image/png;base64,...) if present
            if ',' in file_data:
                file_data = file_data.split(',')[1]
            
            file_bytes = base64.b64decode(file_data)
            if not file_bytes:
                return {'status': 'error', 'message': 'Invalid base64 encoded data'}, 400
        except Exception as e:
            logging.error(f"Error decoding base64: {e}")
            return {'status': 'error', 'message': f'Failed to decode base64 data: {str(e)}'}, 400
        
        # Validate file size (max 10MB)
        max_size = 10 * 1024 * 1024  # 10MB
        if len(file_bytes) > max_size:
            return {'status': 'error', 'message': f'File size exceeds maximum allowed size of {max_size / (1024*1024)}MB'}, 400
        
        # Get file extension from file_name
        file_extension = os.path.splitext(file_name)[1].lower()
        if not file_extension:
            file_extension = '.jpg'  # default extension
        
        # Generate unique filename with timestamp
        now = datetime.now(timezone)
        time_now = int(now.timestamp())
        base_name = os.path.splitext(secure_filename(file_name))[0]
        unique_filename = f"{base_name}_{uuid.uuid4().hex[:8]}_{time_now}{file_extension}"
        
        # Determine content type based on extension
        content_type_map = {
            '.jpg': 'image/jpeg',
            '.jpeg': 'image/jpeg',
            '.png': 'image/png',
            '.gif': 'image/gif',
            '.pdf': 'application/pdf',
            '.doc': 'application/msword',
            '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
            '.xls': 'application/vnd.ms-excel',
            '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        }
        content_type = content_type_map.get(file_extension, 'application/octet-stream')
        
        # Construct GCS path: email/{property_id}/{filename}
        gcs_blob_name = f"{folder}/{property_id}/{unique_filename}"
        
        try:
            # Upload to GCS - use c360-public-resource bucket
            # Use Google Cloud Storage client directly to set proper content_type
            client = gcs_storage.Client(project=os.environ.get("GCP_PROJECT"))
            bucket = client.bucket("c360-public-resource")
            blob = bucket.blob(gcs_blob_name)
            
            blob.upload_from_string(file_bytes, content_type=content_type)
            # Bucket uses uniform bucket-level access: avoid per-object ACL
            public_url = f"https://storage.googleapis.com/{bucket.name}/{gcs_blob_name}"
            
            if public_url:
                return {
                    "status": "0000",
                    "data": {
                        "url": public_url,
                        "file_url": public_url
                    }
                }, 200
            else:
                return {'status': 'error', 'message': 'Failed to upload file to GCS'}, 500
                
        except Exception as e:
            logging.error(f"Error uploading file to GCS: {e}")
            return {'status': 'error', 'message': f'Failed to upload file: {str(e)}'}, 500
    
    except Exception as e:
        logging.error(f"Email upload function error: {e}")
        return {'status': 'error', 'message': str(e)}, 500

@feature_content_v2.route('/email/files',  methods=['GET'])
@feature_content_v2.route('/email/files/',  methods=['GET'])
def feature_content_email_files():
    try:
        data = request.args
        
        # Validate required fields
        error = _validate_required_fields(data, ['property_id'])
        if error:
            return error
        
        property_id = data.get("property_id")
        folder = data.get("folder", "email")
        
        # Validate property_id
        error = _validate_string_field(property_id, 'property_id')
        if error:
            return error
        
        try:
            # List files from GCS bucket
            client = gcs_storage.Client(project=os.environ.get("GCP_PROJECT"))
            bucket = client.bucket("c360-public-resource")
            
            # Construct prefix path: email/{property_id}/
            prefix = f"{folder}/{property_id}/"
            
            # List all blobs with the prefix
            blobs = bucket.list_blobs(prefix=prefix)
            
            files_list = []
            for blob in blobs:
                # Skip if it's a folder (ends with /)
                if blob.name.endswith('/'):
                    continue
                
                # Get file info
                file_info = {
                    "file_name": os.path.basename(blob.name),
                    "file_path": blob.name,
                    "url": blob.public_url,
                    "file_url": blob.public_url,
                    "content_type": blob.content_type,
                    "size": blob.size,
                    "created": blob.time_created.isoformat() if blob.time_created else None,
                    "updated": blob.updated.isoformat() if blob.updated else None,
                }
                files_list.append(file_info)
            
            # Sort by created time (newest first)
            files_list.sort(key=lambda x: x['created'] if x['created'] else '', reverse=True)
            
            return {
                "status": "0000",
                "data": {
                    "files": files_list,
                    "total": len(files_list)
                }
            }, 200
                
        except Exception as e:
            logging.error(f"Error listing files from GCS: {e}")
            return {'status': 'error', 'message': f'Failed to list files: {str(e)}'}, 500
    
    except Exception as e:
        logging.error(f"Email files function error: {e}")
        return {'status': 'error', 'message': str(e)}, 500