import { computed, ComputedRef } from 'vue';
import { Clazz, ClazzRepeatRow } from '~/types';

export interface NormalizedClazzEvent {
  id: string;
  rootId?: string;
  clazzName: string;
  startAt: Date;
  endAt: Date;
  durationMinutes: number;
  teacherId: string;
  teacherName?: string;
  studentIds: string[];
  studentNames: string[];
  isRepeatGhost: boolean;
  isSubsidiary: boolean;
  subsidiaryTeacherId?: string;
  visible: boolean;
  color?: string;
  borderColor?: string;
  /** Raw days-of-week expanded from a repeat row */
  __raw: Clazz | ClazzRepeatRow;
  /** 日期键 YYYY-MM-DD */
  dateKey: string;
  /** 时段键 HH:mm，按课程真实开始时间生成 */
  timeSlotKey: string;
}

function toDate(v: string | Date): Date {
  return typeof v === 'string' ? new Date(v) : v;
}

/** 将 ISO 日期时间字符串转为 YYYY-MM-DD */
function dateKey(d: string | Date): string {
  const dt = toDate(d);
  return `${dt.getFullYear()}-${String(dt.getMonth() + 1).padStart(2, '0')}-${String(dt.getDate()).padStart(2, '0')}`;
}

function timeSlotKey(d: Date): string {
  return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
}

function pickNames(item: Clazz) {
  const teachers = item.teachers?.val?.users?.vals ?? [];
  const students = item.students?.val?.users?.vals ?? [];
  return {
    teacherUserId: teachers[0]?.user_id ?? '',
    teacherName: teachers[0]?.real_name ?? '',
    studentIds: students.map((u) => u.user_id),
    studentNames: students.map((u) => u.real_name).filter(Boolean),
  };
}

function makeEvent(
  item: Clazz,
  isRepeatGhost: boolean,
  isSubsidiary: boolean,
  extra?: Partial<NormalizedClazzEvent>,
): NormalizedClazzEvent {
  const startAt = toDate(item.start_from);
  const endAt = toDate(item.end_by);
  const names = pickNames(item);
  return {
    id: item.id,
    rootId: item.root_id,
    clazzName: item.clazz_name,
    startAt,
    endAt,
    durationMinutes: item.duration ?? 0,
    teacherId: names.teacherUserId,
    teacherName: names.teacherName,
    studentIds: names.studentIds,
    studentNames: names.studentNames,
    isRepeatGhost,
    isSubsidiary,
    subsidiaryTeacherId: extra?.subsidiaryTeacherId,
    visible: extra?.visible ?? true,
    color: extra?.color,
    borderColor: extra?.borderColor,
    __raw: item,
    dateKey: dateKey(startAt),
    timeSlotKey: timeSlotKey(startAt),
  };
}

export function useClazzViewModel(params: {
  list: ComputedRef<Clazz[]>;
  repeatList: ComputedRef<ClazzRepeatRow[]>;
  subsidiaryClazzByHtyId: ComputedRef<Record<string, { list: Clazz[]; repeatList: ClazzRepeatRow[] }>>;
  /** Getter 避免 TDZ hoisting 问题 */
  getViewingSubsidiaries: () => string[];
  /** 下属老师颜色映射，htyId → 颜色 */
  getSubsidiaryColor?: (htyId: string) => string | undefined;
}) {
  const { list, repeatList, subsidiaryClazzByHtyId, getViewingSubsidiaries, getSubsidiaryColor } = params;

  /** 扁平化的标准化事件列表 */
  const normalizedEvents = computed<NormalizedClazzEvent[]>(() => {
    const out: NormalizedClazzEvent[] = [];

    // 自己的非重复排课
    for (const item of list.value) {
      if (item.is_delete) continue;
      out.push(makeEvent(item, false, false));
    }

    // 自己的重复排课（幽灵实例 root）
    for (const row of repeatList.value) {
      if (row.is_delete) continue;

      out.push(makeEvent(row, true, false));
      // 当周实例（如果有）
      if (row.instance && row.instance.id) {
        out.push(makeEvent(row.instance, false, false));
      }
    }

    // 下属老师的排课
    for (const [htyId, data] of Object.entries(subsidiaryClazzByHtyId.value)) {
      const hidden = !getViewingSubsidiaries().includes(htyId);
      const color = getSubsidiaryColor?.(htyId);
      for (const item of data.list) {
        if (item.is_delete) continue;
        out.push(makeEvent(item, false, true, { subsidiaryTeacherId: htyId, visible: !hidden, color }));
      }
      for (const row of data.repeatList) {
        if (row.is_delete) continue;
        out.push(makeEvent(row, true, true, { subsidiaryTeacherId: htyId, visible: !hidden, color }));
        if (row.instance && row.instance.id) {
          out.push(makeEvent(row.instance, false, true, { subsidiaryTeacherId: htyId, visible: !hidden, color }));
        }
      }
    }

    return out;
  });

  /** 按 (dateKey, timeSlotKey) 分组的课程 */
  const eventsBySlot = computed(() => {
    const map: Record<string, Record<string, NormalizedClazzEvent[]>> = {};
    for (const ev of normalizedEvents.value) {
      if (!ev.visible) continue;
      if (!map[ev.dateKey]) map[ev.dateKey] = {};
      if (!map[ev.dateKey][ev.timeSlotKey]) map[ev.dateKey][ev.timeSlotKey] = [];
      map[ev.dateKey][ev.timeSlotKey].push(ev);
    }
    return map;
  });

  return { normalizedEvents, eventsBySlot };
}
