import json
import logging
from django.views.generic import TemplateView
from django.http import JsonResponse
from django.views.decorators.http import require_POST, require_GET

logger = logging.getLogger(__name__)

from user_roles.mixins import OwnerRequiredMixin
from .models import RecommerceIntegration, WooCommerceIntegration, GLMIntegration, OpenRouterIntegration
from integrations.recommerce.tasks import sync_products_batch_task


# Реестр доступных интеграций
# Ключ = идентификатор для URL/JS, значение = (модель, название для UI)
INTEGRATION_REGISTRY = {
    'recommerce': (RecommerceIntegration, 'Recommerce', 'Маркетплейс'),
    'woocommerce': (WooCommerceIntegration, 'WooCommerce', 'Маркетплейс'),
    'glm': (GLMIntegration, 'GLM от Z.AI', 'Сервис ИИ'),
    'openrouter': (OpenRouterIntegration, 'OpenRouter.ai', 'Сервис ИИ'),
    # Добавлять новые интеграции здесь:
    # 'shopify': (ShopifyIntegration, 'Shopify', 'Маркетплейс'),
}


def get_integration_model(integration_id: str):
    """Получить модель интеграции по идентификатору"""
    if integration_id not in INTEGRATION_REGISTRY:
        return None
    return INTEGRATION_REGISTRY[integration_id][0]


def get_all_integrations_status():
    """
    Получить статус всех интеграций.
    Возвращает dict с информацией для UI.
    """
    result = {}
    for key, (model, label, category) in INTEGRATION_REGISTRY.items():
        instance = model.objects.first()
        result[key] = {
            'id': key,
            'label': label,
            'category': category,
            'is_active': instance.is_active if instance else False,
            'is_configured': instance.is_configured if instance else False,
            'exists': instance is not None,
        }
    return result


class IntegrationsListView(OwnerRequiredMixin, TemplateView):
    """Страница настроек интеграций (доступна только владельцу)"""
    template_name = "system_settings/integrations.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        integrations = get_all_integrations_status()
        context['integrations'] = integrations
        # JSON для JavaScript
        context['integrations_json'] = json.dumps(integrations, ensure_ascii=False)
        return context


@require_POST
def toggle_integration(request, integration_id: str):
    """
    API endpoint для включения/выключения интеграции.
    POST /integrations/toggle/<integration_id>/

    Создаёт запись если не существует (singleton).
    Переключает is_active.
    """
    # Проверка прав (только владелец)
    if not hasattr(request, 'user') or not request.user.is_authenticated:
        return JsonResponse({'error': 'Unauthorized'}, status=401)

    # Получить модель
    model = get_integration_model(integration_id)
    if not model:
        return JsonResponse({'error': f'Unknown integration: {integration_id}'}, status=404)

    # Получить или создать singleton
    instance, created = model.objects.get_or_create(
        defaults={
            'name': INTEGRATION_REGISTRY[integration_id][1],
            'is_active': False,
        }
    )

    # Переключить состояние
    new_state = not instance.is_active

    # Проверка: нельзя включить ненастроенную интеграцию
    if new_state and not instance.is_configured:
        return JsonResponse({
            'error': 'Сначала настройте интеграцию (введите credentials)',
            'is_active': instance.is_active,
            'is_configured': False,
        }, status=400)

    instance.is_active = new_state
    instance.save(update_fields=['is_active', 'updated_at'])

    return JsonResponse({
        'success': True,
        'is_active': instance.is_active,
        'is_configured': instance.is_configured,
    })


@require_POST
def test_integration_connection(request, integration_id: str):
    """
    Тестировать соединение с интеграцией.
    POST /integrations/test/<integration_id>/
    """
    import logging
    logger = logging.getLogger(__name__)
    
    logger.info(f"=== Начало тестирования интеграции: {integration_id} ===")
    
    if not hasattr(request, 'user') or not request.user.is_authenticated:
        logger.error("Пользователь не авторизован")
        return JsonResponse({'error': 'Unauthorized'}, status=401)

    model = get_integration_model(integration_id)
    if not model:
        logger.error(f"Неизвестная интеграция: {integration_id}")
        return JsonResponse({'error': f'Unknown integration: {integration_id}'}, status=404)

    instance = model.objects.first()
    if not instance:
        logger.error(f"Интеграция {integration_id} не настроена (нет записи в БД)")
        return JsonResponse({'error': 'Интеграция не настроена'}, status=400)

    logger.info(f"Найдена интеграция: {instance.name}, is_active={instance.is_active}, is_configured={instance.is_configured}")
    
    if not instance.is_configured:
        logger.error(f"Интеграция {integration_id} не сконфигурирована")
        return JsonResponse({'error': 'Заполните настройки интеграции'}, status=400)

    # Получить сервис для интеграции
    try:
        logger.info(f"Попытка получить сервис для {integration_id}...")
        service = get_integration_service(integration_id, instance)
        if not service:
            logger.error(f"Сервис для {integration_id} не реализован")
            return JsonResponse({'error': 'Сервис не реализован'}, status=501)
        logger.info(f"Сервис успешно создан: {service.__class__.__name__}")
    except Exception as e:
        logger.error(f"Ошибка при создании сервиса для {integration_id}: {str(e)}", exc_info=True)
        return JsonResponse({'error': f'Ошибка при создании сервиса: {str(e)}'}, status=500)

    # Выполнить тест
    try:
        logger.info(f"Выполнение теста соединения...")
        success, message = service.test_connection()
        logger.info(f"Результат теста: success={success}, message={message}")
    except Exception as e:
        logger.error(f"Ошибка при выполнении теста соединения: {str(e)}", exc_info=True)
        return JsonResponse({'error': f'Ошибка при тестировании: {str(e)}'}, status=500)

    return JsonResponse({
        'success': success,
        'message': message,
    })


def get_integration_service(integration_id: str, instance):
    """Получить сервис для интеграции"""
    if integration_id == 'recommerce':
        from .services.marketplaces.recommerce import RecommerceService
        return RecommerceService(instance)
    elif integration_id == 'woocommerce':
        from .services.marketplaces.woocommerce import WooCommerceService
        return WooCommerceService(instance)
    elif integration_id == 'glm':
        from .services.ai_services.glm_service import GLMIntegrationService
        return GLMIntegrationService(instance)
    elif integration_id == 'openrouter':
        from .services.ai_services.openrouter_service import OpenRouterIntegrationService
        return OpenRouterIntegrationService(instance)
    return None


@require_GET
def get_openrouter_models(request):
    """
    GET /settings/integrations/openrouter/models/
    Возвращает список моделей OpenRouter (бесплатные сверху)
    """
    import requests

    try:
        response = requests.get('https://openrouter.ai/api/v1/models', timeout=10)
        response.raise_for_status()
        data = response.json()

        models = data.get('data', [])

        # Разделить на бесплатные и платные
        free_models = []
        paid_models = []

        for model in models:
            model_id = model.get('id', '')
            model_name = model.get('name', model_id)

            if ':free' in model_id:
                free_models.append({'id': model_id, 'name': f"{model_name} (Бесплатная)"})
            else:
                paid_models.append({'id': model_id, 'name': model_name})

        # Бесплатные сверху
        all_models = free_models + paid_models

        return JsonResponse({'models': all_models})

    except Exception as e:
        logger.error(f"Error fetching OpenRouter models: {e}")
        return JsonResponse({'error': str(e)}, status=500)


class RecommerceBatchSyncView(TemplateView):
    """
    API View для запуска массовой синхронизации с Recommerce.
    POST /integrations/recommerce/sync/
    """
    def dispatch(self, request, *args, **kwargs):
        # Временное логирование для отладки
        from user_roles.services import RoleService
        import logging
        logger = logging.getLogger(__name__)
        logger.info(f"User: {request.user}, Authenticated: {request.user.is_authenticated}")
        user_role = RoleService.get_user_role(request.user)
        logger.info(f"User role: {user_role}")
        return super().dispatch(request, *args, **kwargs)
    def post(self, request, *args, **kwargs):
        try:
            data = json.loads(request.body)
            product_ids = data.get('product_ids', [])
            options = data.get('options', {})

            if not product_ids:
                return JsonResponse({'error': 'No products selected'}, status=400)

            # Запуск Celery задачи с передачей schema_name
            from django_tenants.utils import get_tenant_model
            Tenant = get_tenant_model()
            schema_name = request.tenant.schema_name
            task = sync_products_batch_task.delay(product_ids, options, schema_name)

            return JsonResponse({
                'success': True,
                'task_id': task.id,
                'message': f'Запущена синхронизация {len(product_ids)} товаров'
            })
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


@require_POST
def save_integration_settings(request, integration_id: str):
    """
    API endpoint для сохранения настроек интеграции.
    POST /integrations/settings/<integration_id>/

    Body: JSON с полями для обновления
    """
    if not hasattr(request, 'user') or not request.user.is_authenticated:
        return JsonResponse({'error': 'Unauthorized'}, status=401)

    model = get_integration_model(integration_id)
    if not model:
        return JsonResponse({'error': f'Unknown integration: {integration_id}'}, status=404)

    # Получить или создать
    instance, created = model.objects.get_or_create(
        defaults={'name': INTEGRATION_REGISTRY[integration_id][1]}
    )

    # Парсинг данных
    try:
        data = json.loads(request.body)
    except json.JSONDecodeError:
        return JsonResponse({'error': 'Invalid JSON'}, status=400)

    # Обновить только разрешённые поля (не is_active - для этого toggle)
    allowed_fields = get_editable_fields(model)
    updated_fields = []

    for field in allowed_fields:
        if field in data:
            setattr(instance, field, data[field])
            updated_fields.append(field)

    if updated_fields:
        updated_fields.append('updated_at')
        instance.save(update_fields=updated_fields)

    return JsonResponse({
        'success': True,
        'is_configured': instance.is_configured,
        'updated_fields': updated_fields,
    })


def get_editable_fields(model):
    """Получить список редактируемых полей модели (исключая служебные)"""
    excluded = {'id', 'integration_type', 'is_active', 'created_at', 'updated_at', 'extra_config'}
    fields = []
    for field in model._meta.get_fields():
        if hasattr(field, 'name') and field.name not in excluded:
            if not field.is_relation:  # Исключаем FK/M2M
                fields.append(field.name)
    return fields


def get_integration_form_data(request, integration_id: str):
    """
    GET endpoint для получения текущих настроек интеграции.
    Используется для заполнения формы справа.
    """
    model = get_integration_model(integration_id)
    if not model:
        return JsonResponse({'error': f'Unknown integration: {integration_id}'}, status=404)

    instance = model.objects.first()
    if not instance:
        # Вернуть пустую структуру полей
        return JsonResponse({
            'exists': False,
            'fields': get_form_fields_meta(model),
        })

    # Собрать данные полей (без чувствительных данных полностью)
    data = {}
    for field_name in get_editable_fields(model):
        field = model._meta.get_field(field_name)
        value = getattr(instance, field_name, None)

        # Маскировать секреты
        if 'token' in field_name.lower() or 'secret' in field_name.lower() or 'key' in field_name.lower():
            data[field_name] = '••••••••' if value else ''
        else:
            data[field_name] = value

    return JsonResponse({
        'exists': True,
        'is_active': instance.is_active,
        'is_configured': instance.is_configured,
        'data': data,
        'fields': get_form_fields_meta(model),
    })


def get_form_fields_meta(model):
    """Получить метаданные полей для построения формы на фронте"""
    fields = []
    editable_fields = get_editable_fields(model)

    # Для GLM отображаем только имя и API ключ
    if model.__name__ == 'GLMIntegration':
        for field_name in editable_fields:
            if field_name in ['name', 'api_key']:
                field = model._meta.get_field(field_name)
                field_info = {
                    'name': field_name,
                    'label': getattr(field, 'verbose_name', field_name),
                    'help_text': getattr(field, 'help_text', ''),
                    'required': not getattr(field, 'blank', True),
                    'type': 'text',  # default
                }

                # Определить тип поля
                if 'BooleanField' in field.__class__.__name__:
                    field_info['type'] = 'checkbox'
                elif 'URLField' in field.__class__.__name__:
                    field_info['type'] = 'url'
                elif 'secret' in field_name.lower() or 'token' in field_name.lower() or 'key' in field_name.lower():
                    field_info['type'] = 'password'

                fields.append(field_info)
            elif field_name == 'model_name':
                field = model._meta.get_field(field_name)
                field_info = {
                    'name': field_name,
                    'label': getattr(field, 'verbose_name', field_name),
                    'help_text': getattr(field, 'help_text', ''),
                    'required': not getattr(field, 'blank', True),
                    'type': 'select',  # dropdown
                    'choices': getattr(field, 'choices', [])
                }

                fields.append(field_info)
    # Для OpenRouter отображаем только имя, API ключ, модель и температуру
    elif model.__name__ == 'OpenRouterIntegration':
        for field_name in editable_fields:
            if field_name in ['name', 'api_key']:
                field = model._meta.get_field(field_name)
                field_info = {
                    'name': field_name,
                    'label': getattr(field, 'verbose_name', field_name),
                    'help_text': getattr(field, 'help_text', ''),
                    'required': not getattr(field, 'blank', True),
                    'type': 'password' if field_name == 'api_key' else 'text',
                }
                fields.append(field_info)

            elif field_name == 'temperature':
                field = model._meta.get_field(field_name)
                field_info = {
                    'name': field_name,
                    'label': getattr(field, 'verbose_name', field_name),
                    'help_text': getattr(field, 'help_text', ''),
                    'required': not getattr(field, 'blank', True),
                    'type': 'select',
                    'choices': getattr(field, 'choices', [])
                }
                fields.append(field_info)

            elif field_name == 'model_name':
                field = model._meta.get_field(field_name)
                field_info = {
                    'name': field_name,
                    'label': getattr(field, 'verbose_name', field_name),
                    'help_text': getattr(field, 'help_text', ''),
                    'required': not getattr(field, 'blank', True),
                    'type': 'select',
                    'dynamic_choices': True,
                    'choices_url': '/settings/integrations/openrouter/models/'
                }
                fields.append(field_info)
    # Для WooCommerce показываем только базовые поля для подключения
    elif model.__name__ == 'WooCommerceIntegration':
        basic_fields = ['store_url', 'consumer_key', 'consumer_secret']
        for field_name in editable_fields:
            if field_name in basic_fields:
                field = model._meta.get_field(field_name)
                field_info = {
                    'name': field_name,
                    'label': getattr(field, 'verbose_name', field_name),
                    'help_text': getattr(field, 'help_text', ''),
                    'required': not getattr(field, 'blank', True),
                    'type': 'text',
                }

                # Определить тип поля
                if 'BooleanField' in field.__class__.__name__:
                    field_info['type'] = 'checkbox'
                elif 'URLField' in field.__class__.__name__:
                    field_info['type'] = 'url'
                elif 'secret' in field_name.lower() or 'key' in field_name.lower():
                    field_info['type'] = 'password'

                fields.append(field_info)
    else:
        # Для других интеграций - все редактируемые поля
        for field_name in editable_fields:
            field = model._meta.get_field(field_name)
            field_info = {
                'name': field_name,
                'label': getattr(field, 'verbose_name', field_name),
                'help_text': getattr(field, 'help_text', ''),
                'required': not getattr(field, 'blank', True),
                'type': 'text',  # default
            }

            # Определить тип поля
            if 'BooleanField' in field.__class__.__name__:
                field_info['type'] = 'checkbox'
            elif 'URLField' in field.__class__.__name__:
                field_info['type'] = 'url'
            elif 'secret' in field_name.lower() or 'token' in field_name.lower() or 'key' in field_name.lower():
                field_info['type'] = 'password'

            fields.append(field_info)

    return fields
