import {
  CatalogEngine,
  CatalogMake,
  CatalogModel,
  CatalogTrim,
  CatalogYear,
} from '../types/admin.types';

export type CatalogLevel = 'makes' | 'models' | 'years' | 'trims' | 'engines';

export type CatalogRow =
  | CatalogMake
  | CatalogModel
  | CatalogYear
  | CatalogTrim
  | CatalogEngine;

export interface CatalogSelectionContext {
  level: CatalogLevel;
  make?: CatalogMake;
  model?: CatalogModel;
  year?: CatalogYear;
  trim?: CatalogTrim;
}

export const LEVEL_LABEL: Record<CatalogLevel, string> = {
  makes: 'Makes',
  models: 'Models',
  years: 'Years',
  trims: 'Trims',
  engines: 'Engines',
};

export const LEVEL_SINGULAR_LABEL: Record<CatalogLevel, string> = {
  makes: 'Make',
  models: 'Model',
  years: 'Year',
  trims: 'Trim',
  engines: 'Engine',
};

export const NEXT_LEVEL: Record<CatalogLevel, CatalogLevel | null> = {
  makes: 'models',
  models: 'years',
  years: 'trims',
  trims: 'engines',
  engines: null,
};

export const pluralize = (count: number, singular: string): string =>
  `${count} ${singular}${count === 1 ? '' : 's'}`;

export const getCascadeSummary = (
  level: CatalogLevel,
  selectedItems: CatalogRow[],
  modelsByMake: Map<string, CatalogModel[]>,
  yearsByModel: Map<string, CatalogYear[]>,
  trimsByYear: Map<string, CatalogTrim[]>,
  enginesByTrim: Map<string, CatalogEngine[]>
): string => {
  if (selectedItems.length === 0) {
    return '';
  }

  if (level === 'engines') {
    return 'Deleting engines will remove their configuration details.';
  }

  let modelCount = 0;
  let yearCount = 0;
  let trimCount = 0;
  let engineCount = 0;

  if (level === 'makes') {
    selectedItems.forEach((item) => {
      const make = item as CatalogMake;
      const makeModels = modelsByMake.get(make.id) ?? [];
      modelCount += makeModels.length;
      makeModels.forEach((model) => {
        const modelYears = yearsByModel.get(model.id) ?? [];
        yearCount += modelYears.length;
        modelYears.forEach((year) => {
          const yearTrims = trimsByYear.get(year.id) ?? [];
          trimCount += yearTrims.length;
          yearTrims.forEach((trim) => {
            const trimEngines = enginesByTrim.get(trim.id) ?? [];
            engineCount += trimEngines.length;
          });
        });
      });
    });

    return `Deleting ${selectedItems.length} ${LEVEL_LABEL.makes.toLowerCase()} will also remove ${pluralize(
      modelCount,
      'model'
    )}, ${pluralize(yearCount, 'year')}, ${pluralize(
      trimCount,
      'trim'
    )}, and ${pluralize(engineCount, 'engine')}.`;
  }

  if (level === 'models') {
    selectedItems.forEach((item) => {
      const model = item as CatalogModel;
      const modelYears = yearsByModel.get(model.id) ?? [];
      yearCount += modelYears.length;
      modelYears.forEach((year) => {
        const yearTrims = trimsByYear.get(year.id) ?? [];
        trimCount += yearTrims.length;
        yearTrims.forEach((trim) => {
          const trimEngines = enginesByTrim.get(trim.id) ?? [];
          engineCount += trimEngines.length;
        });
      });
    });

    return `Deleting ${selectedItems.length} ${LEVEL_LABEL.models.toLowerCase()} will also remove ${pluralize(
      yearCount,
      'year'
    )}, ${pluralize(trimCount, 'trim')}, and ${pluralize(
      engineCount,
      'engine'
    )}.`;
  }

  if (level === 'years') {
    selectedItems.forEach((item) => {
      const year = item as CatalogYear;
      const yearTrims = trimsByYear.get(year.id) ?? [];
      trimCount += yearTrims.length;
      yearTrims.forEach((trim) => {
        const trimEngines = enginesByTrim.get(trim.id) ?? [];
        engineCount += trimEngines.length;
      });
    });

    return `Deleting ${selectedItems.length} ${LEVEL_LABEL.years.toLowerCase()} will also remove ${pluralize(
      trimCount,
      'trim'
    )} and ${pluralize(engineCount, 'engine')}.`;
  }

  if (level === 'trims') {
    selectedItems.forEach((item) => {
      const trim = item as CatalogTrim;
      const trimEngines = enginesByTrim.get(trim.id) ?? [];
      engineCount += trimEngines.length;
    });

    return `Deleting ${selectedItems.length} ${LEVEL_LABEL.trims.toLowerCase()} will also remove ${pluralize(
      engineCount,
      'engine'
    )}.`;
  }

  return '';
};
