// MSW handlers：parent-bff GraphQL + iam REST mock
// 依据：
// - 02-architecture-design.md §8 MSW 模拟未就绪上游
// - F9 GraphQL（查询走 GraphQL）
// - ISSUE-004 登录走 REST
// - ISSUE-010 iam GetChildrenByParent P0 阻塞 → myChildren 返回 mock
// - ISSUE-033 通知偏好 P4 localStorage 降级 → updateNotificationPreferences 仍 mock 200

import { http, HttpResponse, graphql } from "msw";
import type { ActionState, LoginResponse, LeaveRequestInput } from "@/types";
import {
  mockParent,
  mockChildren,
  mockChildSummary,
  mockGradeDataPoints,
  mockAttendance,
  mockHomework,
  mockWeakness,
  mockLearningTrend,
  mockExams,
  mockExamResult,
  mockClasses,
  mockLearningPath,
  mockNotifications,
  mockNotificationPreferences,
  mockLoginResponse,
  mockLeaveRequests,
  mockAcademicYears,
  mockReportCard,
  mockErrorBookStats,
  mockTopWrongQuestions,
  mockWeakKps,
  mockMasterySummary,
  mockDiagnosticReports,
  mockPracticeStats,
  mockPracticeSessions,
  mockCoursePlans,
  mockCoursePlanDetail,
  mockLessonPlans,
  mockLessonPlanDetail,
  mockElectiveSelections,
  mockChildDetail,
  mockGrowthArchive,
  mockExportResult,
} from "./fixtures";

// ===== REST handlers（iam login/refresh，ISSUE-004）=====
// ARB-022 §24.4：双 /v1 前缀，/api/v1/iam/v1/login + /api/v1/iam/v1/refresh
const restHandlers = [
  http.post("/api/v1/iam/v1/login", async ({ request }) => {
    const body = (await request.json()) as { email: string; password: string };
    // mock：任意 parent@example.com / password 通过
    if (body.email === "parent@example.com" && body.password === "password") {
      const res: ActionState<LoginResponse> = {
        success: true,
        data: mockLoginResponse,
      };
      return HttpResponse.json(res);
    }
    const err: ActionState<never> = {
      success: false,
      error: {
        code: "IAM_INVALID_CREDENTIALS",
        message: "邮箱或密码错误",
      },
    };
    return HttpResponse.json(err, { status: 401 });
  }),

  http.post("/api/v1/iam/v1/refresh", async ({ request }) => {
    const body = (await request.json()) as { refreshToken: string };
    if (body.refreshToken === "mock-refresh-token-parent-001") {
      const res: ActionState<{ tokens: LoginResponse["tokens"] }> = {
        success: true,
        data: {
          tokens: {
            accessToken: "mock-access-token-parent-001-renewed",
            refreshToken: "mock-refresh-token-parent-001-renewed",
            expiresIn: 3600,
          },
        },
      };
      return HttpResponse.json(res);
    }
    return HttpResponse.json(
      {
        success: false,
        error: { code: "IAM_INVALID_REFRESH", message: "refresh token 无效" },
      },
      { status: 401 },
    );
  }),
];

// ===== GraphQL handlers（parent-bff，F9）=====
const graphqlHandlers = [
  graphql.query("CurrentUser", () => {
    return HttpResponse.json({
      data: {
        currentUser: mockParent,
      },
    });
  }),

  graphql.query("MyChildren", () => {
    return HttpResponse.json({
      data: {
        myChildren: mockChildren,
      },
    });
  }),

  graphql.query("ChildSummary", ({ variables }) => {
    const childId = variables.childId as string;
    return HttpResponse.json({
      data: {
        childSummary: { ...mockChildSummary, childId },
      },
    });
  }),

  graphql.query("ChildGrades", () => {
    return HttpResponse.json({
      data: {
        childGrades: mockGradeDataPoints,
      },
    });
  }),

  graphql.query("ChildAttendance", () => {
    return HttpResponse.json({
      data: {
        childAttendance: mockAttendance,
      },
    });
  }),

  graphql.query("ChildHomework", () => {
    return HttpResponse.json({
      data: {
        childHomework: mockHomework,
      },
    });
  }),

  graphql.query("ChildWeakness", () => {
    return HttpResponse.json({
      data: {
        childWeakness: mockWeakness,
      },
    });
  }),

  graphql.query("ChildTrend", ({ variables }) => {
    return HttpResponse.json({
      data: {
        childTrend: {
          ...mockLearningTrend,
          childId: variables.childId as string,
        },
      },
    });
  }),

  graphql.query("ChildExams", () => {
    return HttpResponse.json({
      data: {
        childExams: mockExams,
      },
    });
  }),

  graphql.query("ChildExamResult", ({ variables }) => {
    const examId = variables.examId as string;
    return HttpResponse.json({
      data: {
        childExamResult: { ...mockExamResult, examId },
      },
    });
  }),

  graphql.query("ChildClasses", () => {
    return HttpResponse.json({
      data: {
        childClasses: mockClasses,
      },
    });
  }),

  graphql.query("ChildLearningPath", () => {
    return HttpResponse.json({
      data: {
        childLearningPath: mockLearningPath,
      },
    });
  }),

  graphql.query("CurrentParentDetail", () => {
    return HttpResponse.json({
      data: {
        currentUser: mockParent,
      },
    });
  }),

  graphql.query("MyNotifications", () => {
    return HttpResponse.json({
      data: {
        myNotifications: mockNotifications,
      },
    });
  }),

  graphql.query("MyNotificationPreferences", () => {
    return HttpResponse.json({
      data: {
        myNotificationPreferences: mockNotificationPreferences,
      },
    });
  }),

  graphql.mutation("MarkAsRead", ({ variables }) => {
    const notificationId = variables.notificationId as string;
    return HttpResponse.json({
      data: {
        markAsRead: { id: notificationId, read: true },
      },
    });
  }),

  graphql.mutation("MarkAllAsRead", () => {
    return HttpResponse.json({
      data: {
        markAllAsRead: { count: mockNotifications.length },
      },
    });
  }),

  // ISSUE-033：P4 localStorage 降级，但仍 mock 返回 200（前端优先用 localStorage）
  graphql.mutation("UpdateNotificationPreferences", ({ variables }) => {
    return HttpResponse.json({
      data: {
        updateNotificationPreferences: {
          parentId: (variables as { parentId: string }).parentId,
          updatedAt: new Date().toISOString(),
        },
      },
    });
  }),

  // ARB-020 §22.5：switchChild Mutation（后端审计记录）
  graphql.mutation("SwitchChild", ({ variables }) => {
    const childId = variables.childId as string;
    const child = mockChildren.find((c) => c.id === childId);
    return HttpResponse.json({
      data: {
        switchChild: {
          childId,
          childName: child?.name ?? "未知",
          selectedAt: new Date().toISOString(),
        },
      },
    });
  }),

  // ===== 参考项目差距补齐：请假 / 报告卡 / 错题本 / 诊断 / 练习 / 课程 / 备课 / 选修 / 子女详情 =====

  // ----- 请假 -----
  graphql.query("ChildLeaveRequests", ({ variables }) => {
    const childId = variables.childId as string;
    return HttpResponse.json({
      data: {
        childLeaveRequests: mockLeaveRequests.filter((l) => l.childId === childId),
      },
    });
  }),

  graphql.mutation("CreateLeaveRequest", ({ variables }) => {
    const input = variables.input as LeaveRequestInput;
    const child = mockChildren.find((c) => c.id === input.childId);
    const newLeave = {
      id: `leave-${Date.now()}`,
      childId: input.childId,
      childName: child?.name,
      className: child?.className,
      type: input.type,
      startDate: input.startDate,
      endDate: input.endDate,
      reason: input.reason,
      status: "pending" as const,
      submittedAt: new Date().toISOString(),
    };
    return HttpResponse.json({
      data: {
        createLeaveRequest: newLeave,
      },
    });
  }),

  // ----- 报告卡 -----
  graphql.query("AcademicYears", () => {
    return HttpResponse.json({
      data: {
        academicYears: mockAcademicYears,
      },
    });
  }),

  graphql.query("ChildReportCard", ({ variables }) => {
    const childId = variables.childId as string;
    return HttpResponse.json({
      data: {
        childReportCard: { ...mockReportCard, childId },
      },
    });
  }),

  // ----- 错题本 -----
  graphql.query("ChildErrorBookStats", ({ variables }) => {
    const childId = variables.childId as string;
    return HttpResponse.json({
      data: {
        childErrorBookStats: { ...mockErrorBookStats, childId },
      },
    });
  }),

  graphql.query("ChildTopWrongQuestions", ({ variables }) => {
    const limit = variables.limit as number | undefined;
    const list =
      typeof limit === "number" && limit > 0
        ? mockTopWrongQuestions.slice(0, limit)
        : mockTopWrongQuestions;
    return HttpResponse.json({
      data: {
        childTopWrongQuestions: list,
      },
    });
  }),

  graphql.query("ChildWeakKps", ({ variables }) => {
    const limit = variables.limit as number | undefined;
    const list =
      typeof limit === "number" && limit > 0
        ? mockWeakKps.slice(0, limit)
        : mockWeakKps;
    return HttpResponse.json({
      data: {
        childWeakKps: list,
      },
    });
  }),

  // ----- 诊断报告 -----
  graphql.query("ChildMasterySummary", ({ variables }) => {
    const childId = variables.childId as string;
    return HttpResponse.json({
      data: {
        childMasterySummary: { ...mockMasterySummary, childId },
      },
    });
  }),

  graphql.query("ChildDiagnosticReports", ({ variables }) => {
    const childId = variables.childId as string;
    return HttpResponse.json({
      data: {
        childDiagnosticReports: mockDiagnosticReports.map((r) => ({
          ...r,
          childId,
        })),
      },
    });
  }),

  // ----- 练习统计 -----
  graphql.query("ChildPracticeStats", ({ variables }) => {
    const childId = variables.childId as string;
    return HttpResponse.json({
      data: {
        childPracticeStats: { ...mockPracticeStats, childId },
      },
    });
  }),

  graphql.query("ChildPracticeSessions", ({ variables }) => {
    const childId = variables.childId as string;
    const limit = variables.limit as number | undefined;
    const list =
      typeof limit === "number" && limit > 0
        ? mockPracticeSessions.slice(0, limit)
        : mockPracticeSessions;
    return HttpResponse.json({
      data: {
        childPracticeSessions: list.map((s) => ({ ...s, childId })),
      },
    });
  }),

  // ----- 课程计划 -----
  graphql.query("ChildCoursePlans", () => {
    return HttpResponse.json({
      data: {
        childCoursePlans: mockCoursePlans,
      },
    });
  }),

  graphql.query("ChildCoursePlanDetail", ({ variables }) => {
    const planId = variables.planId as string;
    const detail =
      planId === mockCoursePlanDetail.id
        ? mockCoursePlanDetail
        : { ...mockCoursePlanDetail, id: planId };
    return HttpResponse.json({
      data: {
        childCoursePlanDetail: detail,
      },
    });
  }),

  // ----- 备课计划 -----
  graphql.query("ChildLessonPlans", () => {
    return HttpResponse.json({
      data: {
        childLessonPlans: mockLessonPlans,
      },
    });
  }),

  graphql.query("ChildLessonPlanDetail", ({ variables }) => {
    const planId = variables.planId as string;
    const detail =
      planId === mockLessonPlanDetail.id
        ? mockLessonPlanDetail
        : { ...mockLessonPlanDetail, id: planId };
    return HttpResponse.json({
      data: {
        childLessonPlanDetail: detail,
      },
    });
  }),

  // ----- 选修课 -----
  graphql.query("ChildElective", ({ variables }) => {
    const childId = variables.childId as string;
    return HttpResponse.json({
      data: {
        childElective: mockElectiveSelections.filter((e) => e.childId === childId),
      },
    });
  }),

  // ----- 子女详情聚合 -----
  graphql.query("ChildDetail", ({ variables }) => {
    const childId = variables.childId as string;
    return HttpResponse.json({
      data: {
        childDetail: { ...mockChildDetail, childId },
      },
    });
  }),

  // ----- 成长档案（班级均对比线）-----
  graphql.query("ChildGrowthArchive", ({ variables }) => {
    const childId = variables.childId as string;
    const subject = (variables.subject as string | undefined) ?? null;
    return HttpResponse.json({
      data: {
        childGrowthArchive: {
          ...mockGrowthArchive,
          childId,
          subject: subject ?? mockGrowthArchive.subject,
        },
      },
    });
  }),

  // ----- 导出成绩 -----
  graphql.mutation("ExportChildGrades", ({ variables }) => {
    const childId = variables.childId as string;
    const subject = (variables.subject as string | undefined) ?? null;
    return HttpResponse.json({
      data: {
        exportChildGrades: {
          ...mockExportResult,
          downloadUrl: `https://example.com/exports/grades-${childId}${
            subject ? `-${subject}` : ""
          }-2026-07-13.xlsx`,
        },
      },
    });
  }),
];

export const handlers = [...restHandlers, ...graphqlHandlers];
