import type { IAsset } from '../types';

/** Loại mặc định trong app (luôn merge trừ khi người dùng ẩn) */
export const DEFAULT_ASSET_TYPES = [
  'Plant',
  'Block',
  'Inverter',
  'Combiner Box',
  'String',
  'Panel',
  'Weather Station',
] as const;

const STORAGE_KEY = 'amom.assetTypeCatalog.v1';

export type PersistedAssetTypeCatalog = {
  /** Loại không thuộc danh mục có sẵn, lưu bởi người dùng */
  customTypes: string[];
  /** Tên trong DEFAULT đã được ẩn khỏi droplist (đổi tên / xóa khỏi danh mục UI) */
  hiddenBuiltinTypes: string[];
};

export function normalizeAssetTypeName(raw: string): string {
  return raw.trim().replace(/\s+/g, ' ');
}

export function isBuiltinAssetType(type: string): boolean {
  return (DEFAULT_ASSET_TYPES as readonly string[]).includes(type);
}

function normalizeCustomPersistList(types: unknown): string[] {
  if (!Array.isArray(types)) return [];
  return [...new Set(types.map((x) => normalizeAssetTypeName(String(x))).filter(Boolean))].filter(
    (t) => !isBuiltinAssetType(t)
  );
}

/** Chỉ cho phép ẩn đúng tên built-in trong code */
function normalizeHiddenBuiltinList(types: unknown): string[] {
  if (!Array.isArray(types)) return [];
  const allowed = new Set(DEFAULT_ASSET_TYPES as readonly string[]);
  const out = new Set<string>();
  for (const x of types) {
    const n = normalizeAssetTypeName(String(x));
    if (n && allowed.has(n)) out.add(n);
  }
  return [...out];
}

export function normalizePersistedAssetTypeCatalog(state: PersistedAssetTypeCatalog): PersistedAssetTypeCatalog {
  return {
    customTypes: normalizeCustomPersistList(state.customTypes),
    hiddenBuiltinTypes: normalizeHiddenBuiltinList(state.hiddenBuiltinTypes),
  };
}

/** Đọc localStorage — hỗ trợ mảng cũ chỉ chứa custom types */
export function loadPersistedAssetTypeCatalog(): PersistedAssetTypeCatalog {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    if (!raw) return { customTypes: [], hiddenBuiltinTypes: [] };
    const parsed = JSON.parse(raw) as unknown;
    if (Array.isArray(parsed)) {
      return { customTypes: normalizeCustomPersistList(parsed), hiddenBuiltinTypes: [] };
    }
    if (parsed && typeof parsed === 'object') {
      const o = parsed as Record<string, unknown>;
      const customTypes = normalizeCustomPersistList(
        Array.isArray(o.customTypes)
          ? o.customTypes
          : Array.isArray(o.custom)
            ? o.custom
            : []
      );
      const hiddenBuiltinTypes = normalizeHiddenBuiltinList(
        Array.isArray(o.hiddenBuiltinTypes)
          ? o.hiddenBuiltinTypes
          : Array.isArray(o.hiddenBuiltin)
            ? o.hiddenBuiltin
            : []
      );
      return { customTypes, hiddenBuiltinTypes };
    }
    return { customTypes: [], hiddenBuiltinTypes: [] };
  } catch {
    return { customTypes: [], hiddenBuiltinTypes: [] };
  }
}

export function savePersistedAssetTypeCatalog(state: PersistedAssetTypeCatalog): void {
  const payload = normalizePersistedAssetTypeCatalog(state);
  localStorage.setItem(STORAGE_KEY, JSON.stringify(payload));
}

/** @deprecated Giữ tương thích; dùng loadPersistedAssetTypeCatalog */
export function loadCustomAssetTypes(): string[] {
  return loadPersistedAssetTypeCatalog().customTypes;
}

/** @deprecated Giữ hiddenBuiltin không đổi; dùng savePersistedAssetTypeCatalog */
export function saveCustomAssetTypes(types: string[]): void {
  const cur = loadPersistedAssetTypeCatalog();
  savePersistedAssetTypeCatalog({ ...cur, customTypes: types });
}

type CatalogMergeInput = {
  customTypes: readonly string[];
  hiddenBuiltinTypes: readonly string[];
};

/**
 * Hợp nhất cho droplist:
 * defaults (không ẩn) + tuỳ chỉnh + mọi loại đang gắn trên tài sản.
 */
export function mergeAssetTypeOptionList(persisted: CatalogMergeInput, assets: IAsset[]): string[] {
  const fromAssets = assets
    .map((a) => normalizeAssetTypeName(String(a.assetType || '')))
    .filter(Boolean);

  const hidden = new Set(persisted.hiddenBuiltinTypes.map((t) => normalizeAssetTypeName(t)).filter(Boolean));

  const set = new Set<string>();

  for (const t of DEFAULT_ASSET_TYPES) {
    if (!hidden.has(t)) set.add(t);
  }

  for (const t of persisted.customTypes) {
    const n = normalizeAssetTypeName(t);
    if (n) set.add(n);
  }

  for (const t of fromAssets) set.add(t);

  return [...set].sort((a, b) => a.localeCompare(b, 'vi', { sensitivity: 'base' }));
}
