import type { ClassScheduleItem } from '../api';

export const WEEK_DAYS = ['Thứ 2', 'Thứ 3', 'Thứ 4', 'Thứ 5', 'Thứ 6', 'Thứ 7', 'Chủ Nhật'] as const;
export const PERIODS = [1, 2, 3, 4] as const;

export interface ActiveClassItem {
  rkId: number;
  name: string;
  classCode: string;
  type?: string;
  studentCount?: number;
  specializeName?: string;
  systemName?: string;
  schedules?: ClassScheduleItem[];
  allowedApps?: string;
}

export function getDayLabel(day: number): string {
  return WEEK_DAYS[day] ?? `Ngày ${day}`;
}

/** Thứ 2 = 0 … Chủ nhật = 6 */
export function getTodayDayOfWeek(): number {
  const js = new Date().getDay();
  return js === 0 ? 6 : js - 1;
}

/** Ca có dữ liệu hiển thị (có giờ hoặc môn) — kể cả ca template chưa bật */
export function isScheduleVisible(s: ClassScheduleItem): boolean {
  return Boolean(s.startTime?.trim() || s.courseName?.trim());
}

export function filterActiveClasses(
  classes: ActiveClassItem[],
  query: string,
  dayFilter: number | null
): ActiveClassItem[] {
  const q = query.trim().toLowerCase();
  return classes.filter(cls => {
    if (dayFilter !== null) {
      const hasDay = (cls.schedules || []).some(
        s => s.dayOfWeek === dayFilter && isScheduleVisible(s)
      );
      if (!hasDay) return false;
    }
    if (!q) return true;
    const haystack = [
      cls.name,
      cls.classCode,
      cls.specializeName,
      cls.systemName,
      cls.type,
      ...(cls.schedules || []).map(s => `${s.courseName} ${s.startTime} ${s.endTime}`),
    ]
      .filter(Boolean)
      .join(' ')
      .toLowerCase();
    return haystack.includes(q);
  });
}

export function countWeeklyShifts(classes: ActiveClassItem[]): number {
  return classes.reduce(
    (sum, cls) => sum + (cls.schedules || []).filter(isScheduleVisible).length,
    0
  );
}

export function classHasToday(cls: ActiveClassItem): boolean {
  const today = getTodayDayOfWeek();
  return (cls.schedules || []).some(s => s.dayOfWeek === today && isScheduleVisible(s) && s.isActive !== false);
}

export function schedulesByDay(cls: ActiveClassItem): Map<number, ClassScheduleItem[]> {
  const map = new Map<number, ClassScheduleItem[]>();
  for (const s of cls.schedules || []) {
    if (!isScheduleVisible(s)) continue;
    const list = map.get(s.dayOfWeek) || [];
    list.push(s);
    map.set(s.dayOfWeek, list);
  }
  for (const [, list] of map) {
    list.sort((a, b) => (a.period || 1) - (b.period || 1));
  }
  return map;
}

const CLASS_COLORS = [
  '#c62828',
  '#1565c0',
  '#2e7d32',
  '#6a1b9a',
  '#ef6c00',
  '#00838f',
  '#ad1457',
  '#4527a0',
];

export function classAccentColor(classCode: string): string {
  let hash = 0;
  for (let i = 0; i < classCode.length; i++) {
    hash = classCode.charCodeAt(i) + ((hash << 5) - hash);
  }
  return CLASS_COLORS[Math.abs(hash) % CLASS_COLORS.length];
}

export interface TimetableCellEntry {
  cls: ActiveClassItem;
  schedule: ClassScheduleItem;
}

export function buildTimetableMap(
  classes: ActiveClassItem[]
): Map<string, TimetableCellEntry[]> {
  const map = new Map<string, TimetableCellEntry[]>();
  for (const cls of classes) {
    for (const s of cls.schedules || []) {
      if (!isScheduleVisible(s)) continue;
      const key = `${s.dayOfWeek}-${s.period || 1}`;
      const list = map.get(key) || [];
      list.push({ cls, schedule: s });
      map.set(key, list);
    }
  }
  for (const [, list] of map) {
    list.sort((a, b) => a.cls.classCode.localeCompare(b.cls.classCode));
  }
  return map;
}
