import type { TemplateClass } from '../store/useStore';

export const RESERVED_UNCLASSIFIED_CLASS: TemplateClass = {
  id: 'reserved-unclassified',
  name: '待分类',
  color: '#000000',
  zIndex: 0,
  maskId: 0,
  category: '系统保留',
};

export function isReservedUnclassifiedClass(templateClass: Pick<TemplateClass, 'id' | 'maskId' | 'name'>): boolean {
  return Number(templateClass.maskId) === 0 || templateClass.id === RESERVED_UNCLASSIFIED_CLASS.id || templateClass.name === RESERVED_UNCLASSIFIED_CLASS.name;
}

function reservedUnclassifiedClass(source?: Partial<TemplateClass>): TemplateClass {
  return {
    ...RESERVED_UNCLASSIFIED_CLASS,
    ...source,
    id: RESERVED_UNCLASSIFIED_CLASS.id,
    name: RESERVED_UNCLASSIFIED_CLASS.name,
    color: RESERVED_UNCLASSIFIED_CLASS.color,
    zIndex: RESERVED_UNCLASSIFIED_CLASS.zIndex,
    maskId: RESERVED_UNCLASSIFIED_CLASS.maskId,
    category: RESERVED_UNCLASSIFIED_CLASS.category,
  };
}

export function normalizeClassMaskIds(classes: TemplateClass[] = []): TemplateClass[] {
  const used = new Set<number>();
  let nextMaskId = 1;
  let reservedClass: TemplateClass | undefined;

  const nextAvailableMaskId = () => {
    while (used.has(nextMaskId)) nextMaskId += 1;
    const value = nextMaskId;
    used.add(value);
    nextMaskId += 1;
    return value;
  };

  const normalized = classes
    .filter((templateClass) => {
      if (isReservedUnclassifiedClass(templateClass)) {
        reservedClass ??= reservedUnclassifiedClass(templateClass);
        return false;
      }
      return true;
    })
    .map((templateClass) => {
    const parsed = Number(templateClass.maskId);
    if (Number.isInteger(parsed) && parsed > 0 && !used.has(parsed)) {
      used.add(parsed);
      return { ...templateClass, maskId: parsed };
    }
    return { ...templateClass, maskId: nextAvailableMaskId() };
  });
  return [...normalized, reservedClass || reservedUnclassifiedClass()];
}

export function nextClassMaskId(classes: TemplateClass[] = []): number {
  const used = new Set(
    classes
      .map((templateClass) => Number(templateClass.maskId))
      .filter((value) => Number.isInteger(value) && value > 0),
  );
  let value = 1;
  while (used.has(value)) value += 1;
  return value;
}
