"""
趨勢資料庫模型

包含:
- TrendRecord: 趨勢記錄表
- TrendKeyword: 趨勢關鍵字表
- TrendAnalysis: AI 趨勢分析報告表
- WebSearchCache: Web Search 結果快取表
- TelegramUser: Telegram 用戶綁定表
"""

from sqlalchemy import (
    Column, Integer, String, Text, Float, Boolean, DateTime, Date,
    ForeignKey, Index, UniqueConstraint, BigInteger
)
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from datetime import datetime, date, timedelta
import hashlib
import json

# 使用與其他模型相同的 Base
from database.models import Base


class TrendRecord(Base):
    """趨勢資料記錄 - 儲存爬取的原始內容"""
    __tablename__ = 'trend_records'

    id = Column(Integer, primary_key=True)

    # 來源識別
    source = Column(String(50), nullable=False, index=True)
    # 可選值: 'google_news', 'ptt', 'dcard', 'youtube', 'weather', 'ollama_web_search'

    source_board = Column(String(100))
    # PTT/Dcard 看板名稱，如 'Gossiping', '網路購物'

    source_url = Column(String(500))
    # 原始連結

    source_id = Column(String(100))
    # 來源平台的唯一識別碼 (用於去重)

    # 內容
    title = Column(String(500), nullable=False)
    content = Column(Text)
    # 全文內容或摘要

    author = Column(String(100))
    # 作者/媒體名稱

    # 互動指標
    popularity_score = Column(Integer, default=0)
    # 熱門度分數 (推數、讚數、觀看數等)

    comment_count = Column(Integer, default=0)
    # 留言數

    # 分類標籤
    category = Column(String(100), index=True)
    # 商品分類對應: '美妝', '3C', '家電', '服飾' 等

    tags = Column(Text)
    # JSON 格式的標籤列表

    # 時間資訊
    published_at = Column(DateTime)
    # 原始發布時間

    trend_date = Column(Date, nullable=False, index=True)
    # 趨勢所屬日期 (用於聚合查詢)

    created_at = Column(DateTime, default=datetime.now)
    # 爬取時間

    # AI 分析結果
    sentiment = Column(String(20))
    # 情緒分析: 'positive', 'negative', 'neutral'

    ai_summary = Column(Text)
    # Ollama 生成的摘要

    relevance_score = Column(Float, default=0.0)
    # 與商品銷售的相關性分數 (0-1)

    # 索引優化
    __table_args__ = (
        Index('idx_trend_source_date', 'source', 'trend_date'),
        Index('idx_trend_category_date', 'category', 'trend_date'),
        Index('idx_trend_popularity', 'popularity_score', 'trend_date'),
        UniqueConstraint('source', 'source_id', name='uq_source_record'),
    )

    def to_dict(self):
        """轉換為字典"""
        return {
            'id': self.id,
            'source': self.source,
            'source_board': self.source_board,
            'source_url': self.source_url,
            'title': self.title,
            'content': self.content[:200] if self.content else None,
            'author': self.author,
            'popularity_score': self.popularity_score,
            'comment_count': self.comment_count,
            'category': self.category,
            'tags': json.loads(self.tags) if self.tags else [],
            'published_at': self.published_at.isoformat() if self.published_at else None,
            'trend_date': self.trend_date.isoformat() if self.trend_date else None,
            'sentiment': self.sentiment,
            'ai_summary': self.ai_summary,
            'relevance_score': self.relevance_score,
        }


class TrendKeyword(Base):
    """趨勢關鍵字 - 從文章中萃取的熱門詞彙"""
    __tablename__ = 'trend_keywords'

    id = Column(Integer, primary_key=True)

    keyword = Column(String(100), nullable=False, index=True)
    # 關鍵字

    keyword_type = Column(String(50), default='general')
    # 類型: 'product' (商品), 'brand' (品牌), 'event' (事件), 'general'

    source = Column(String(50), nullable=False)
    # 來源平台

    category = Column(String(100), index=True)
    # 商品分類

    mention_count = Column(Integer, default=1)
    # 提及次數

    trend_date = Column(Date, nullable=False, index=True)
    # 趨勢日期

    sentiment_avg = Column(Float, default=0.0)
    # 平均情緒分數 (-1 到 1)

    related_keywords = Column(Text)
    # JSON 格式的相關關鍵字

    created_at = Column(DateTime, default=datetime.now)
    updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)

    __table_args__ = (
        Index('idx_keyword_date_count', 'trend_date', 'mention_count'),
        UniqueConstraint('keyword', 'source', 'trend_date', name='uq_keyword_source_date'),
    )

    def to_dict(self):
        """轉換為字典"""
        return {
            'id': self.id,
            'keyword': self.keyword,
            'keyword_type': self.keyword_type,
            'source': self.source,
            'category': self.category,
            'mention_count': self.mention_count,
            'trend_date': self.trend_date.isoformat() if self.trend_date else None,
            'sentiment_avg': self.sentiment_avg,
            'related_keywords': json.loads(self.related_keywords) if self.related_keywords else [],
        }


class TrendAnalysis(Base):
    """趨勢分析報告 - Ollama AI 生成的分析結果"""
    __tablename__ = 'trend_analysis'

    id = Column(Integer, primary_key=True)

    analysis_date = Column(Date, nullable=False, index=True)
    # 分析日期

    category = Column(String(100), index=True)
    # 分析的商品分類 (null 表示全品類)

    analysis_type = Column(String(50), nullable=False)
    # 分析類型: 'daily_summary', 'weekly_trend', 'hot_topic', 'marketing_insight'

    # AI 分析內容
    summary = Column(Text, nullable=False)
    # 摘要說明

    hot_keywords = Column(Text)
    # JSON: 熱門關鍵字列表

    hot_topics = Column(Text)
    # JSON: 熱門話題列表

    consumer_insights = Column(Text)
    # JSON: 消費者洞察

    marketing_suggestions = Column(Text)
    # JSON: 行銷建議

    copywriting_hints = Column(Text)
    # JSON: 文案撰寫提示

    # 來源統計
    source_stats = Column(Text)
    # JSON: 各來源資料統計

    record_count = Column(Integer, default=0)
    # 分析涵蓋的記錄數

    # Ollama 資訊
    model_used = Column(String(50))
    # 使用的模型

    generation_time = Column(Float)
    # 生成耗時 (秒)

    created_at = Column(DateTime, default=datetime.now)

    __table_args__ = (
        UniqueConstraint('analysis_date', 'category', 'analysis_type', name='uq_analysis'),
    )

    def to_dict(self):
        """轉換為字典"""
        return {
            'id': self.id,
            'analysis_date': self.analysis_date.isoformat() if self.analysis_date else None,
            'category': self.category,
            'analysis_type': self.analysis_type,
            'summary': self.summary,
            'hot_keywords': json.loads(self.hot_keywords) if self.hot_keywords else [],
            'hot_topics': json.loads(self.hot_topics) if self.hot_topics else [],
            'consumer_insights': json.loads(self.consumer_insights) if self.consumer_insights else [],
            'marketing_suggestions': json.loads(self.marketing_suggestions) if self.marketing_suggestions else [],
            'copywriting_hints': json.loads(self.copywriting_hints) if self.copywriting_hints else [],
            'source_stats': json.loads(self.source_stats) if self.source_stats else {},
            'record_count': self.record_count,
            'model_used': self.model_used,
            'generation_time': self.generation_time,
            'created_at': self.created_at.isoformat() if self.created_at else None,
        }


class WebSearchCache(Base):
    """Web Search 結果快取 - 避免重複查詢"""
    __tablename__ = 'web_search_cache'

    id = Column(Integer, primary_key=True)

    # 查詢識別
    query_hash = Column(String(64), nullable=False, unique=True, index=True)
    # MD5(query + search_type)

    query = Column(String(500), nullable=False)
    # 原始查詢字串

    search_type = Column(String(50), default='general')
    # 搜尋類型: general, news, shopping, trends

    # 結果
    result_json = Column(Text, nullable=False)
    # JSON 格式的完整結果

    summary = Column(Text)
    # AI 生成的摘要

    result_count = Column(Integer, default=0)
    # 結果數量

    # 元資料
    model_used = Column(String(50))
    generation_time = Column(Float)

    # 時間
    created_at = Column(DateTime, default=datetime.now, index=True)
    expires_at = Column(DateTime)
    # 快取過期時間 (預設 24 小時)

    __table_args__ = (
        Index('idx_cache_query_type', 'query', 'search_type'),
        Index('idx_cache_expires', 'expires_at'),
    )

    @staticmethod
    def generate_hash(query: str, search_type: str) -> str:
        """產生查詢雜湊"""
        return hashlib.md5(f"{query}:{search_type}".encode(), usedforsecurity=False).hexdigest()

    def is_expired(self) -> bool:
        """檢查是否已過期"""
        if not self.expires_at:
            return True
        return datetime.now() > self.expires_at

    def to_dict(self):
        """轉換為字典"""
        return {
            'id': self.id,
            'query': self.query,
            'search_type': self.search_type,
            'result': json.loads(self.result_json) if self.result_json else None,
            'summary': self.summary,
            'result_count': self.result_count,
            'model_used': self.model_used,
            'generation_time': self.generation_time,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'expires_at': self.expires_at.isoformat() if self.expires_at else None,
            'is_expired': self.is_expired(),
        }


class TelegramUser(Base):
    """Telegram 用戶綁定表"""
    __tablename__ = 'telegram_users'

    id = Column(Integer, primary_key=True)

    telegram_id = Column(BigInteger, unique=True, nullable=False, index=True)
    # Telegram 用戶 ID

    telegram_username = Column(String(100))
    # Telegram 用戶名稱

    user_id = Column(Integer, ForeignKey('users.id'))
    # 綁定的系統用戶 ID (可選)

    display_name = Column(String(100))
    # 顯示名稱

    is_active = Column(Boolean, default=True)
    # 是否啟用

    is_admin = Column(Boolean, default=False)
    # 是否為管理員

    # 偏好設定
    notify_trends = Column(Boolean, default=True)
    # 是否接收趨勢通知

    notify_daily_summary = Column(Boolean, default=True)
    # 是否接收每日摘要

    preferred_categories = Column(Text)
    # JSON: 偏好的分類列表

    created_at = Column(DateTime, default=datetime.now)
    last_active_at = Column(DateTime, default=datetime.now)

    def to_dict(self):
        """轉換為字典"""
        return {
            'id': self.id,
            'telegram_id': self.telegram_id,
            'telegram_username': self.telegram_username,
            'user_id': self.user_id,
            'display_name': self.display_name,
            'is_active': self.is_active,
            'is_admin': self.is_admin,
            'notify_trends': self.notify_trends,
            'notify_daily_summary': self.notify_daily_summary,
            'preferred_categories': json.loads(self.preferred_categories) if self.preferred_categories else [],
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'last_active_at': self.last_active_at.isoformat() if self.last_active_at else None,
        }


# PTT 目標看板
PTT_BOARDS = [
    'Gossiping',      # 八卦板 - 熱門話題
    'Lifeismoney',    # 省錢板 - 優惠情報
    'e-shopping',     # 網購板 - 電商趨勢
    'Beauty',         # 美妝板 - 美妝趨勢
    'MakeUp',         # 化妝板 - 彩妝趨勢
    'WomenTalk',      # 女板 - 女性消費趨勢
    'home-sale',      # 房屋板 - 居家用品參考
    'BabyMother',     # 媽寶板 - 母嬰市場
    'Tech_Job',       # 科技業 - 3C 消費力
]

# Dcard 目標看板
DCARD_BOARDS = [
    '網路購物',        # 電商討論
    '美妝',           # 美妝趨勢
    '穿搭',           # 服飾趨勢
    '3C',             # 科技產品
    '省錢',           # 優惠情報
    '生活',           # 生活趨勢
    '美食',           # 餐飲趨勢
]

# 看板對應分類
BOARD_CATEGORY_MAPPING = {
    # PTT
    'Beauty': '美妝',
    'MakeUp': '美妝',
    'e-shopping': '電商',
    'Lifeismoney': '優惠',
    'home-sale': '居家',
    'BabyMother': '母嬰',
    'Gossiping': '熱門',
    'WomenTalk': '生活',
    'Tech_Job': '3C',
    # Dcard
    '美妝': '美妝',
    '穿搭': '服飾',
    '3C': '3C',
    '網路購物': '電商',
    '省錢': '優惠',
    '生活': '生活',
    '美食': '美食',
}


def get_category_for_board(board: str) -> str:
    """根據看板名稱取得商品分類"""
    return BOARD_CATEGORY_MAPPING.get(board, '其他')
