export type SystemSection = 'organization' | 'network' | 'templates' | 'seating';

export type TabId = 'dashboard' | 'classes' | 'students' | 'learning' | 'exams' | 'system' | 'profile' | 'student-affairs' | 'applications';

export interface NavEntry {
  id: string;
  kind: 'tab' | 'class' | 'exam';
  tab: TabId;
  classId?: number;
  examId?: number;
  systemSection?: SystemSection;
  label: string;
  timestamp: number;
}

export const SYSTEM_SECTION_LABELS: Record<SystemSection, string> = {
  organization: 'Tổ chức',
  network: 'Gói mạng',
  templates: 'Khung ứng dụng',
  seating: 'Sơ đồ chỗ ngồi',
};

export const TAB_LABELS: Record<TabId, string> = {
  dashboard: 'Tổng quan',
  classes: 'Lớp học',
  students: 'Sinh viên',
  learning: 'Giám sát & Lịch học',
  exams: 'Phòng thi',
  system: 'Hệ thống',
  profile: 'Tài khoản của tôi',
  'student-affairs': 'Công Tác Sinh Viên',
  applications: 'Ứng Dụng',
};

const HISTORY_KEY = 'sc_nav_history';
const MAX_HISTORY = 10;

function isTabId(value: string | null): value is TabId {
  return (
    value === 'dashboard' ||
    value === 'classes' ||
    value === 'students' ||
    value === 'learning' ||
    value === 'exams' ||
    value === 'system' ||
    value === 'profile' ||
    value === 'student-affairs' ||
    value === 'applications'
  );
}

function isSystemSection(value: string | null): value is SystemSection {
  return value === 'organization' || value === 'network' || value === 'templates' || value === 'seating';
}

function resolveTabAndSection(tabParam: string | null): { tab: TabId; systemSection: SystemSection } {
  if (tabParam === 'email-domains' || tabParam === 'accounts') {
    return { tab: 'system', systemSection: 'organization' };
  }
  if (tabParam === 'network') {
    return { tab: 'system', systemSection: 'network' };
  }
  const tab: TabId = isTabId(tabParam) ? tabParam : 'dashboard';
  const params = new URLSearchParams(window.location.search);
  const secParam = params.get('section');
  let systemSection: SystemSection = 'organization';
  if (isSystemSection(secParam)) {
    systemSection = secParam;
  }
  return { tab, systemSection };
}

export function parseRoute(): {
  tab: TabId;
  classId: number | null;
  examId: number | null;
  systemSection: SystemSection;
} {
  const params = new URLSearchParams(window.location.search);
  const tabParam = params.get('tab');
  const { tab, systemSection } = resolveTabAndSection(tabParam);
  const classIdRaw = params.get('classId');
  const classId = classIdRaw ? Number(classIdRaw) : null;
  const examIdRaw = params.get('examId');
  const examId = examIdRaw ? Number(examIdRaw) : null;
  return {
    tab,
    classId: classId && !Number.isNaN(classId) ? classId : null,
    examId: examId && !Number.isNaN(examId) ? examId : null,
    systemSection,
  };
}

export function buildUrl(
  tab: TabId,
  classId?: number | null,
  examId?: number | null,
  systemSection?: SystemSection,
): string {
  const params = new URLSearchParams();
  params.set('tab', tab);
  if (tab === 'system' && systemSection) {
    params.set('section', systemSection);
  }
  if (classId) {
    params.set('classId', String(classId));
  }
  if (examId) {
    params.set('examId', String(examId));
  }
  return `/?${params.toString()}`;
}

export function readHistory(): NavEntry[] {
  try {
    const raw = sessionStorage.getItem(HISTORY_KEY);
    if (!raw) return [];
    const parsed = JSON.parse(raw) as NavEntry[];
    return Array.isArray(parsed) ? parsed : [];
  } catch {
    return [];
  }
}

function writeHistory(entries: NavEntry[]) {
  sessionStorage.setItem(HISTORY_KEY, JSON.stringify(entries.slice(0, MAX_HISTORY)));
}

function entryKey(kind: NavEntry['kind'], tab: TabId, id?: number, section?: SystemSection) {
  if (kind === 'class') return `class:${id}`;
  if (kind === 'exam') return `exam:${id}`;
  if (tab === 'system' && section) return `tab:system:${section}`;
  return `tab:${tab}`;
}

export function pushNav(entry: Omit<NavEntry, 'id' | 'timestamp'>) {
  const history = readHistory();
  const id = entryKey(entry.kind, entry.tab, entry.classId ?? entry.examId, entry.systemSection);
  const next: NavEntry = {
    ...entry,
    id,
    timestamp: Date.now(),
  };
  const filtered = history.filter((h) => h.id !== id);
  writeHistory([next, ...filtered]);
}

export function navigate(
  tab: TabId,
  id?: number | null,
  label?: string,
  kind: 'class' | 'exam' = 'class',
  systemSection?: SystemSection,
) {
  const url =
    kind === 'exam'
      ? buildUrl(tab, null, id, systemSection)
      : buildUrl(tab, id, undefined, systemSection);
  window.history.pushState({}, '', url);

  if (id && label) {
    pushNav({
      kind,
      tab,
      classId: kind === 'class' ? id : undefined,
      examId: kind === 'exam' ? id : undefined,
      label,
    });
  } else {
    const navLabel =
      tab === 'system' && systemSection
        ? `Hệ thống · ${SYSTEM_SECTION_LABELS[systemSection]}`
        : TAB_LABELS[tab];
    pushNav({
      kind: 'tab',
      tab,
      systemSection: tab === 'system' ? systemSection : undefined,
      label: navLabel,
    });
  }

  window.dispatchEvent(new PopStateEvent('popstate'));
}

export function navigateSystem(section: SystemSection) {
  navigate('system', null, undefined, 'class', section);
}

export function goBack(fallbackTab: TabId = 'classes') {
  const history = readHistory();
  const current = parseRoute();
  const currentId = current.classId
    ? entryKey('class', current.tab, current.classId)
    : current.examId
      ? entryKey('exam', current.tab, current.examId)
      : entryKey('tab', current.tab, undefined, current.systemSection);

  const remaining = history.filter((h) => h.id !== currentId);
  writeHistory(remaining);

  const previous = remaining[0];
  if (previous) {
    const url =
      previous.kind === 'class' && previous.classId
        ? buildUrl(previous.tab, previous.classId)
        : previous.kind === 'exam' && previous.examId
          ? buildUrl(previous.tab, null, previous.examId)
          : buildUrl(previous.tab, null, null, previous.systemSection);
    window.history.pushState({}, '', url);
  } else {
    window.history.pushState({}, '', buildUrl(fallbackTab));
  }
  window.dispatchEvent(new PopStateEvent('popstate'));
}
