from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.views import View
import json
import logging

from noticeapp.models import NoticeUser, Listing as NoticeListing
from .services import WordPressIntegrationService

logger = logging.getLogger(__name__)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_wp_listing(request):
    """
    Create a new listing in WordPress database
    Expected payload:
    {
        "title": "Listing Title",
        "description": "Full description",
        "tagline": "Short tagline",
        "phone": "+1234567890",
        "email": "contact@example.com",
        "website": "https://example.com",
        "address": "123 Main St, City, State",
        "lat": "40.7128",
        "lng": "-74.0060",
        "price_range": "$$",
        "minimum_price": "10",
        "maximum_price": "50",
        "social_networks": {
            "facebook": "https://facebook.com/page",
            "twitter": "https://twitter.com/page"
        },
        "gallery": [
            {"src": "image_url", "id": "attachment_id"}
        ],
        "videos": [
            {"src": "video_url", "name": "Video Title"}
        ],
        "categories": [1, 2],
        "tags": [3, 4],
        "post_type": "listing",
        "plan_id": 1
    }
    """
    try:
        # Get the NoticeUser from the authenticated user
        try:
            notice_user = NoticeUser.objects.get(email=request.user.email)
        except NoticeUser.DoesNotExist:
            return Response({
                'success': False,
                'error': 'NoticeUser not found',
                'message': 'User not found in NoticeApp database'
            }, status=status.HTTP_404_NOT_FOUND)
        
        # Validate required fields
        required_fields = ['title', 'description']
        for field in required_fields:
            if not request.data.get(field):
                return Response({
                    'success': False,
                    'error': f'Missing required field: {field}',
                    'message': f'{field} is required'
                }, status=status.HTTP_400_BAD_REQUEST)
        
        # Prepare listing data
        listing_data = {
            'title': request.data.get('title'),
            'description': request.data.get('description'),
            'tagline': request.data.get('tagline', ''),
            'phone': request.data.get('phone', ''),
            'email': request.data.get('email', ''),
            'website': request.data.get('website', ''),
            'address': request.data.get('address', ''),
            'lat': request.data.get('lat', ''),
            'lng': request.data.get('lng', ''),
            'price_range': request.data.get('price_range', ''),
            'price_range_desc': request.data.get('price_range_desc', ''),
            'minimum_price': request.data.get('minimum_price', ''),
            'maximum_price': request.data.get('maximum_price', ''),
            'social_networks': request.data.get('social_networks', {}),
            'gallery': request.data.get('gallery', []),
            'videos': request.data.get('videos', []),
            'categories': request.data.get('categories', []),
            'tags': request.data.get('tags', []),
            'post_type': request.data.get('post_type', 'listing'),
            'plan_id': request.data.get('plan_id', 1),
            'cover_image': request.data.get('cover_image', ''),
            'cover_image_id': request.data.get('cover_image_id', ''),
            'logo': request.data.get('logo', ''),
            'logo_id': request.data.get('logo_id', ''),
            'custom_sections': request.data.get('custom_sections', {}),
            'business_hours': request.data.get('business_hours', {})
        }
        
        # Create WordPress listing
        wp_service = WordPressIntegrationService()
        result = wp_service.create_listing_from_noticeapp(notice_user, listing_data)
        
        if result['success']:
            # Create or update NoticeListing record
            notice_listing, created = NoticeListing.objects.get_or_create(
                wp_listing_id=result['wp_listing_id'],
                defaults={
                    'title': listing_data['title'],
                    'post_type': listing_data['post_type'],
                    'location': listing_data['address'],
                    'tagline': listing_data['tagline'],
                    'description_html': listing_data['description'],
                    'description_text': listing_data['description'],
                    'phone': listing_data['phone'],
                    'website': listing_data['website'],
                    'socials_json': listing_data['social_networks'],
                    'gallery_json': listing_data['gallery']
                }
            )
            
            if not created:
                # Update existing record
                notice_listing.title = listing_data['title']
                notice_listing.post_type = listing_data['post_type']
                notice_listing.location = listing_data['address']
                notice_listing.tagline = listing_data['tagline']
                notice_listing.description_html = listing_data['description']
                notice_listing.description_text = listing_data['description']
                notice_listing.phone = listing_data['phone']
                notice_listing.website = listing_data['website']
                notice_listing.socials_json = listing_data['social_networks']
                notice_listing.gallery_json = listing_data['gallery']
                notice_listing.save()
            
            return Response({
                'success': True,
                'wp_listing_id': result['wp_listing_id'],
                'wp_user_id': result['wp_user_id'],
                'notice_listing_id': notice_listing.id,
                'message': 'Listing created successfully',
                'data': {
                    'title': listing_data['title'],
                    'post_type': listing_data['post_type'],
                    'status': 'publish'
                }
            }, status=status.HTTP_201_CREATED)
        else:
            return Response({
                'success': False,
                'error': result['error'],
                'message': result['message']
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            
    except Exception as e:
        logger.error(f"Error creating WordPress listing: {str(e)}")
        return Response({
            'success': False,
            'error': str(e),
            'message': 'Internal server error'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['PUT'])
@permission_classes([IsAuthenticated])
def update_wp_listing(request, wp_listing_id):
    """
    Update an existing WordPress listing
    """
    try:
        # Validate wp_listing_id
        if not wp_listing_id:
            return Response({
                'success': False,
                'error': 'Missing wp_listing_id',
                'message': 'WordPress listing ID is required'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # Prepare listing data
        listing_data = {
            'title': request.data.get('title'),
            'description': request.data.get('description'),
            'tagline': request.data.get('tagline', ''),
            'phone': request.data.get('phone', ''),
            'email': request.data.get('email', ''),
            'website': request.data.get('website', ''),
            'address': request.data.get('address', ''),
            'lat': request.data.get('lat', ''),
            'lng': request.data.get('lng', ''),
            'price_range': request.data.get('price_range', ''),
            'minimum_price': request.data.get('minimum_price', ''),
            'maximum_price': request.data.get('maximum_price', ''),
            'social_networks': request.data.get('social_networks', {}),
            'gallery': request.data.get('gallery', []),
            'videos': request.data.get('videos', []),
            'categories': request.data.get('categories', []),
            'tags': request.data.get('tags', [])
        }
        
        # Update WordPress listing
        wp_service = WordPressIntegrationService()
        result = wp_service.update_listing_from_noticeapp(wp_listing_id, listing_data)
        
        if result['success']:
            # Update NoticeListing record
            try:
                notice_listing = NoticeListing.objects.get(wp_listing_id=wp_listing_id)
                notice_listing.title = listing_data.get('title', notice_listing.title)
                notice_listing.location = listing_data.get('address', notice_listing.location)
                notice_listing.tagline = listing_data.get('tagline', notice_listing.tagline)
                notice_listing.description_html = listing_data.get('description', notice_listing.description_html)
                notice_listing.description_text = listing_data.get('description', notice_listing.description_text)
                notice_listing.phone = listing_data.get('phone', notice_listing.phone)
                notice_listing.website = listing_data.get('website', notice_listing.website)
                notice_listing.socials_json = listing_data.get('social_networks', notice_listing.socials_json)
                notice_listing.gallery_json = listing_data.get('gallery', notice_listing.gallery_json)
                notice_listing.save()
            except NoticeListing.DoesNotExist:
                pass  # WordPress listing exists but not in NoticeApp
            
            return Response({
                'success': True,
                'wp_listing_id': wp_listing_id,
                'message': 'Listing updated successfully'
            }, status=status.HTTP_200_OK)
        else:
            return Response({
                'success': False,
                'error': result['error'],
                'message': result['message']
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            
    except Exception as e:
        logger.error(f"Error updating WordPress listing: {str(e)}")
        return Response({
            'success': False,
            'error': str(e),
            'message': 'Internal server error'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_categories(request):
    """
    Get all available categories for listings
    """
    try:
        wp_service = WordPressIntegrationService()
        categories = wp_service.taxonomy_manager.get_categories()
        
        return Response({
            'success': True,
            'categories': categories
        }, status=status.HTTP_200_OK)
        
    except Exception as e:
        logger.error(f"Error getting categories: {str(e)}")
        return Response({
            'success': False,
            'error': str(e),
            'message': 'Failed to get categories'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_tags(request):
    """
    Get all available tags for listings
    """
    try:
        wp_service = WordPressIntegrationService()
        tags = wp_service.taxonomy_manager.get_tags()
        
        return Response({
            'success': True,
            'tags': tags
        }, status=status.HTTP_200_OK)
        
    except Exception as e:
        logger.error(f"Error getting tags: {str(e)}")
        return Response({
            'success': False,
            'error': str(e),
            'message': 'Failed to get tags'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_category(request):
    """
    Create a new category
    """
    try:
        name = request.data.get('name')
        if not name:
            return Response({
                'success': False,
                'error': 'Category name is required',
                'message': 'Name field is required'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        wp_service = WordPressIntegrationService()
        category_id = wp_service.taxonomy_manager.create_category(
            name=name,
            slug=request.data.get('slug'),
            description=request.data.get('description', '')
        )
        
        return Response({
            'success': True,
            'category_id': category_id,
            'message': 'Category created successfully'
        }, status=status.HTTP_201_CREATED)
        
    except Exception as e:
        logger.error(f"Error creating category: {str(e)}")
        return Response({
            'success': False,
            'error': str(e),
            'message': 'Failed to create category'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_tag(request):
    """
    Create a new tag
    """
    try:
        name = request.data.get('name')
        if not name:
            return Response({
                'success': False,
                'error': 'Tag name is required',
                'message': 'Name field is required'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        wp_service = WordPressIntegrationService()
        tag_id = wp_service.taxonomy_manager.create_tag(
            name=name,
            slug=request.data.get('slug'),
            description=request.data.get('description', '')
        )
        
        return Response({
            'success': True,
            'tag_id': tag_id,
            'message': 'Tag created successfully'
        }, status=status.HTTP_201_CREATED)
        
    except Exception as e:
        logger.error(f"Error creating tag: {str(e)}")
        return Response({
            'success': False,
            'error': str(e),
            'message': 'Failed to create tag'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def sync_user_to_wordpress(request):
    """
    Sync current NoticeApp user to WordPress
    """
    try:
        # Get the NoticeUser from the authenticated user
        try:
            notice_user = NoticeUser.objects.get(email=request.user.email)
        except NoticeUser.DoesNotExist:
            return Response({
                'success': False,
                'error': 'NoticeUser not found',
                'message': 'User not found in NoticeApp database'
            }, status=status.HTTP_404_NOT_FOUND)
        
        wp_service = WordPressIntegrationService()
        wp_user_id = wp_service.user_manager.get_or_create_wp_user(notice_user)
        
        return Response({
            'success': True,
            'wp_user_id': wp_user_id,
            'notice_user_id': notice_user.id,
            'message': 'User synced to WordPress successfully'
        }, status=status.HTTP_200_OK)
        
    except Exception as e:
        logger.error(f"Error syncing user: {str(e)}")
        return Response({
            'success': False,
            'error': str(e),
            'message': 'Failed to sync user to WordPress'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_wp_listing(request, wp_listing_id):
    """
    Get WordPress listing data
    """
    try:
        wp_service = WordPressIntegrationService()
        listing_data = wp_service.get_listing_from_wordpress(wp_listing_id)
        
        if listing_data:
            return Response({
                'success': True,
                'data': listing_data
            }, status=status.HTTP_200_OK)
        else:
            return Response({
                'success': False,
                'error': 'Listing not found',
                'message': 'WordPress listing not found'
            }, status=status.HTTP_404_NOT_FOUND)
            
    except Exception as e:
        logger.error(f"Error getting WordPress listing: {str(e)}")
        return Response({
            'success': False,
            'error': str(e),
            'message': 'Internal server error'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def sync_noticeapp_to_wordpress(request):
    """
    Sync existing NoticeApp listings to WordPress
    """
    try:
        wp_service = WordPressIntegrationService()
        synced_count = 0
        errors = []
        
        # Get all NoticeListings that don't have wp_listing_id
        notice_listings = NoticeListing.objects.filter(wp_listing_id__isnull=True)
        
        for notice_listing in notice_listings:
            try:
                # Get the user who created this listing (if available)
                # For now, we'll use the first NoticeUser or create a default one
                try:
                    notice_user = NoticeUser.objects.first()
                    if not notice_user:
                        # Create a default user if none exists
                        notice_user = NoticeUser.objects.create(
                            email='admin@noticeboard.co.zw',
                            password_hash='default_hash',
                            display_name='Admin User'
                        )
                except:
                    continue
                
                # Prepare listing data
                listing_data = {
                    'title': notice_listing.title or 'Untitled Listing',
                    'description': notice_listing.description_html or notice_listing.description_text or '',
                    'tagline': notice_listing.tagline or '',
                    'phone': notice_listing.phone or '',
                    'website': notice_listing.website or '',
                    'address': notice_listing.location or '',
                    'social_networks': notice_listing.socials_json or {},
                    'gallery': notice_listing.gallery_json or [],
                    'post_type': notice_listing.post_type or 'listing',
                    'plan_id': 1
                }
                
                # Create WordPress listing
                result = wp_service.create_listing_from_noticeapp(notice_user, listing_data)
                
                if result['success']:
                    # Update NoticeListing with wp_listing_id
                    notice_listing.wp_listing_id = result['wp_listing_id']
                    notice_listing.save()
                    synced_count += 1
                else:
                    errors.append(f"Failed to sync listing {notice_listing.id}: {result['error']}")
                    
            except Exception as e:
                errors.append(f"Error syncing listing {notice_listing.id}: {str(e)}")
        
        return Response({
            'success': True,
            'synced_count': synced_count,
            'total_processed': notice_listings.count(),
            'errors': errors,
            'message': f'Successfully synced {synced_count} listings to WordPress'
        }, status=status.HTTP_200_OK)
        
    except Exception as e:
        logger.error(f"Error syncing to WordPress: {str(e)}")
        return Response({
            'success': False,
            'error': str(e),
            'message': 'Internal server error'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# Non-authenticated endpoints for external API access
@method_decorator(csrf_exempt, name='dispatch')
class ExternalWordPressAPI(View):
    """
    External API endpoints for WordPress integration
    These endpoints can be called from external systems
    """
    
    def post(self, request):
        """
        Create listing via external API
        Expected headers: X-API-Key
        """
        try:
            # Simple API key authentication
            api_key = request.headers.get('X-API-Key')
            if api_key != 'your-secret-api-key':  # Change this to your actual API key
                return JsonResponse({
                    'success': False,
                    'error': 'Invalid API key',
                    'message': 'Unauthorized access'
                }, status=401)
            
            data = json.loads(request.body)
            
            # Get or create NoticeUser
            email = data.get('email', 'external@noticeboard.co.zw')
            display_name = data.get('display_name', 'External User')
            
            notice_user, created = NoticeUser.objects.get_or_create(
                email=email,
                defaults={
                    'password_hash': 'external_user_hash',
                    'display_name': display_name
                }
            )
            
            # Prepare listing data
            listing_data = {
                'title': data.get('title', ''),
                'description': data.get('description', ''),
                'tagline': data.get('tagline', ''),
                'phone': data.get('phone', ''),
                'email': data.get('email', ''),
                'website': data.get('website', ''),
                'address': data.get('address', ''),
                'lat': data.get('lat', ''),
                'lng': data.get('lng', ''),
                'price_range': data.get('price_range', ''),
                'minimum_price': data.get('minimum_price', ''),
                'maximum_price': data.get('maximum_price', ''),
                'social_networks': data.get('social_networks', {}),
                'gallery': data.get('gallery', []),
                'videos': data.get('videos', []),
                'categories': data.get('categories', []),
                'tags': data.get('tags', []),
                'post_type': data.get('post_type', 'listing'),
                'plan_id': data.get('plan_id', 1)
            }
            
            # Create WordPress listing
            wp_service = WordPressIntegrationService()
            result = wp_service.create_listing_from_noticeapp(notice_user, listing_data)
            
            if result['success']:
                # Create NoticeListing record
                notice_listing = NoticeListing.objects.create(
                    wp_listing_id=result['wp_listing_id'],
                    title=listing_data['title'],
                    post_type=listing_data['post_type'],
                    location=listing_data['address'],
                    tagline=listing_data['tagline'],
                    description_html=listing_data['description'],
                    description_text=listing_data['description'],
                    phone=listing_data['phone'],
                    website=listing_data['website'],
                    socials_json=listing_data['social_networks'],
                    gallery_json=listing_data['gallery']
                )
                
                return JsonResponse({
                    'success': True,
                    'wp_listing_id': result['wp_listing_id'],
                    'wp_user_id': result['wp_user_id'],
                    'notice_listing_id': notice_listing.id,
                    'message': 'Listing created successfully via external API'
                }, status=201)
            else:
                return JsonResponse({
                    'success': False,
                    'error': result['error'],
                    'message': result['message']
                }, status=500)
                
        except Exception as e:
            logger.error(f"Error in external WordPress API: {str(e)}")
            return JsonResponse({
                'success': False,
                'error': str(e),
                'message': 'Internal server error'
            }, status=500)
