"""HostPortMapping Repository - Django ORM 实现"""

import logging
from typing import List, Iterator, Dict, Optional

from django.db.models import QuerySet, Min

from apps.asset.models.asset_models import HostPortMapping
from apps.asset.dtos.asset import HostPortMappingDTO
from apps.common.decorators import auto_ensure_db_connection
from apps.common.utils import deduplicate_for_bulk

logger = logging.getLogger(__name__)


@auto_ensure_db_connection
class DjangoHostPortMappingRepository:
    """HostPortMapping Repository - Django ORM 实现
    
    职责：纯数据访问，不包含业务逻辑
    """

    def bulk_create_ignore_conflicts(self, items: List[HostPortMappingDTO]) -> int:
        """
        批量创建主机端口关联（忽略冲突）
        
        注意：自动按模型唯一约束去重，保留最后一条记录。
        
        Args:
            items: 主机端口关联 DTO 列表
        
        Returns:
            int: 实际创建的记录数
        """
        try:
            logger.debug("准备批量创建主机端口关联 - 数量: %d", len(items))
            
            if not items:
                logger.debug("主机端口关联为空，跳过创建")
                return 0
            
            # 自动按模型唯一约束去重
            unique_items = deduplicate_for_bulk(items, HostPortMapping)
                
            records = [
                HostPortMapping(
                    target_id=item.target_id,
                    host=item.host,
                    ip=item.ip,
                    port=item.port
                )
                for item in unique_items
            ]
            
            created = HostPortMapping.objects.bulk_create(
                records, 
                ignore_conflicts=True
            )
            
            created_count = len(created) if created else 0
            logger.debug("主机端口关联创建完成 - 数量: %d", created_count)
            
            return created_count
            
        except Exception as e:
            logger.error(
                "批量创建主机端口关联失败 - 数量: %d, 错误: %s",
                len(items),
                str(e),
                exc_info=True
            )
            raise

    def get_for_export(self, target_id: int, batch_size: int = 1000):
        queryset = (
            HostPortMapping.objects
            .filter(target_id=target_id)
            .order_by("host", "port")
            .values("host", "port")
            .iterator(chunk_size=batch_size)
        )
        for item in queryset:
            yield item

    def get_ips_for_export(self, target_id: int, batch_size: int = 1000) -> Iterator[str]:
        """流式导出目标下的所有唯一 IP 地址。"""
        queryset = (
            HostPortMapping.objects
            .filter(target_id=target_id)
            .values_list("ip", flat=True)
            .distinct()
            .order_by("ip")
            .iterator(chunk_size=batch_size)
        )
        for ip in queryset:
            yield ip

    def get_queryset_by_target(self, target_id: int) -> QuerySet:
        """获取目标下的 QuerySet"""
        return HostPortMapping.objects.filter(target_id=target_id)

    def get_all_queryset(self) -> QuerySet:
        """获取所有记录的 QuerySet"""
        return HostPortMapping.objects.all()

    def get_queryset_by_ip(self, ip: str, target_id: Optional[int] = None) -> QuerySet:
        """获取指定 IP 的 QuerySet"""
        qs = HostPortMapping.objects.filter(ip=ip)
        if target_id:
            qs = qs.filter(target_id=target_id)
        return qs

    def iter_raw_data_for_export(
        self, 
        target_id: int,
        batch_size: int = 1000
    ) -> Iterator[dict]:
        """
        流式获取原始数据用于 CSV 导出
        
        Args:
            target_id: 目标 ID
            batch_size: 每批数据量
        
        Yields:
            {
                'ip': '192.168.1.1',
                'host': 'example.com',
                'port': 80,
                'created_at': datetime
            }
        """
        qs = (
            HostPortMapping.objects
            .filter(target_id=target_id)
            .values('ip', 'host', 'port', 'created_at')
            .order_by('ip', 'host', 'port')
        )
        
        for row in qs.iterator(chunk_size=batch_size):
            yield row
