# -*- coding: utf-8 -*-
"""
product_service.py — 产品服务模块（离线模式）

功能：
  - 管理产品列表、产品资料文档
  - 按产品筛选知识库常见问题
  - 提供文档下载路径

用法：
  from services.product_service import get_product_service
  service = get_product_service()
  products = service.get_products()
"""

import json
import shutil
from pathlib import Path
from typing import Optional

from utils.paths import SCRIPT_DIR, PROJECT_ROOT
from utils.logger import get_logger

logger = get_logger(__name__)

# 产品配置文件路径
PRODUCTS_FILE = SCRIPT_DIR / "products.json"
# 维护手册目录
DOCS_DIR = PROJECT_ROOT / "Docs" / "维护手册"


class ProductService:
    """产品服务：管理产品列表、资料、常见问题"""

    def __init__(self):
        self._products = []
        self._load_products()

    def _load_products(self):
        """加载产品配置"""
        try:
            if PRODUCTS_FILE.exists():
                with open(PRODUCTS_FILE, 'r', encoding='utf-8') as f:
                    data = json.load(f)
                    self._products = data.get('products', [])
                logger.info(f"[ProductService] 加载 {len(self._products)} 个产品配置")
            else:
                self._products = []
                logger.warning(f"[ProductService] 产品配置文件不存在: {PRODUCTS_FILE}")
        except Exception as e:
            logger.error(f"[ProductService] 加载产品配置失败: {e}")
            self._products = []

    def get_products(self) -> list[dict]:
        """获取所有产品列表（含常见问题数量）"""
        products = []
        for p in self._products:
            product = dict(p)
            # 查询该产品的知识库记录数量
            product['faq_count'] = self._count_faqs(product)
            products.append(product)
        return products

    def get_product(self, product_id: str) -> Optional[dict]:
        """获取单个产品详情"""
        for p in self._products:
            if p['id'] == product_id:
                product = dict(p)
                product['faq_count'] = self._count_faqs(product)
                return product
        return None

    def get_documents(self, product_id: str) -> list[dict]:
        """获取产品的资料文档列表"""
        product = self.get_product(product_id)
        if product:
            return product.get('documents', [])
        return []

    def get_document_path(self, doc_id: str) -> Optional[Path]:
        """获取文档文件路径"""
        for p in self._products:
            for doc in p.get('documents', []):
                if doc['id'] == doc_id:
                    filename = doc.get('filename', '')
                    if not filename:
                        continue
                    # 查找文件：优先在维护手册目录
                    file_path = DOCS_DIR / filename
                    if file_path.exists():
                        return file_path
                    # 备用：在项目根目录下查找
                    alt_path = PROJECT_ROOT / filename
                    if alt_path.exists():
                        return alt_path
        return None

    def get_faqs(self, product_id: str, limit: int = 50) -> list[dict]:
        """获取产品的常见问题列表（优先从 products.json 的 faqs 字段读取）"""
        product = self.get_product(product_id)
        if not product:
            return []

        # 优先从配置文件中静态定义的 faqs 获取
        static_faqs = product.get('faqs')
        if static_faqs is not None:
            return static_faqs

        # 否则从知识库动态搜索
        apk_product = product.get('apk_product', '')
        tags = product.get('tags', [])

        if not apk_product and not tags:
            return []

        try:
            import container
            engine = container.get_search_engine()
            if not engine:
                return []

            records = engine.search_by_product(
                apk_product=apk_product,
                tags=tags,
                limit=limit
            )

            # 转换为 FAQ 格式
            faqs = []
            for r in records:
                faqs.append({
                    'record_id': str(r.get('id', '')),
                    'title': r.get('title', ''),
                    'phenomenon': r.get('phenomenon', ''),
                    'solution': r.get('solution', ''),
                })
            return faqs
        except Exception as e:
            logger.error(f"[ProductService] 获取常见问题失败: {e}")
            return []

    def _count_faqs(self, product: dict) -> int:
        """计算产品的常见问题数量（优先使用静态配置的 faqs 字段）"""
        # 优先使用 products.json 中的 faqs 数量
        static_faqs = product.get('faqs')
        if static_faqs is not None:
            return len(static_faqs)

        apk_product = product.get('apk_product', '')
        tags = product.get('tags', [])

        if not apk_product and not tags:
            return 0

        try:
            import container
            engine = container.get_search_engine()
            if not engine:
                return 0
            records = engine.search_by_product(
                apk_product=apk_product,
                tags=tags,
                limit=1000
            )
            return len(records)
        except Exception as e:
            logger.error(f"[ProductService] 计算常见问题数量失败: {e}")
            return 0

    # ============================================================
    # 管理员上传/删除文档
    # ============================================================

    def add_document(self, product_id: str, filename: str, file_data: bytes) -> dict:
        """上传文档到产品资料目录

        Args:
            product_id: 产品 ID
            filename: 文件名（用户上传的原始文件名）
            file_data: 文件二进制内容

        Returns:
            {'success': bool, 'doc_id': str, 'message': str}
        """
        product = self.get_product(product_id)
        if not product:
            return {'success': False, 'message': '产品不存在'}

        product_name = product.get('name', product_id)
        product_dir = DOCS_DIR / product_name

        # 去重：如果已存在同名文件，删除
        existing_path = product_dir / filename
        if existing_path.exists():
            # 保留旧文件但更新
            pass

        # 确保目录存在
        product_dir.mkdir(parents=True, exist_ok=True)

        # 写入文件
        try:
            file_path = product_dir / filename
            with open(file_path, 'wb') as f:
                f.write(file_data)

            # 更新 products.json 配置
            doc_id = f'doc-{product_id}-{filename.replace(" ", "-").replace(".", "-")}'
            relative_path = f'{product_name}/{filename}'

            # 检查是否已存在于配置中
            existing_docs = product.get('documents', [])
            found = False
            for doc in existing_docs:
                if doc.get('filename') == relative_path:
                    found = True
                    break

            if not found:
                from utils.paths import SCRIPT_DIR
                products_file = SCRIPT_DIR / 'products.json'
                file_ext = filename.rsplit('.', 1)[-1] if '.' in filename else 'unknown'
                existing_docs.append({
                    'id': doc_id,
                    'title': filename.rsplit('.', 1)[0] if '.' in filename else filename,
                    'filename': relative_path,
                    'type': file_ext.lower(),
                })

                # 写回配置
                with open(products_file, 'r', encoding='utf-8') as f:
                    config = json.load(f)
                for p in config.get('products', []):
                    if p['id'] == product_id:
                        p['documents'] = existing_docs
                with open(products_file, 'w', encoding='utf-8') as f:
                    json.dump(config, f, ensure_ascii=False, indent=2)

                # 重新加载配置
                self._load_products()

            logger.info(f"[ProductService] 文档已上传: {relative_path} ({len(file_data)} bytes)")
            return {'success': True, 'doc_id': doc_id, 'message': f'文档 {filename} 上传成功', 'size': len(file_data)}
        except Exception as e:
            logger.error(f"[ProductService] 上传文档失败: {e}")
            return {'success': False, 'message': str(e)}

    def delete_document(self, doc_id: str) -> dict:
        """删除文档资料

        Args:
            doc_id: 文档 ID

        Returns:
            {'success': bool, 'message': str}
        """
        try:
            # 查找文档信息
            for p in self._products:
                for doc in p.get('documents', []):
                    if doc['id'] == doc_id:
                        filename = doc.get('filename', '')
                        product_id = p['id']

                        # 删除文件
                        file_path = DOCS_DIR / filename
                        if file_path.exists():
                            file_path.unlink()

                        # 从配置中移除
                        from utils.paths import SCRIPT_DIR
                        products_file = SCRIPT_DIR / 'products.json'
                        with open(products_file, 'r', encoding='utf-8') as f:
                            config = json.load(f)
                        for cp in config.get('products', []):
                            if cp['id'] == product_id:
                                cp['documents'] = [d for d in cp.get('documents', []) if d['id'] != doc_id]
                        with open(products_file, 'w', encoding='utf-8') as f:
                            json.dump(config, f, ensure_ascii=False, indent=2)

                        # 重新加载
                        self._load_products()

                        logger.info(f"[ProductService] 文档已删除: {filename}")
                        return {'success': True, 'message': f'文档已删除'}

            return {'success': False, 'message': '文档不存在'}
        except Exception as e:
            logger.error(f"[ProductService] 删除文档失败: {e}")
            return {'success': False, 'message': str(e)}


# 单例
_product_service = None


def get_product_service() -> ProductService:
    """获取产品服务单例"""
    global _product_service
    if _product_service is None:
        _product_service = ProductService()
    return _product_service
