from fastapi import APIRouter, Depends, HTTPException, status, Request, UploadFile, File
from sqlalchemy.orm import Session
from typing import Optional
from datetime import datetime
from pathlib import Path
import json
import os
import aiofiles
import uuid
from ..config.database import get_db
from ..config.logging_config import get_logger
from ..middleware.auth import get_current_user, authorize_roles
from ..models.user import User
from ..models.page_content import PageContent, PageType
logger = get_logger(__name__)
router = APIRouter(prefix='/page-content', tags=['page-content'])

@router.get('/')
async def get_all_page_contents(db: Session=Depends(get_db)):
    try:
        contents = db.query(PageContent).all()
        result = []
        for content in contents:
            content_dict = {'id': content.id, 'page_type': content.page_type.value, 'title': content.title, 'subtitle': content.subtitle, 'description': content.description, 'content': content.content, 'meta_title': content.meta_title, 'meta_description': content.meta_description, 'meta_keywords': content.meta_keywords, 'og_title': content.og_title, 'og_description': content.og_description, 'og_image': content.og_image, 'canonical_url': content.canonical_url, 'contact_info': json.loads(content.contact_info) if content.contact_info else None, 'map_url': content.map_url, 'social_links': json.loads(content.social_links) if content.social_links else None, 'footer_links': json.loads(content.footer_links) if content.footer_links else None, 'badges': json.loads(content.badges) if content.badges else None, 'copyright_text': content.copyright_text, 'hero_title': content.hero_title, 'hero_subtitle': content.hero_subtitle, 'hero_image': content.hero_image, 'story_content': content.story_content, 'values': json.loads(content.values) if content.values else None, 'features': json.loads(content.features) if content.features else None, 'about_hero_image': content.about_hero_image, 'mission': content.mission, 'vision': content.vision, 'team': json.loads(content.team) if content.team else None, 'timeline': json.loads(content.timeline) if content.timeline else None, 'achievements': json.loads(content.achievements) if content.achievements else None, 'amenities_section_title': content.amenities_section_title, 'amenities_section_subtitle': content.amenities_section_subtitle, 'amenities': json.loads(content.amenities) if content.amenities else None, 'testimonials_section_title': content.testimonials_section_title, 'testimonials_section_subtitle': content.testimonials_section_subtitle, 'testimonials': json.loads(content.testimonials) if content.testimonials else None, 'gallery_section_title': content.gallery_section_title, 'gallery_section_subtitle': content.gallery_section_subtitle, 'gallery_images': json.loads(content.gallery_images) if content.gallery_images else None, 'luxury_section_title': content.luxury_section_title, 'luxury_section_subtitle': content.luxury_section_subtitle, 'luxury_section_image': content.luxury_section_image, 'luxury_features': json.loads(content.luxury_features) if content.luxury_features else None, 'luxury_gallery_section_title': content.luxury_gallery_section_title, 'luxury_gallery_section_subtitle': content.luxury_gallery_section_subtitle, 'luxury_gallery': json.loads(content.luxury_gallery) if content.luxury_gallery else None, 'luxury_testimonials_section_title': content.luxury_testimonials_section_title, 'luxury_testimonials_section_subtitle': content.luxury_testimonials_section_subtitle, 'luxury_testimonials': json.loads(content.luxury_testimonials) if content.luxury_testimonials else None, 'about_preview_title': content.about_preview_title, 'about_preview_subtitle': content.about_preview_subtitle, 'about_preview_content': content.about_preview_content, 'about_preview_image': content.about_preview_image, 'stats': json.loads(content.stats) if content.stats else None, 'luxury_services_section_title': content.luxury_services_section_title, 'luxury_services_section_subtitle': content.luxury_services_section_subtitle, 'luxury_services': json.loads(content.luxury_services) if content.luxury_services else None, 'luxury_experiences_section_title': content.luxury_experiences_section_title, 'luxury_experiences_section_subtitle': content.luxury_experiences_section_subtitle, 'luxury_experiences': json.loads(content.luxury_experiences) if content.luxury_experiences else None, 'awards_section_title': content.awards_section_title, 'awards_section_subtitle': content.awards_section_subtitle, 'awards': json.loads(content.awards) if content.awards else None, 'cta_title': content.cta_title, 'cta_subtitle': content.cta_subtitle, 'cta_button_text': content.cta_button_text, 'cta_button_link': content.cta_button_link, 'cta_image': content.cta_image, 'partners_section_title': content.partners_section_title, 'partners_section_subtitle': content.partners_section_subtitle, 'partners': json.loads(content.partners) if content.partners else None, 'is_active': content.is_active, 'created_at': content.created_at.isoformat() if content.created_at else None, 'updated_at': content.updated_at.isoformat() if content.updated_at else None}
            result.append(content_dict)
        return {'status': 'success', 'data': {'page_contents': result}}
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f'Error fetching page contents: {str(e)}')

def get_base_url(request: Request) -> str:
    return os.getenv('SERVER_URL') or f'http://{request.headers.get('host', 'localhost:8000')}'

def normalize_image_url(image_url: str, base_url: str) -> str:
    if not image_url:
        return image_url
    if image_url.startswith('http://') or image_url.startswith('https://'):
        return image_url
    if image_url.startswith('/'):
        return f'{base_url}{image_url}'
    return f'{base_url}/{image_url}'

@router.post('/upload', dependencies=[Depends(authorize_roles('admin'))])
async def upload_page_content_image(request: Request, image: UploadFile=File(...), current_user: User=Depends(authorize_roles('admin'))):
    try:
        logger.info(f'Upload request received: filename={image.filename}, content_type={image.content_type}')
        if not image:
            logger.error('No file provided in upload request')
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='No file provided')
        if not image.content_type or not image.content_type.startswith('image/'):
            logger.error(f'Invalid file type: {image.content_type}')
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f'File must be an image. Received: {image.content_type}')
        if not image.filename:
            logger.error('No filename provided in upload request')
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='Filename is required')
        upload_dir = Path(__file__).parent.parent.parent / 'uploads' / 'page-content'
        upload_dir.mkdir(parents=True, exist_ok=True)
        logger.info(f'Upload directory: {upload_dir}')
        ext = Path(image.filename).suffix or '.jpg'
        filename = f'page-content-{uuid.uuid4()}{ext}'
        file_path = upload_dir / filename
        async with aiofiles.open(file_path, 'wb') as f:
            content = await image.read()
            if not content:
                logger.error('Empty file uploaded')
                raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='File is empty')
            await f.write(content)
            logger.info(f'File saved successfully: {file_path}, size: {len(content)} bytes')
        image_url = f'/uploads/page-content/{filename}'
        base_url = get_base_url(request)
        full_url = normalize_image_url(image_url, base_url)
        logger.info(f'Upload successful: {image_url}')
        return {'success': True, 'status': 'success', 'message': 'Image uploaded successfully', 'data': {'image_url': image_url, 'full_url': full_url}}
    except HTTPException as e:
        logger.error(f'HTTPException in upload: {e.detail}')
        raise
    except Exception as e:
        logger.error(f'Unexpected error uploading image: {str(e)}', exc_info=True)
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f'Error uploading image: {str(e)}')

@router.get('/{page_type}')
async def get_page_content(page_type: PageType, db: Session=Depends(get_db)):
    try:
        content = db.query(PageContent).filter(PageContent.page_type == page_type).first()
        if not content:
            return {'status': 'success', 'data': {'page_content': None}}
        content_dict = {'id': content.id, 'page_type': content.page_type.value, 'title': content.title, 'subtitle': content.subtitle, 'description': content.description, 'content': content.content, 'meta_title': content.meta_title, 'meta_description': content.meta_description, 'meta_keywords': content.meta_keywords, 'og_title': content.og_title, 'og_description': content.og_description, 'og_image': content.og_image, 'canonical_url': content.canonical_url, 'contact_info': json.loads(content.contact_info) if content.contact_info else None, 'map_url': content.map_url, 'social_links': json.loads(content.social_links) if content.social_links else None, 'footer_links': json.loads(content.footer_links) if content.footer_links else None, 'badges': json.loads(content.badges) if content.badges else None, 'copyright_text': content.copyright_text, 'hero_title': content.hero_title, 'hero_subtitle': content.hero_subtitle, 'hero_image': content.hero_image, 'story_content': content.story_content, 'values': json.loads(content.values) if content.values else None, 'features': json.loads(content.features) if content.features else None, 'about_hero_image': content.about_hero_image, 'mission': content.mission, 'vision': content.vision, 'team': json.loads(content.team) if content.team else None, 'timeline': json.loads(content.timeline) if content.timeline else None, 'achievements': json.loads(content.achievements) if content.achievements else None, 'amenities_section_title': content.amenities_section_title, 'amenities_section_subtitle': content.amenities_section_subtitle, 'amenities': json.loads(content.amenities) if content.amenities else None, 'testimonials_section_title': content.testimonials_section_title, 'testimonials_section_subtitle': content.testimonials_section_subtitle, 'testimonials': json.loads(content.testimonials) if content.testimonials else None, 'gallery_section_title': content.gallery_section_title, 'gallery_section_subtitle': content.gallery_section_subtitle, 'gallery_images': json.loads(content.gallery_images) if content.gallery_images else None, 'luxury_section_title': content.luxury_section_title, 'luxury_section_subtitle': content.luxury_section_subtitle, 'luxury_section_image': content.luxury_section_image, 'luxury_features': json.loads(content.luxury_features) if content.luxury_features else None, 'luxury_gallery_section_title': content.luxury_gallery_section_title, 'luxury_gallery_section_subtitle': content.luxury_gallery_section_subtitle, 'luxury_gallery': json.loads(content.luxury_gallery) if content.luxury_gallery else None, 'luxury_testimonials_section_title': content.luxury_testimonials_section_title, 'luxury_testimonials_section_subtitle': content.luxury_testimonials_section_subtitle, 'luxury_testimonials': json.loads(content.luxury_testimonials) if content.luxury_testimonials else None, 'about_preview_title': content.about_preview_title, 'about_preview_subtitle': content.about_preview_subtitle, 'about_preview_content': content.about_preview_content, 'about_preview_image': content.about_preview_image, 'stats': json.loads(content.stats) if content.stats else None, 'luxury_services_section_title': content.luxury_services_section_title, 'luxury_services_section_subtitle': content.luxury_services_section_subtitle, 'luxury_services': json.loads(content.luxury_services) if content.luxury_services else None, 'luxury_experiences_section_title': content.luxury_experiences_section_title, 'luxury_experiences_section_subtitle': content.luxury_experiences_section_subtitle, 'luxury_experiences': json.loads(content.luxury_experiences) if content.luxury_experiences else None, 'awards_section_title': content.awards_section_title, 'awards_section_subtitle': content.awards_section_subtitle, 'awards': json.loads(content.awards) if content.awards else None, 'cta_title': content.cta_title, 'cta_subtitle': content.cta_subtitle, 'cta_button_text': content.cta_button_text, 'cta_button_link': content.cta_button_link, 'cta_image': content.cta_image, 'partners_section_title': content.partners_section_title, 'partners_section_subtitle': content.partners_section_subtitle, 'partners': json.loads(content.partners) if content.partners else None, 'is_active': content.is_active, 'created_at': content.created_at.isoformat() if content.created_at else None, 'updated_at': content.updated_at.isoformat() if content.updated_at else None}
        return {'status': 'success', 'data': {'page_content': content_dict}}
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f'Error fetching page content: {str(e)}')

@router.post('/{page_type}')
async def create_or_update_page_content(page_type: PageType, title: Optional[str]=None, subtitle: Optional[str]=None, description: Optional[str]=None, content: Optional[str]=None, meta_title: Optional[str]=None, meta_description: Optional[str]=None, meta_keywords: Optional[str]=None, og_title: Optional[str]=None, og_description: Optional[str]=None, og_image: Optional[str]=None, canonical_url: Optional[str]=None, contact_info: Optional[str]=None, map_url: Optional[str]=None, social_links: Optional[str]=None, footer_links: Optional[str]=None, badges: Optional[str]=None, hero_title: Optional[str]=None, hero_subtitle: Optional[str]=None, hero_image: Optional[str]=None, story_content: Optional[str]=None, values: Optional[str]=None, features: Optional[str]=None, about_hero_image: Optional[str]=None, mission: Optional[str]=None, vision: Optional[str]=None, team: Optional[str]=None, timeline: Optional[str]=None, achievements: Optional[str]=None, is_active: bool=True, current_user: User=Depends(get_current_user), db: Session=Depends(get_db)):
    try:
        authorize_roles(current_user, ['admin'])
        if contact_info:
            try:
                json.loads(contact_info)
            except json.JSONDecodeError:
                raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='Invalid JSON in contact_info')
        if social_links:
            try:
                json.loads(social_links)
            except json.JSONDecodeError:
                raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='Invalid JSON in social_links')
        if footer_links:
            try:
                json.loads(footer_links)
            except json.JSONDecodeError:
                raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='Invalid JSON in footer_links')
        if badges:
            try:
                json.loads(badges)
            except json.JSONDecodeError:
                raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='Invalid JSON in badges')
        if values:
            try:
                json.loads(values)
            except json.JSONDecodeError:
                raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='Invalid JSON in values')
        if features:
            try:
                json.loads(features)
            except json.JSONDecodeError:
                raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='Invalid JSON in features')
        existing_content = db.query(PageContent).filter(PageContent.page_type == page_type).first()
        if existing_content:
            if title is not None:
                existing_content.title = title
            if subtitle is not None:
                existing_content.subtitle = subtitle
            if description is not None:
                existing_content.description = description
            if content is not None:
                existing_content.content = content
            if meta_title is not None:
                existing_content.meta_title = meta_title
            if meta_description is not None:
                existing_content.meta_description = meta_description
            if meta_keywords is not None:
                existing_content.meta_keywords = meta_keywords
            if og_title is not None:
                existing_content.og_title = og_title
            if og_description is not None:
                existing_content.og_description = og_description
            if og_image is not None:
                existing_content.og_image = og_image
            if canonical_url is not None:
                existing_content.canonical_url = canonical_url
            if contact_info is not None:
                existing_content.contact_info = contact_info
            if map_url is not None:
                existing_content.map_url = map_url
            if social_links is not None:
                existing_content.social_links = social_links
            if footer_links is not None:
                existing_content.footer_links = footer_links
            if badges is not None:
                existing_content.badges = badges
            if hero_title is not None:
                existing_content.hero_title = hero_title
            if hero_subtitle is not None:
                existing_content.hero_subtitle = hero_subtitle
            if hero_image is not None:
                existing_content.hero_image = hero_image
            if story_content is not None:
                existing_content.story_content = story_content
            if values is not None:
                existing_content.values = values
            if features is not None:
                existing_content.features = features
            if about_hero_image is not None:
                existing_content.about_hero_image = about_hero_image
            if mission is not None:
                existing_content.mission = mission
            if vision is not None:
                existing_content.vision = vision
            if team is not None:
                existing_content.team = team
            if timeline is not None:
                existing_content.timeline = timeline
            if achievements is not None:
                existing_content.achievements = achievements
            if is_active is not None:
                existing_content.is_active = is_active
            existing_content.updated_at = datetime.utcnow()
            db.commit()
            db.refresh(existing_content)
            return {'status': 'success', 'message': 'Page content updated successfully', 'data': {'page_content': {'id': existing_content.id, 'page_type': existing_content.page_type.value, 'title': existing_content.title, 'updated_at': existing_content.updated_at.isoformat() if existing_content.updated_at else None}}}
        else:
            new_content = PageContent(page_type=page_type, title=title, subtitle=subtitle, description=description, content=content, meta_title=meta_title, meta_description=meta_description, meta_keywords=meta_keywords, og_title=og_title, og_description=og_description, og_image=og_image, canonical_url=canonical_url, contact_info=contact_info, map_url=map_url, social_links=social_links, footer_links=footer_links, badges=badges, hero_title=hero_title, hero_subtitle=hero_subtitle, hero_image=hero_image, story_content=story_content, values=values, features=features, about_hero_image=about_hero_image, mission=mission, vision=vision, team=team, timeline=timeline, achievements=achievements, is_active=is_active)
            db.add(new_content)
            db.commit()
            db.refresh(new_content)
            return {'status': 'success', 'message': 'Page content created successfully', 'data': {'page_content': {'id': new_content.id, 'page_type': new_content.page_type.value, 'title': new_content.title, 'created_at': new_content.created_at.isoformat() if new_content.created_at else None}}}
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f'Error saving page content: {str(e)}')

@router.put('/{page_type}')
async def update_page_content(page_type: PageType, page_data: dict, current_user: User=Depends(get_current_user), db: Session=Depends(get_db)):
    try:
        authorize_roles(current_user, ['admin'])
        existing_content = db.query(PageContent).filter(PageContent.page_type == page_type).first()
        if not existing_content:
            existing_content = PageContent(page_type=page_type, is_active=True)
            db.add(existing_content)
        for key, value in page_data.items():
            if hasattr(existing_content, key):
                if key in ['contact_info', 'social_links', 'footer_links', 'badges', 'values', 'features', 'amenities', 'testimonials', 'gallery_images', 'stats', 'luxury_features', 'luxury_gallery', 'luxury_testimonials', 'luxury_services', 'luxury_experiences', 'awards', 'partners', 'team', 'timeline', 'achievements'] and value is not None:
                    if isinstance(value, str):
                        try:
                            json.loads(value)
                        except json.JSONDecodeError:
                            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f'Invalid JSON in {key}')
                    elif isinstance(value, (dict, list)):
                        value = json.dumps(value)
                if value is not None:
                    setattr(existing_content, key, value)
        existing_content.updated_at = datetime.utcnow()
        db.commit()
        db.refresh(existing_content)
        content_dict = {'id': existing_content.id, 'page_type': existing_content.page_type.value, 'title': existing_content.title, 'subtitle': existing_content.subtitle, 'description': existing_content.description, 'content': existing_content.content, 'meta_title': existing_content.meta_title, 'meta_description': existing_content.meta_description, 'meta_keywords': existing_content.meta_keywords, 'og_title': existing_content.og_title, 'og_description': existing_content.og_description, 'og_image': existing_content.og_image, 'canonical_url': existing_content.canonical_url, 'contact_info': json.loads(existing_content.contact_info) if existing_content.contact_info else None, 'map_url': existing_content.map_url, 'social_links': json.loads(existing_content.social_links) if existing_content.social_links else None, 'footer_links': json.loads(existing_content.footer_links) if existing_content.footer_links else None, 'badges': json.loads(existing_content.badges) if existing_content.badges else None, 'copyright_text': existing_content.copyright_text, 'hero_title': existing_content.hero_title, 'hero_subtitle': existing_content.hero_subtitle, 'hero_image': existing_content.hero_image, 'story_content': existing_content.story_content, 'values': json.loads(existing_content.values) if existing_content.values else None, 'features': json.loads(existing_content.features) if existing_content.features else None, 'about_hero_image': existing_content.about_hero_image, 'mission': existing_content.mission, 'vision': existing_content.vision, 'team': json.loads(existing_content.team) if existing_content.team else None, 'timeline': json.loads(existing_content.timeline) if existing_content.timeline else None, 'achievements': json.loads(existing_content.achievements) if existing_content.achievements else None, 'amenities_section_title': existing_content.amenities_section_title, 'amenities_section_subtitle': existing_content.amenities_section_subtitle, 'amenities': json.loads(existing_content.amenities) if existing_content.amenities else None, 'testimonials_section_title': existing_content.testimonials_section_title, 'testimonials_section_subtitle': existing_content.testimonials_section_subtitle, 'testimonials': json.loads(existing_content.testimonials) if existing_content.testimonials else None, 'gallery_section_title': existing_content.gallery_section_title, 'gallery_section_subtitle': existing_content.gallery_section_subtitle, 'gallery_images': json.loads(existing_content.gallery_images) if existing_content.gallery_images else None, 'luxury_section_title': existing_content.luxury_section_title, 'luxury_section_subtitle': existing_content.luxury_section_subtitle, 'luxury_section_image': existing_content.luxury_section_image, 'luxury_features': json.loads(existing_content.luxury_features) if existing_content.luxury_features else None, 'luxury_gallery_section_title': existing_content.luxury_gallery_section_title, 'luxury_gallery_section_subtitle': existing_content.luxury_gallery_section_subtitle, 'luxury_gallery': json.loads(existing_content.luxury_gallery) if existing_content.luxury_gallery else None, 'luxury_testimonials_section_title': existing_content.luxury_testimonials_section_title, 'luxury_testimonials_section_subtitle': existing_content.luxury_testimonials_section_subtitle, 'luxury_testimonials': json.loads(existing_content.luxury_testimonials) if existing_content.luxury_testimonials else None, 'about_preview_title': existing_content.about_preview_title, 'about_preview_subtitle': existing_content.about_preview_subtitle, 'about_preview_content': existing_content.about_preview_content, 'about_preview_image': existing_content.about_preview_image, 'stats': json.loads(existing_content.stats) if existing_content.stats else None, 'luxury_services_section_title': existing_content.luxury_services_section_title, 'luxury_services_section_subtitle': existing_content.luxury_services_section_subtitle, 'luxury_services': json.loads(existing_content.luxury_services) if existing_content.luxury_services else None, 'luxury_experiences_section_title': existing_content.luxury_experiences_section_title, 'luxury_experiences_section_subtitle': existing_content.luxury_experiences_section_subtitle, 'luxury_experiences': json.loads(existing_content.luxury_experiences) if existing_content.luxury_experiences else None, 'awards_section_title': existing_content.awards_section_title, 'awards_section_subtitle': existing_content.awards_section_subtitle, 'awards': json.loads(existing_content.awards) if existing_content.awards else None, 'cta_title': existing_content.cta_title, 'cta_subtitle': existing_content.cta_subtitle, 'cta_button_text': existing_content.cta_button_text, 'cta_button_link': existing_content.cta_button_link, 'cta_image': existing_content.cta_image, 'partners_section_title': existing_content.partners_section_title, 'partners_section_subtitle': existing_content.partners_section_subtitle, 'partners': json.loads(existing_content.partners) if existing_content.partners else None, 'is_active': existing_content.is_active, 'updated_at': existing_content.updated_at.isoformat() if existing_content.updated_at else None}
        return {'status': 'success', 'message': 'Page content updated successfully', 'data': {'page_content': content_dict}}
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f'Error updating page content: {str(e)}')