/**
 * student-bff Mock 数据提供器.
 *
 * 仲裁依据:
 *   - workline §5.2 (Mock 策略: env.MOCK_UPSTREAM=true 时返回固定数据)
 *   - matrix.md §7 (全并行 Mock 策略: 上游未就绪时拦截)
 *
 * 当 env.MOCK_UPSTREAM=true 时, DownstreamClient 调用 MockDataProvider 获取固定数据,
 * 上游服务就绪后设置 MOCK_UPSTREAM=false 即可切换真实调用.
 *
 * Mock 数据覆盖:
 *   - iam: GetUserInfo / GetEffectivePermissions / GetViewports
 *   - core-edu: HomeworkService / ExamService / GradeService / ClassService
 *   - content: TextbookService / ChapterService / QuestionService / KnowledgeGraphService
 *   - data-ana: AnalyticsService (GetStudentWeakness / GetLearningTrend)
 *   - msg: NotificationService
 *   - ai: AiService
 */
import type { MockDataProvider } from "@edu/shared-ts/bff";
import { logger } from "../shared/observability/logger.js";

/**
 * 学生 Mock 数据 (固定 ID 便于前端联调).
 */
const MOCK_STUDENT_ID = "u-stu-001";
const MOCK_CLASS_ID = "c-001";

/**
 * Mock 数据提供器实现.
 */
export const studentBffMockProvider: MockDataProvider = (
  service,
  method,
  request,
) => {
  logger.debug({ service, method, request }, "Mock data request");

  switch (service) {
    case "iam":
      return mockIam(method, request);
    case "core-edu":
      return mockCoreEdu(method, request);
    case "content":
      return mockContent(method, request);
    case "data-ana":
      return mockDataAna(method, request);
    case "msg":
      return mockMsg(method, request);
    case "ai":
      return mockAi(method, request);
    default:
      return undefined;
  }
};

function mockIam(method: string, _request: unknown): unknown {
  switch (method) {
    case "GetUserInfo":
      return {
        userId: MOCK_STUDENT_ID,
        email: "li.tongxue@example.com",
        name: "李同学",
        avatar: null,
        roles: ["student"],
        classId: MOCK_CLASS_ID,
        className: "高一(1)班",
        grade: "高一",
      };
    case "GetEffectivePermissions":
      return {
        userId: MOCK_STUDENT_ID,
        permissions: [
          "STUDENT_DASHBOARD_READ",
          "STUDENT_EXAM_READ",
          "STUDENT_HOMEWORK_READ",
          "STUDENT_HOMEWORK_SUBMIT",
          "STUDENT_GRADE_READ",
          "STUDENT_CONTENT_READ",
          "STUDENT_ANALYTICS_READ",
          "STUDENT_NOTIFICATION_READ",
          "STUDENT_AI_CHAT",
        ],
      };
    case "GetViewports":
      return {
        userId: MOCK_STUDENT_ID,
        navigation: [
          { key: "dashboard", label: "首页", route: "/student/dashboard", sortOrder: 1 },
          { key: "homework", label: "我的作业", route: "/student/homework", sortOrder: 2 },
          { key: "grades", label: "我的成绩", route: "/student/grades", sortOrder: 3 },
          { key: "exams", label: "考试", route: "/student/exams", sortOrder: 4 },
          { key: "content", label: "教材", route: "/student/textbooks", sortOrder: 5 },
          { key: "analytics", label: "学情诊断", route: "/student/analytics", sortOrder: 6 },
          { key: "ai", label: "AI 答疑", route: "/student/ai", sortOrder: 7 },
        ],
        dataScope: {
          showHistoryGrades: true,
          showClassRanking: false,
          enableAIChat: true,
        },
      };
    case "GetChildrenByParent":
      // 学生场景不调用, 返回空
      return { children: [] };
    default:
      return undefined;
  }
}

function mockCoreEdu(method: string, request: unknown): unknown {
  switch (method) {
    case "ListHomeworkByClass":
    case "ListHomeworkByStudent":
      return {
        homework: [
          {
            id: "h-001",
            title: "数学作业第三章",
            classId: MOCK_CLASS_ID,
            subject: "数学",
            dueDate: "2026-07-15T23:59:59Z",
            status: "pending",
            questions: [
              { id: "q-001", type: "short_answer", content: "求 x²+2x+1=0 的解" },
              { id: "q-002", type: "essay", content: "解释二次方程求根公式" },
            ],
          },
          {
            id: "h-002",
            title: "物理作业: 力学基础",
            classId: MOCK_CLASS_ID,
            subject: "物理",
            dueDate: "2026-07-18T23:59:59Z",
            status: "submitted",
            submissionId: "sub-001",
          },
        ],
      };
    case "GetHomework":
      return {
        id: "h-001",
        title: "数学作业第三章",
        classId: MOCK_CLASS_ID,
        subject: "数学",
        dueDate: "2026-07-15T23:59:59Z",
        status: "pending",
        questions: [
          { id: "q-001", type: "short_answer", content: "求 x²+2x+1=0 的解" },
          { id: "q-002", type: "essay", content: "解释二次方程求根公式" },
        ],
      };
    case "SubmitHomework":
      return {
        submissionId: "sub-" + Date.now(),
        homeworkId: (request as { homeworkId?: string })?.homeworkId ?? "h-001",
        submittedAt: new Date().toISOString(),
        status: "submitted",
      };
    case "ListExamsByClass":
      return {
        exams: [
          {
            id: "e-001",
            title: "期中考试",
            classId: MOCK_CLASS_ID,
            subject: "综合",
            examDate: "2026-07-25T09:00:00Z",
            duration: 120,
            location: "教学楼 A301",
            status: "upcoming",
          },
          {
            id: "e-002",
            title: "数学单元测试",
            classId: MOCK_CLASS_ID,
            subject: "数学",
            examDate: "2026-07-20T14:00:00Z",
            duration: 90,
            location: "教学楼 B201",
            status: "upcoming",
          },
        ],
      };
    case "ListGradesByStudent":
      return {
        grades: [
          {
            id: "g-001",
            studentId: MOCK_STUDENT_ID,
            examId: "e-003",
            examTitle: "月考",
            subject: "数学",
            score: 92,
            maxScore: 100,
            gradedAt: "2026-07-01T15:00:00Z",
            feedback: "解题思路清晰, 步骤完整",
            rank: 5,
          },
          {
            id: "g-002",
            studentId: MOCK_STUDENT_ID,
            examId: "e-004",
            examTitle: "物理测验",
            subject: "物理",
            score: 85,
            maxScore: 100,
            gradedAt: "2026-07-03T10:00:00Z",
            feedback: "力学基础掌握良好",
            rank: 12,
          },
        ],
        totalCount: 2,
      };
    case "GetClassesByStudent":
      return {
        classes: [
          {
            id: MOCK_CLASS_ID,
            name: "高一(1)班",
            grade: "高一",
            homeroomTeacher: { id: "u-tch-001", name: "王老师" },
            subjects: ["数学", "物理", "化学", "语文", "英语"],
          },
        ],
      };
    default:
      return undefined;
  }
}

function mockContent(method: string, _request: unknown): unknown {
  switch (method) {
    case "ListTextbooks":
      return {
        textbooks: [
          { id: "tb-001", title: "高一数学(上)", grade: "高一", subject: "数学", version: "人教版" },
          { id: "tb-002", title: "高一物理(上)", grade: "高一", subject: "物理", version: "人教版" },
        ],
      };
    case "ListChapters":
      return {
        chapters: [
          { id: "ch-001", textbookId: "tb-001", title: "第一章 集合与函数", sortOrder: 1 },
          { id: "ch-002", textbookId: "tb-001", title: "第二章 基本初等函数", sortOrder: 2 },
        ],
      };
    case "GetLearningPath":
      return {
        knowledgePointId: "kp-001",
        path: [
          { id: "kp-001", title: "二次方程", mastery: 0.6, recommended: true },
          { id: "kp-002", title: "因式分解", mastery: 0.8, recommended: false },
        ],
      };
    default:
      return undefined;
  }
}

function mockDataAna(method: string, _request: unknown): unknown {
  switch (method) {
    case "GetStudentWeakness":
      return {
        studentId: MOCK_STUDENT_ID,
        weakPoints: [
          { knowledgePointId: "kp-001", title: "二次方程", mastery: 0.4, trend: "declining" },
          { knowledgePointId: "kp-003", title: "三角函数", mastery: 0.55, trend: "stable" },
        ],
        summary: "数学代数基础薄弱, 建议加强二次方程练习",
      };
    case "GetLearningTrend":
      return {
        studentId: MOCK_STUDENT_ID,
        range: "30d",
        points: [
          { date: "2026-06-10", mastery: 0.55, studyMinutes: 120 },
          { date: "2026-06-20", mastery: 0.62, studyMinutes: 180 },
          { date: "2026-07-01", mastery: 0.68, studyMinutes: 210 },
        ],
        trend: "improving",
      };
    case "GetStudentDashboard":
      return {
        studentId: MOCK_STUDENT_ID,
        overallMastery: 0.68,
        weakPointCount: 2,
        studyMinutesLast7d: 840,
        upcomingExams: 2,
      };
    default:
      return undefined;
  }
}

function mockMsg(method: string, _request: unknown): unknown {
  switch (method) {
    case "ListNotifications":
      return {
        notifications: [
          {
            id: "n-001",
            userId: MOCK_STUDENT_ID,
            type: "homework.graded",
            title: "作业批改完成",
            content: "你的数学作业已批改, 得分 92/100",
            read: false,
            createdAt: "2026-07-09T10:00:00Z",
          },
          {
            id: "n-002",
            userId: MOCK_STUDENT_ID,
            type: "exam.published",
            title: "新考试发布",
            content: "期中考试将于 7月25日 举行",
            read: false,
            createdAt: "2026-07-08T15:00:00Z",
          },
        ],
        totalCount: 2,
        unreadCount: 2,
      };
    case "MarkNotificationAsRead":
      return { success: true, notificationId: "n-001", readAt: new Date().toISOString() };
    default:
      return undefined;
  }
}

function mockAi(method: string, _request: unknown): unknown {
  switch (method) {
    case "Chat":
      return {
        response: "好的, 让我帮你分析这道题. x²+2x+1=0 是完全平方式, 可以写成 (x+1)²=0, 所以 x=-1.",
        model: "gpt-4o-mini",
        usage: { promptTokens: 120, completionTokens: 50, totalTokens: 170 },
      };
    case "StreamChat":
      // mock 流式响应: 返回单个 chunk (DownstreamClient.callStream mock 模式产出 1 个 chunk 后结束)
      return {
        content: "好的, 让我帮你分析这道题. x²+2x+1=0 是完全平方式, 可以写成 (x+1)²=0, 所以 x=-1.",
        done: true,
        model: "gpt-4o-mini",
        usage: { promptTokens: 120, completionTokens: 50, totalTokens: 170 },
      };
    default:
      return undefined;
  }
}
