type OverviewLayoutVersion = 1;

export type OverviewBlockId = "description" | "myTasks" | "files" | "info";

export type OverviewLayoutV1 = {
  version: OverviewLayoutVersion;
  leftZone: OverviewBlockId[];
  rightZone: OverviewBlockId[];
  updatedAt?: string;
  updatedBy?: string;
};

const DEFAULT_LEFT_ZONE: OverviewBlockId[] = ["description", "myTasks"];
const DEFAULT_RIGHT_ZONE: OverviewBlockId[] = ["files", "info"];
const ALL_BLOCK_IDS: OverviewBlockId[] = ["description", "myTasks", "files", "info"];

export const DEFAULT_OVERVIEW_LAYOUT: OverviewLayoutV1 = {
  version: 1,
  leftZone: DEFAULT_LEFT_ZONE,
  rightZone: DEFAULT_RIGHT_ZONE,
};

function unique<T>(items: T[]): T[] {
  return [...new Set(items)];
}

function isObject(value: unknown): value is Record<string, unknown> {
  return typeof value === "object" && value !== null;
}

function parseZone(value: unknown): OverviewBlockId[] {
  if (!Array.isArray(value)) return [];
  const valid = value.filter(
    (item): item is OverviewBlockId =>
      item === "description" || item === "myTasks" || item === "files" || item === "info"
  );
  return unique(valid);
}

export function sanitizeOverviewLayout(input: unknown): OverviewLayoutV1 {
  if (!isObject(input)) {
    return DEFAULT_OVERVIEW_LAYOUT;
  }

  const leftZoneInput = parseZone(input.leftZone);
  const rightZoneInput = parseZone(input.rightZone);

  const leftZoneSize = leftZoneInput.length;
  const allBlocks = unique([...leftZoneInput, ...rightZoneInput]);

  for (const blockId of ALL_BLOCK_IDS) {
    if (!allBlocks.includes(blockId)) {
      allBlocks.push(blockId);
    }
  }

  const safeLeftZoneSize = Math.min(leftZoneSize, allBlocks.length);
  const leftZone = allBlocks.slice(0, safeLeftZoneSize);
  const rightZone = allBlocks.slice(safeLeftZoneSize);

  return {
    version: 1,
    leftZone,
    rightZone,
  };
}
