import { Controller, Post, Get, Body, Param, UseGuards, Logger } from '@nestjs/common'
import { InjectModel } from '@nestjs/mongoose'
import { Model } from 'mongoose'
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard'
import { Public } from '../../common/decorators/public.decorator'
import { CurrentUser } from '../../common/decorators/current-user.decorator'
import { AiService } from '../ai/ai.service'
import { Contribution, ContributionDocument } from '../schemas/contribution.schema'
import { CompanyBank, CompanyBankDocument } from '../schemas/company-bank.schema'

@Controller('contribution')
@UseGuards(JwtAuthGuard)
export class ContributionController {
  private readonly logger = new Logger(ContributionController.name)

  constructor(
    @InjectModel(Contribution.name) private contributionModel: Model<ContributionDocument>,
    @InjectModel(CompanyBank.name) private companyBankModel: Model<CompanyBankDocument>,
    private readonly aiService: AiService,
  ) {}

  @Post()
  async create(
    @CurrentUser('userId') userId: string,
    @Body() body: {
      interviewId: string
      company: string
      position: string
      rounds?: string
      questions?: string[]
      experience?: string
      tags?: string[]
    },
  ) {
    const contribution = await this.contributionModel.create({
      userId,
      interviewId: body.interviewId,
      company: body.company,
      position: body.position,
      rounds: body.rounds || '',
      questions: body.questions || [],
      experience: body.experience || '',
      tags: body.tags || [],
      verified: false,
    })

    // Async AI processing (non-blocking)
    this.aiProcessContribution(contribution, body).catch(e => {
      this.logger.error(`AI processing failed for contribution ${contribution._id}: ${e.message}`)
    })

    // Update company bank
    if (body.questions && body.questions.length > 0) {
      let bank = await this.companyBankModel.findOne({
        company: body.company,
        position: body.position,
      }).exec()

      if (!bank) {
        bank = await this.companyBankModel.create({
          company: body.company,
          position: body.position,
          questions: [],
          contributionCount: 0,
          viewCount: 0,
        })
      }

      // Add new questions (avoid duplicates)
      for (const q of body.questions) {
        const exists = bank.questions.some(eq => eq.content === q)
        if (!exists) {
          bank.questions.push({
            content: q,
            type: 'general',
            referenceAnswer: '',
            difficulty: 'medium',
            frequency: 1,
            tags: body.tags || [],
          })
        } else {
          const existing = bank.questions.find(eq => eq.content === q)
          if (existing) existing.frequency += 1
        }
      }
      bank.contributionCount += 1
      await bank.save()
    }

    return {
      id: contribution._id.toString(),
      company: contribution.company,
      position: contribution.position,
      message: '感谢你的分享！你的面经将帮助更多同学准备面试',
    }
  }

  private async aiProcessContribution(contribution: ContributionDocument, body: any) {
    const prompt = `你是一个面试题分析专家。请分析以下面经内容，返回 JSON（不要 Markdown 包裹）：

公司: ${body.company}
岗位: ${body.position}
轮次: ${body.rounds || '未说明'}
面试题: ${(body.questions || []).join('\n')}
面试经验: ${body.experience || ''}
用户标签: ${(body.tags || []).join(', ')}

请返回严格 JSON:
{
  "structuredQuestions": [
    {
      "content": "原题",
      "type": "技术题|行为题|场景题|算法题|系统设计题|HR题",
      "difficulty": "easy|medium|hard",
      "referenceAnswer": "参考答案",
      "tags": ["标签1", "标签2"]
    }
  ],
  "aiSummary": "面试总结，包含难度评估、重点方向、准备建议（50字以内）"
}`

    const result = await this.aiService.call({ systemPrompt: prompt, userMessage: '请分析以上面经', maxTokens: 3000 })
    const parsed = JSON.parse(result.replace(/```json\s*|\s*```/g, '').trim())

    await this.contributionModel.findByIdAndUpdate(contribution._id, {
      $set: {
        aiProcessed: true,
        structuredQuestions: parsed.structuredQuestions || [],
        aiSummary: parsed.aiSummary || '',
      },
    }).exec()

    // Update company bank with structured data
    if (parsed.structuredQuestions?.length > 0) {
      const bank = await this.companyBankModel.findOne({
        company: body.company,
        position: body.position,
      }).exec()

      if (bank) {
        for (const sq of parsed.structuredQuestions) {
          const existing = bank.questions.find(eq => eq.content === sq.content)
          if (existing) {
            existing.type = sq.type || existing.type
            existing.difficulty = sq.difficulty || existing.difficulty
            existing.referenceAnswer = sq.referenceAnswer || existing.referenceAnswer
            if (sq.tags) existing.tags = [...new Set([...existing.tags, ...sq.tags])]
          }
        }
        await bank.save()
      }
    }
  }

  @Get('company/:company/position/:position')
  async getBank(@Param('company') company: string, @Param('position') position: string) {
    const bank = await this.companyBankModel.findOne({ company, position }).exec()
    if (!bank) return { company, position, questions: [], contributionCount: 0 }

    bank.viewCount += 1
    await bank.save()

    return {
      company: bank.company,
      position: bank.position,
      questions: bank.questions.sort((a, b) => b.frequency - a.frequency),
      contributionCount: bank.contributionCount,
      viewCount: bank.viewCount,
    }
  }

  @Get('company/:company')
  async getCompanyBanks(@Param('company') company: string) {
    const banks = await this.companyBankModel.find({ company }).exec()
    return banks.map(b => ({
      position: b.position,
      questionCount: b.questions.length,
      contributionCount: b.contributionCount,
    }))
  }

  @Get('my')
  async getMyContributions(@CurrentUser('userId') userId: string) {
    return this.contributionModel
      .find({ userId })
      .sort({ createdAt: -1 })
      .select('company position rounds experience createdAt')
      .exec()
  }

  @Public()
  @Get('companies/hot')
  async getHotCompanies() {
    const banks = await this.companyBankModel.aggregate([
      { $group: { _id: '$company', positionCount: { $sum: 1 }, totalContributions: { $sum: '$contributionCount' } } },
      { $sort: { totalContributions: -1, positionCount: -1 } },
      { $project: { _id: 0, name: '$_id', positionCount: 1 } },
    ]).exec()

    if (banks.length > 0) return banks

    const DEFAULT_COMPANIES = ['腾讯', '字节跳动', '阿里巴巴', '美团', '百度', '京东', '网易', '小红书']
    return DEFAULT_COMPANIES.map((name, i) => ({ name, positionCount: 0, sort: i }))
  }
}