import os
import json

from langchain_openai import ChatOpenAI
from pathlib import Path

from src.config.load_config import project_config

PROJECT_PATH = Path(__file__).resolve().parent.parent.parent.absolute()
DATA_PATH = os.path.join(PROJECT_PATH, 'data')

LLM = ChatOpenAI(
    model="qwen-plus-latest",
    api_key=project_config.get('bailian_API_key', ''),
    base_url=project_config.get('bailian_API_URL', ''),
)  # type: ignore


def load_year_logs(year: int = 2025, base_data_path: str | None = None) -> dict:
    """读取 data/Log/<year> 下的 .md 文件，返回结构化字典。

    返回示例结构：
    {
      'year': 2025,
      'year_summary': '...',
      'months': {
        '01': {
          'monthly_summary': '...',
          'entries': {
            '2025-01-01': '...'
          },
          'other_files': { 'notes.md': '...' }
        },
        ...
      },
      'other_files': [ { 'path': 'Log/2025/some.md', 'content': '...' } ]
    }

    规则说明：
    - 识别形如 YYYY-MM-DD.md 的为按日条目，日期作为键。
    - 识别月份名称（January..December）或数字为月度总结（例如 December.md 或 12.md）。
    - 当文件位于月份子目录（例如 .../2025/December/*.md）时，也会归到对应月份。
    - 未能确定归属的文件会被放入 other_files。
    """
    import re
    from pathlib import Path

    if base_data_path is None:
        base_data_path = DATA_PATH

    year_path = Path(base_data_path) / 'Log' / str(year)
    if not year_path.exists():
        return {}

    month_map = {
        'january': '01', 'february': '02', 'march': '03', 'april': '04',
        'may': '05', 'june': '06', 'july': '07', 'august': '08',
        'september': '09', 'october': '10', 'november': '11', 'december': '12'
    }

    def month_name_to_num(name: str) -> str | None:
        if not name:
            return None
        s = name.lower().strip()
        s = s.replace('.md', '')
        # 直接数字
        if s.isdigit():
            n = int(s)
            if 1 <= n <= 12:
                return f"{n:02d}"
        # 完整英文月份
        if s in month_map:
            return month_map[s]
        # 缩写或开头匹配
        for k in month_map:
            if k.startswith(s):
                return month_map[k]
        return None

    def ensure_month(res: dict, m: str):
        if m not in res['months']:
            res['months'][m] = {'monthly_summary': None, 'entries': {}, 'other_files': {}}

    def parse_date_from_stem(stem: str, default_year: int | None = None) -> str | None:
        """尝试从文件名 stem 中解析日期，支持：
        - YYYY-MM-DD
        - YY-MM-DD（自动扩展为 2000+YY）
        如果匹配成功返回 'YYYY-MM-DD'，否则返回 None。
        """
        import re

        # 允许后缀，比如 '25-08-11 Mon'，只取开头部分进行解析
        m = re.match(r'^(?P<y>\d{2,4})-(?P<m>\d{1,2})-(?P<d>\d{1,2})', stem)
        if not m:
            return None
        y = m.group('y')
        mo = int(m.group('m'))
        d = int(m.group('d'))
        if len(y) == 2:
            yy = int(y)
            yyyy = 2000 + yy
        else:
            yyyy = int(y)
        try:
            return f"{yyyy:04d}-{mo:02d}-{d:02d}"
        except Exception:
            return None

    res: dict = {'year': year, 'year_summary': None, 'months': {}, 'other_files': []}

    # 遍历年份目录下的文件和子目录
    for item in sorted(year_path.iterdir()):
        if item.is_file() and item.suffix.lower() == '.md':
            stem = item.stem
            try:
                text = item.read_text(encoding='utf-8')
            except Exception:
                text = item.read_text(encoding='utf-8', errors='ignore')

            # YYYY-MM-DD.md or YY-MM-DD... -> 日志条目
            parsed = parse_date_from_stem(stem)
            if parsed:
                month = parsed[5:7]
                ensure_month(res, month)
                res['months'][month]['entries'][parsed] = text
                continue

            # Month name like December.md
            mn = month_name_to_num(stem)
            if mn:
                ensure_month(res, mn)
                # 将视为当月的月度记录
                res['months'][mn]['monthly_summary'] = text
                continue

            # 整体年度总结
            if stem.lower() == 'summary' or 'summary' in stem.lower():
                # 若带有月份名称则上面已经捕获，这里为年度/通用总结
                res['year_summary'] = text
                continue

            # 其他无法分类的文件
            res['other_files'].append({'path': str(item.relative_to(base_data_path)), 'content': text})

        elif item.is_dir():
            # 目录通常是月份目录
            mnum = month_name_to_num(item.name)
            for f in sorted(item.glob('*.md')):
                stem = f.stem
                try:
                    text = f.read_text(encoding='utf-8')
                except Exception:
                    text = f.read_text(encoding='utf-8', errors='ignore')

                # summary 文件
                if 'summary' in stem.lower():
                    if mnum:
                        ensure_month(res, mnum)
                        res['months'][mnum]['monthly_summary'] = text
                    else:
                        res['other_files'].append({'path': str(f.relative_to(base_data_path)), 'content': text})
                    continue

                # 完整日期格式
                # 支持 YYYY-MM-DD 或 YY-MM-DD 开头（允许后缀，例如 '25-08-11 Mon'）
                parsed = parse_date_from_stem(stem, default_year=year)
                if parsed:
                    date = parsed
                    month = date[5:7]
                    ensure_month(res, month)
                    res['months'][month]['entries'][date] = text
                    continue

                # 仅为日号，如 1.md, 31.md
                if re.match(r'^\d{1,2}$', stem):
                    if mnum:
                        day = int(stem)
                        date = f"{year}-{mnum}-{day:02d}"
                        ensure_month(res, mnum)
                        res['months'][mnum]['entries'][date] = text
                    else:
                        res['other_files'].append({'path': str(f.relative_to(base_data_path)), 'content': text})
                    continue

                # 其他文件，放入该月份的 other_files
                if mnum:
                    ensure_month(res, mnum)
                    res['months'][mnum]['other_files'][stem] = text
                else:
                    res['other_files'].append({'path': str(f.relative_to(base_data_path)), 'content': text})

    return res


if __name__ == "__main__":
    year_logs = load_year_logs(2025)

    prompt = f"""
你是一个日记分析专家，擅长根据用户的日记，分析用户的行为，按照月和年为时间维度，输出总结。

你的总结应当包括但不限于以下内容：
1. 用户在这个时间段内的主要活动和重大事件。
2. 用户的情绪变化和心理状态。
3. 用户的兴趣爱好和关注点。
4. 用户的社交活动和人际关系。
5. 用户的生活习惯和日常规律。
6. 任何其他你认为重要的信息。

注意：不要对于进行过度的推断，只基于用户的日记内容进行分析。

你的输出应当包含分月份的总结和整体的年度总结。

以下是用户的日记内容：
{json.dumps(year_logs, ensure_ascii=False)}
    """

    llm_resp = LLM.invoke(prompt)
    print(llm_resp.content)

    print('done')