import requests
import json
import logging
from datetime import datetime
from django.utils import timezone
from .models import CrawledDevelopment, CrawledFlat, CrawledAttachment, SyncLog

logger = logging.getLogger(__name__)

class SyncService:
    @staticmethod
    def get_api_config():
        """تنظیمات API را از فایل تنظیمات یا دیتابیس بخوان"""
        # این مقادیر را از تنظیمات پروژه یا دیتابیس بخوانید
        return {
            'api_url': 'https://your-main-server.com/api/sync/',
            'api_key': 'your-api-key-here',
        }
    
    @staticmethod
    def prepare_development_data(development):
        """آماده‌سازی داده‌های ساختمان برای ارسال"""
        return {
            'external_id': development.external_id,
            'reference_id': development.reference_id,
            'title': development.title,
            'address': development.address,
            'base_price': development.base_price,
            'latitude': development.latitude,
            'longitude': development.longitude,
            'country_code': development.country_code,
            'city_name': development.city_name,
            'is_active': development.is_active,
            'is_sold_out': development.is_sold_out,
            'completed_status': development.completed_status,
            'completed_date': development.completed_date,
            # سایر فیلدهای مورد نیاز
        }
    
    @staticmethod
    def prepare_flat_data(flat):
        """آماده‌سازی داده‌های واحد برای ارسال"""
        return {
            'external_id': flat.external_id,
            'development_external_id': flat.development.external_id,
            'bedrooms_num': flat.bedrooms_num,
            'bathrooms_num': flat.bathrooms_num,
            'area': flat.area,
            'base_price': flat.base_price,
            'price_per_meter': flat.price_per_meter,
            'is_sold_out': flat.is_sold_out,
        }
    
    @staticmethod
    def prepare_attachment_data(attachment):
        """آماده‌سازی داده‌های پیوست برای ارسال"""
        return {
            'external_id': attachment.external_id,
            'development_external_id': attachment.development.external_id,
            'file_url': attachment.file_url,
            'file_type': attachment.file_type,
            'category': attachment.category,
            'title': attachment.title,
        }
    
    @staticmethod
    def sync_development(development_id):
        """سینک‌سازی یک ساختمان"""
        try:
            development = CrawledDevelopment.objects.get(id=development_id)
            
            # آماده‌سازی داده
            data = SyncService.prepare_development_data(development)
            
            # تعیین نوع سینک
            sync_type = 1 if development.is_synced else 0  # 0=Create, 1=Update
            
            # ارسال به API
            config = SyncService.get_api_config()
            response = requests.post(
                f"{config['api_url']}developments/",
                json={
                    'sync_type': sync_type,
                    'model_name': 'Development',
                    'data': data,
                },
                headers={
                    'Authorization': f"Bearer {config['api_key']}",
                    'Content-Type': 'application/json',
                }
            )
            
            # ثبت نتیجه
            if response.status_code in [200, 201]:
                development.is_synced = True
                development.last_sync_at = timezone.now()
                development.sync_status = 1  # Pending
                development.save()
                
                SyncLog.objects.create(
                    development=development,
                    sync_type=sync_type,
                    status=0,  # Pending
                    response_data=response.json(),
                )
                
                return {
                    'success': True,
                    'message': 'Development sync request sent successfully',
                    'data': response.json()
                }
            else:
                development.sync_status = 3  # Failed
                development.sync_message = f"API Error: {response.text}"
                development.save()
                
                SyncLog.objects.create(
                    development=development,
                    sync_type=sync_type,
                    status=2,  # Failed
                    message=f"API Error: {response.text}",
                )
                
                return {
                    'success': False,
                    'message': f"API Error: {response.text}"
                }
                
        except CrawledDevelopment.DoesNotExist:
            return {
                'success': False,
                'message': f"Development with ID {development_id} not found"
            }
        except Exception as e:
            logger.error(f"Error syncing development {development_id}: {str(e)}")
            return {
                'success': False,
                'message': str(e)
            }
    
    @staticmethod
    def sync_flat(flat_id):
        """سینک‌سازی یک واحد"""
        # مشابه با sync_development پیاده‌سازی شود
        pass
    
    @staticmethod
    def sync_attachment(attachment_id):
        """سینک‌سازی یک پیوست"""
        # مشابه با sync_development پیاده‌سازی شود
        pass
    
    @staticmethod
    def check_sync_status(sync_log_id):
        """بررسی وضعیت یک درخواست سینک"""
        try:
            sync_log = SyncLog.objects.get(id=sync_log_id)
            
            # اگر وضعیت در حال انتظار است، از سرور اصلی بررسی کنید
            if sync_log.status == 0:  # Pending
                config = SyncService.get_api_config()
                
                # فرض کنید API برای بررسی وضعیت سینک وجود دارد
                response = requests.get(
                    f"{config['api_url']}sync-status/{sync_log.response_data.get('sync_request_id')}/",
                    headers={'Authorization': f"Bearer {config['api_key']}"}
                )
                
                if response.status_code == 200:
                    status_data = response.json()
                    
                    # به‌روزرسانی وضعیت در سیستم محلی
                    if status_data.get('status') == 'approved':
                        sync_log.status = 1  # Success
                        
                        # به‌روزرسانی وضعیت آیتم سینک شده
                        if sync_log.development:
                            sync_log.development.sync_status = 2  # Synced
                            sync_log.development.save()
                        elif sync_log.flat:
                            sync_log.flat.sync_status = 2  # Synced
                            sync_log.flat.save()
                        elif sync_log.attachment:
                            sync_log.attachment.sync_status = 2  # Synced
                            sync_log.attachment.save()
                            
                    elif status_data.get('status') == 'rejected':
                        sync_log.status = 3  # Rejected
                        sync_log.message = status_data.get('reason', 'Rejected by admin')
                        
                        # به‌روزرسانی وضعیت آیتم سینک شده
                        if sync_log.development:
                            sync_log.development.sync_status = 4  # Rejected
                            sync_log.development.sync_message = status_data.get('reason', 'Rejected by admin')
                            sync_log.development.save()
                        elif sync_log.flat:
                            sync_log.flat.sync_status = 4  # Rejected
                            sync_log.flat.save()
                        elif sync_log.attachment:
                            sync_log.attachment.sync_status = 4  # Rejected
                            sync_log.attachment.save()
                    
                    sync_log.save()
                    
                    return {
                        'success': True,
                        'status': status_data.get('status'),
                        'message': status_data.get('reason', '')
                    }
            
            # اگر وضعیت قبلاً مشخص شده است
            return {
                'success': True,
                'status': sync_log.get_status_display(),
                'message': sync_log.message
            }
            
        except SyncLog.DoesNotExist:
            return {
                'success': False,
                'message': f"Sync log with ID {sync_log_id} not found"
            }
        except Exception as e:
            logger.error(f"Error checking sync status for log {sync_log_id}: {str(e)}")
            return {
                'success': False,
                'message': str(e)
            }