import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { SkillsService } from '../skills/skills.service';

export interface ToolDefinition {
  name: string;
  description: string;
  parameters: Record<string, any>;
}

export interface ToolCall {
  tool: string;
  params: Record<string, any>;
  description?: string;
}

export interface ToolResult {
  success: boolean;
  data: any;
  summary: string;
}

const KNOWLEDGE_DOMAINS = [
  { id: 'ai-basics', name: 'AI 基础知识', keywords: ['AI', '人工智能', '大模型', 'chatgpt', 'gpt', '大语言模型', 'llm', '深度学习', '神经网络', 'machine learning', '机器学习'] },
  { id: 'prompt-engineering', name: '提示词工程', keywords: ['提示词', 'prompt', 'system prompt', 'role', 'few-shot', 'chain-of-thought', 'cot'] },
  { id: 'programming', name: '编程开发', keywords: ['python', 'javascript', 'typescript', 'java', '代码', '函数', '算法', 'debug', 'bug', '编程', '开发', 'react', 'vue', 'node'] },
  { id: 'writing', name: '写作创作', keywords: ['写作', '文章', '文案', '润色', '作文', '创作', '故事', '小说', '博客'] },
  { id: 'english', name: '英语学习', keywords: ['英语', 'english', '翻译', '语法', 'grammar', 'vocabulary', '口语', '写作', '阅读'] },
  { id: 'data-science', name: '数据分析', keywords: ['数据', '分析', '统计', '图表', '可视化', 'sql', 'excel', 'pandas', 'numpy', '数据分析'] },
  { id: 'office', name: '办公效率', keywords: ['ppt', 'excel', 'word', '办公', '邮件', '报告', '文档', '会议', '总结'] },
  { id: 'career', name: '职业发展', keywords: ['简历', '面试', '求职', '职业', '工作', '升职', '薪资'] },
];

const LEARNING_PATH_STAGES = [
  {
    id: 'basics', title: '认识大模型',
    tasks: [
      { label: '了解 AI 基本概念', keyword: '人工智能' },
      { label: '认识大语言模型', keyword: '大模型' },
      { label: '体验 AI 对话', keyword: '' },
    ],
  },
  {
    id: 'prompt', title: '提示词工程',
    tasks: [
      { label: '了解提示词基础', keyword: '提示词' },
      { label: '练习提示词编写', keyword: '' },
      { label: '保存优质提示词', keyword: '' },
    ],
  },
  {
    id: 'advanced', title: '模型微调与高级应用',
    tasks: [
      { label: '了解模型微调', keyword: '微调' },
      { label: '了解 RAG', keyword: 'rag' },
      { label: '了解 Function Calling', keyword: 'function calling' },
    ],
  },
  {
    id: 'agent', title: 'Agent 开发',
    tasks: [
      { label: '了解 AI Agent', keyword: 'agent' },
      { label: '学习工具调用', keyword: 'tool' },
      { label: '实践项目', keyword: '' },
    ],
  },
];

@Injectable()
export class UserAiAssistantService {
  constructor(
    private prisma: PrismaService,
    private skillsService: SkillsService,
  ) {}

  private userTools(): ToolDefinition[] {
    return [
      {
        name: 'navigate',
        description: '跳转到网站的某个页面',
        parameters: { path: { type: 'string', description: '页面路径，如 /sandbox、/skills、/my/member、/learning、/models、/prompts、/compare、/community、/courses、/my、/about' } },
      },
      {
        name: 'search',
        description: '搜索平台上的课程、提示词、工具、文章等内容',
        parameters: { q: { type: 'string', description: '搜索关键词（必填）' }, type: { type: 'string', enum: ['all', 'courses', 'prompts', 'tools', 'contents'], description: '搜索类型（可选，默认全部）' } },
      },
      {
        name: 'list-skills',
        description: '浏览技能列表，可按分类、难度、关键词过滤',
        parameters: { category: { type: 'string', description: '分类（可选，如 basic/technical/creative）' }, difficulty: { type: 'string', description: '难度（可选，如 beginner/intermediate/advanced）' }, search: { type: 'string', description: '搜索关键词（可选）' } },
      },
      {
        name: 'get-skill',
        description: '查看某个技能的详细信息',
        parameters: { id: { type: 'string', description: '技能ID（必填），如 coding、writing、english、data-analysis' } },
      },
      {
        name: 'get-skill-categories',
        description: '查看所有技能分类',
        parameters: {},
      },
      {
        name: 'get-learning-analytics',
        description: '查看学情分析（知识领域掌握度），需要登录',
        parameters: {},
      },
      {
        name: 'get-learning-path',
        description: '查看学习路径进度，需要登录',
        parameters: {},
      },
      {
        name: 'list-notifications',
        description: '查看我的通知列表，需要登录',
        parameters: { page: { type: 'number', description: '页码（可选）' }, pageSize: { type: 'number', description: '每页数量（可选）' } },
      },
      {
        name: 'get-unread-count',
        description: '查看未读通知数量，需要登录',
        parameters: {},
      },
      {
        name: 'mark-notification-read',
        description: '标记某条通知为已读，需要登录',
        parameters: { id: { type: 'number', description: '通知ID（必填）' } },
      },
      {
        name: 'mark-all-read',
        description: '将所有通知标记为已读，需要登录',
        parameters: {},
      },
      {
        name: 'get-profile',
        description: '查看我的个人信息（昵称、手机号、会员状态等），需要登录',
        parameters: {},
      },
      {
        name: 'list-models',
        description: '查看平台支持的AI模型列表',
        parameters: {},
      },
      {
        name: 'list-prompts',
        description: '浏览提示词列表',
        parameters: {},
      },
      {
        name: 'list-courses',
        description: '浏览课程列表',
        parameters: {},
      },
      {
        name: 'list-user-orders',
        description: '查看我的订单记录，需要登录',
        parameters: {},
      },
      {
        name: 'get-current-subscription',
        description: '查看当前会员订阅信息，需要登录',
        parameters: {},
      },
    ];
  }

  getAvailableTools(): ToolDefinition[] {
    return this.userTools();
  }

  getToolsDescription(): string {
    return this.getAvailableTools().map(t => {
      const params = Object.entries(t.parameters)
        .map(([k, v]: any) => `  - ${k}: ${v.type}${v.description ? ' (' + v.description + ')' : ''}${v.enum ? ' [' + v.enum.join('|') + ']' : ''}`)
        .join('\n');
      return `- **${t.name}**: ${t.description}\n${params}`;
    }).join('\n\n');
  }

  async execute(call: ToolCall, userId?: number): Promise<ToolResult> {
    try {
      switch (call.tool) {
        case 'navigate':
          return { success: true, data: { path: call.params.path }, summary: `跳转到 ${call.params.path}` };

        case 'search': {
          const { q, type } = call.params;
          if (!q) throw new Error('请输入搜索关键词');
          const results = await this.search(q, type || 'all');
          return { success: true, data: results, summary: `找到 ${results.total} 条结果：${results.results.slice(0, 5).map(r => r.title).join('、')}` };
        }

        case 'list-skills': {
          const skills = await this.skillsService.findAll(call.params);
          return { success: true, data: skills, summary: `共 ${skills.total} 个技能：${skills.items.map(s => s.name).join('、')}` };
        }

        case 'get-skill': {
          const skill = await this.skillsService.findById(call.params.id);
          if (!skill) throw new Error(`技能 ${call.params.id} 不存在`);
          return { success: true, data: skill, summary: `技能「${skill.name}」(${skill.category} - ${skill.difficulty})：${skill.description}` };
        }

        case 'get-skill-categories': {
          const cats = await this.skillsService.getCategories();
          return { success: true, data: { categories: cats }, summary: `共 ${cats.length} 个分类：${cats.map(c => c.name).join('、')}` };
        }

        case 'get-learning-analytics': {
          if (!userId) throw new Error('需要登录');
          const analytics = await this.getLearningAnalytics(userId);
          return { success: true, data: analytics, summary: `总对话 ${analytics.totalSessions} 次，${analytics.domains.filter(d => d.weak).length} 个薄弱领域，建议从 ${analytics.recommendations[0]?.title || '探索更多'} 开始` };
        }

        case 'get-learning-path': {
          if (!userId) throw new Error('需要登录');
          const path = await this.getLearningPath(userId);
          return { success: true, data: path, summary: `学习路径共 ${path.length} 个阶段：${path.map(s => `${s.title}(${s.progress}%)`).join('、')}` };
        }

        case 'list-notifications': {
          if (!userId) throw new Error('需要登录');
          const page = call.params.page || 1;
          const pageSize = call.params.pageSize || 20;
          const [items, total] = await Promise.all([
            this.prisma.notification.findMany({
              where: { userId }, orderBy: { createdAt: 'desc' }, skip: (page - 1) * pageSize, take: pageSize,
            }),
            this.prisma.notification.count({ where: { userId } }),
          ]);
          return { success: true, data: { items, total, page, pageSize }, summary: `共 ${total} 条通知` };
        }

        case 'get-unread-count': {
          if (!userId) throw new Error('需要登录');
          const count = await this.prisma.notification.count({ where: { userId, isRead: false } });
          return { success: true, data: { count }, summary: `有 ${count} 条未读通知` };
        }

        case 'mark-notification-read': {
          if (!userId) throw new Error('需要登录');
          await this.prisma.notification.updateMany({ where: { id: call.params.id, userId }, data: { isRead: true } });
          return { success: true, data: {}, summary: `通知 ${call.params.id} 已标记为已读` };
        }

        case 'mark-all-read': {
          if (!userId) throw new Error('需要登录');
          await this.prisma.notification.updateMany({ where: { userId, isRead: false }, data: { isRead: true } });
          return { success: true, data: {}, summary: '所有通知已标记为已读' };
        }

        case 'get-profile': {
          if (!userId) throw new Error('需要登录');
          const profile = await this.prisma.user.findUnique({
            where: { id: userId },
            select: { id: true, phone: true, email: true, nickname: true, avatar: true, status: true, memberPlan: true, memberExpire: true, sandboxDaily: true, createdAt: true },
          });
          if (!profile) throw new Error('用户不存在');
          return { success: true, data: profile, summary: `用户 ${profile.nickname || profile.phone || profile.email}${profile.memberPlan !== 'FREE' ? '，会员: ' + profile.memberPlan : '，当前为免费用户'}${profile.memberExpire ? '，到期: ' + profile.memberExpire.toISOString().slice(0, 10) : ''}` };
        }

        case 'list-models': {
          const models = await this.prisma.aiModel.findMany({ where: { status: 'ACTIVE' }, orderBy: { sortOrder: 'asc' } });
          if (models.length === 0) {
            return { success: true, data: { models: [] }, summary: '目前没有可用的AI模型，请稍后再试' };
          }
          return { success: true, data: { models }, summary: `共 ${models.length} 个模型：${models.map(m => m.name).join('、')}` };
        }

        case 'list-prompts': {
          const items = await this.prisma.prompt.findMany({
            where: { deletedAt: null, status: 'PUBLISHED' },
            take: 50, orderBy: { createdAt: 'desc' },
            select: { id: true, title: true, description: true, tags: true },
          });
          return { success: true, data: { items, total: items.length }, summary: `共 ${items.length} 个提示词：${items.map(p => p.title).join('、')}` };
        }

        case 'list-courses': {
          const items = await this.prisma.course.findMany({
            where: { deletedAt: null, status: 'PUBLISHED' },
            take: 50, orderBy: { createdAt: 'desc' },
            select: { id: true, title: true, description: true, price: true, isFree: true },
          });
          const freeCount = items.filter(c => c.isFree).length;
          return { success: true, data: { items, total: items.length }, summary: `共 ${items.length} 个课程（${freeCount} 个免费）：${items.map(c => c.title).join('、')}` };
        }

        case 'list-user-orders': {
          if (!userId) throw new Error('需要登录');
          const items = await this.prisma.order.findMany({
            where: { userId },
            take: 50, orderBy: { createdAt: 'desc' },
          });
          const paidAmount = items.filter(o => o.status === 'PAID').reduce((s, o) => s + o.amount, 0);
          return { success: true, data: { items, total: items.length, paidAmount }, summary: `共 ${items.length} 笔订单，已支付总额 ¥${paidAmount}` };
        }

        case 'get-current-subscription': {
          if (!userId) throw new Error('需要登录');
          const now = new Date();
          const sub = await this.prisma.subscription.findFirst({
            where: { userId, status: 'ACTIVE', endDate: { gt: now } },
            orderBy: { endDate: 'desc' },
          });
          if (!sub) {
            const user = await this.prisma.user.findUnique({ where: { id: userId }, select: { memberPlan: true, memberExpire: true } });
            if (!user) throw new Error('用户不存在');
            return { success: true, data: null, summary: user.memberPlan !== 'FREE' ? `会员状态: ${user.memberPlan}，到期 ${user.memberExpire?.toISOString().slice(0, 10) || '未知'}` : '当前为免费用户，暂无有效订阅' };
          }
          return { success: true, data: sub, summary: `当前订阅: ${sub.plan}，到期 ${sub.endDate.toISOString().slice(0, 10)}，剩余 ${Math.ceil((sub.endDate.getTime() - Date.now()) / 86400000)} 天` };
        }

        default:
          throw new Error(`未知工具: ${call.tool}`);
      }
    } catch (err: any) {
      return { success: false, data: null, summary: `执行失败: ${err.message}` };
    }
  }

  private async getLearningAnalytics(userId: number) {
    const sessions = await this.prisma.sandboxSession.findMany({
      where: { userId }, orderBy: { createdAt: 'desc' }, take: 100,
    });

    const domainCounts: Record<string, number> = {};
    const domainDates: Record<string, string> = {};
    const totalSessions = sessions.length;

    for (const d of KNOWLEDGE_DOMAINS) domainCounts[d.id] = 0;

    for (const session of sessions) {
      const searchText = `${session.title} ${session.messages || ''}`.toLowerCase();
      for (const domain of KNOWLEDGE_DOMAINS) {
        if (domain.keywords.some(kw => searchText.includes(kw))) {
          domainCounts[domain.id] = (domainCounts[domain.id] || 0) + 1;
          if (!domainDates[domain.id] || session.createdAt.toISOString() > domainDates[domain.id]) {
            domainDates[domain.id] = session.createdAt.toISOString();
          }
        }
      }
    }

    const domains = KNOWLEDGE_DOMAINS.map(d => {
      const count = domainCounts[d.id] || 0;
      const mastery = Math.min(Math.round((count / Math.max(totalSessions * 0.3, 1)) * 100), 100);
      return { id: d.id, name: d.name, sessionCount: count, mastery, lastActive: domainDates[d.id] || null, weak: mastery < 30 };
    });

    const weakDomains = domains.filter(d => d.weak);
    const recommendations = weakDomains.length > 0
      ? weakDomains.slice(0, 3).flatMap(d => [
        { title: `了解 ${d.name}`, url: '/sandbox' },
      ])
      : [{ title: '探索更多知识领域', url: '/sandbox' }];

    return { domains, totalSessions, weakDomains: weakDomains.map(d => d.name), recommendations };
  }

  private async getLearningPath(userId: number) {
    const sessions = await this.prisma.sandboxSession.findMany({
      where: { userId }, select: { title: true, messages: true },
    });
    const allText = sessions.map(s => `${s.title} ${s.messages || ''}`.toLowerCase()).join(' ');

    return LEARNING_PATH_STAGES.map(stage => {
      const completedCount = stage.tasks.filter(t => !t.keyword || allText.includes(t.keyword)).length;
      const progress = stage.tasks.length > 0 ? Math.round((completedCount / stage.tasks.length) * 100) : 0;
      return { ...stage, completedCount, totalTasks: stage.tasks.length, progress, unlocked: true };
    });
  }

  private async search(q: string, type: string) {
    const results: any[] = [];
    let total = 0;

    if (type === 'all' || type === 'courses') {
      const [items, count] = await Promise.all([
        this.prisma.course.findMany({
          where: { deletedAt: null, status: 'PUBLISHED', OR: [{ title: { contains: q } }, { description: { contains: q } }] },
          select: { id: true, title: true, description: true, isFree: true },
          take: type === 'courses' ? 20 : 5,
        }),
        this.prisma.course.count({ where: { deletedAt: null, status: 'PUBLISHED', OR: [{ title: { contains: q } }, { description: { contains: q } }] } }),
      ]);
      results.push(...items.map(i => ({ ...i, _type: 'course' })));
      total += count;
    }

    if (type === 'all' || type === 'prompts') {
      const [items, count] = await Promise.all([
        this.prisma.prompt.findMany({
          where: { deletedAt: null, status: 'PUBLISHED', OR: [{ title: { contains: q } }, { description: { contains: q } }, { content: { contains: q } }] },
          select: { id: true, title: true, description: true },
          take: type === 'prompts' ? 20 : 5,
        }),
        this.prisma.prompt.count({ where: { deletedAt: null, status: 'PUBLISHED', OR: [{ title: { contains: q } }, { description: { contains: q } }, { content: { contains: q } }] } }),
      ]);
      results.push(...items.map(i => ({ ...i, _type: 'prompt' })));
      total += count;
    }

    if (type === 'all' || type === 'tools') {
      const [items, count] = await Promise.all([
        this.prisma.tool.findMany({
          where: { deletedAt: null, OR: [{ name: { contains: q } }, { description: { contains: q } }] },
          select: { id: true, name: true, description: true },
          take: type === 'tools' ? 20 : 5,
        }),
        this.prisma.tool.count({ where: { deletedAt: null, OR: [{ name: { contains: q } }, { description: { contains: q } }] } }),
      ]);
      results.push(...items.map(i => ({ ...i, _type: 'tool' })));
      total += count;
    }

    if (type === 'all' || type === 'contents') {
      const [items, count] = await Promise.all([
        this.prisma.content.findMany({
          where: { deletedAt: null, status: 'PUBLISHED', OR: [{ title: { contains: q } }, { summary: { contains: q } }] },
          select: { id: true, title: true, summary: true },
          take: type === 'contents' ? 20 : 5,
        }),
        this.prisma.content.count({ where: { deletedAt: null, status: 'PUBLISHED', OR: [{ title: { contains: q } }, { summary: { contains: q } }] } }),
      ]);
      results.push(...items.map(i => ({ ...i, _type: 'content' })));
      total += count;
    }

    return { results, total };
  }
}
