import type { EventHandler, EventContext } from "./event-handler.js";
import { invalidateCache } from "../../../aggregation/fallback-strategy.js";
import { CacheKeys } from "../../cache/cache-key.builder.js";
import { logger } from "../../observability/logger.js";

/**
 * 缓存失效事件处理器（对齐 02-architecture-design.md §5.2 + workline P5.4）。
 *
 * 处理教学事件（成绩/作业/考试），失效对应缓存：
 *
 * | Topic                          | 失效缓存                              |
 * |--------------------------------|---------------------------------------|
 * | edu.notification.read          | bff:parent:notifications:*            |
 * | edu.notification.recalled      | bff:parent:notifications:*            |
 * | edu.teaching.grade.recorded    | bff:parent:grades:{childId}:* + dashboard |
 * | edu.teaching.homework.graded   | bff:parent:homework:{childId}:* + dashboard |
 * | edu.teaching.exam.published    | bff:parent:exams:{childId}:* + dashboard |
 */

interface TeachingEventBody {
  studentId?: string;
  childId?: string;
  classId?: string;
  parentId?: string;
}

export class CacheInvalidationHandler implements EventHandler<TeachingEventBody> {
  async handle(ctx: EventContext<TeachingEventBody>): Promise<void> {
    const { topic, body } = ctx;
    const childId = body.childId ?? body.studentId;
    const parentId = body.parentId;

    logger.info(
      { topic, childId, parentId },
      "Processing cache invalidation event",
    );

    switch (topic) {
      case "edu.notification.read":
      case "edu.notification.recalled":
        if (parentId) {
          await invalidateCache(CacheKeys.notifications(parentId, 1));
        }
        break;

      case "edu.teaching.grade.recorded":
        if (childId) {
          await invalidateCache(CacheKeys.grades(childId, 1));
        }
        if (parentId) {
          await invalidateCache(CacheKeys.dashboard(parentId));
        }
        break;

      case "edu.teaching.homework.graded":
        if (childId && body.classId) {
          await invalidateCache(CacheKeys.homework(childId, body.classId));
        }
        if (parentId) {
          await invalidateCache(CacheKeys.dashboard(parentId));
        }
        break;

      case "edu.teaching.exam.published":
        if (childId && body.classId) {
          await invalidateCache(CacheKeys.exams(childId, body.classId));
        }
        if (parentId) {
          await invalidateCache(CacheKeys.dashboard(parentId));
        }
        break;

      default:
        logger.warn({ topic }, "CacheInvalidationHandler: unknown topic");
    }
  }
}
