import type { ProcurementMaterial } from '@/types';
import { normalizeEmptyFieldText } from '@/lib/emptyFieldPlaceholders';
import { filterKnownTestMaterials } from '@/lib/materialFilters';

const MATERIAL_DRAFTS_KEY = 'autoprocurement.materials.upload-drafts';
const HIDDEN_MOCK_MATERIAL_IDS_KEY = 'autoprocurement.materials.hidden-mock-ids';

function readJson<T>(key: string): T | null {
  if (typeof window === 'undefined') {
    return null;
  }

  const rawValue = window.localStorage.getItem(key);
  if (!rawValue) {
    return null;
  }

  try {
    return JSON.parse(rawValue) as T;
  } catch {
    window.localStorage.removeItem(key);
    return null;
  }
}

function writeJson<T>(key: string, value: T) {
  if (typeof window === 'undefined') {
    return;
  }

  window.localStorage.setItem(key, JSON.stringify(value));
}

function isValidMaterialDraft(value: unknown): value is ProcurementMaterial {
  if (!value || typeof value !== 'object') {
    return false;
  }

  const material = value as Record<string, unknown>;

  return typeof material.id === 'string'
    && typeof material.material_name === 'string'
    && typeof material.specification === 'string'
    && typeof material.quantity === 'number'
    && typeof material.unit === 'string'
    && typeof material.technical_standard === 'string'
    && typeof material.material_requirement === 'string'
    && typeof material.technical_requirement === 'string'
    && typeof material.applicable_conditions === 'string'
    && typeof material.test_requirement === 'string'
    && typeof material.acceptance_note === 'string'
    && typeof material.warranty_period === 'string'
    && typeof material.deadline === 'string'
    && typeof material.invoice_type === 'string'
    && typeof material.brand === 'string'
    && typeof material.remarks === 'string'
    && typeof material.delivery_address === 'string'
    && typeof material.source_file === 'string'
    && (material.source_file_id === undefined || typeof material.source_file_id === 'string')
    && typeof material.batch_id === 'string'
    && typeof material.created_at === 'string'
    && (material.created_by === undefined || typeof material.created_by === 'string');
}

function normalizeMaterialDraft(material: ProcurementMaterial): ProcurementMaterial {
  return {
    ...material,
    material_name: normalizeEmptyFieldText(material.material_name),
    specification: normalizeEmptyFieldText(material.specification),
    unit: normalizeEmptyFieldText(material.unit),
    technical_standard: normalizeEmptyFieldText(material.technical_standard),
    material_requirement: normalizeEmptyFieldText(material.material_requirement),
    technical_requirement: normalizeEmptyFieldText(material.technical_requirement),
    applicable_conditions: normalizeEmptyFieldText(material.applicable_conditions),
    test_requirement: normalizeEmptyFieldText(material.test_requirement),
    acceptance_note: normalizeEmptyFieldText(material.acceptance_note),
    warranty_period: normalizeEmptyFieldText(material.warranty_period),
    deadline: normalizeEmptyFieldText(material.deadline),
    invoice_type: normalizeEmptyFieldText(material.invoice_type),
    brand: normalizeEmptyFieldText(material.brand),
    remarks: normalizeEmptyFieldText(material.remarks),
    delivery_address: normalizeEmptyFieldText(material.delivery_address),
  };
}

export function getStoredMaterialDrafts() {
  const value = readJson<unknown>(MATERIAL_DRAFTS_KEY);

  if (!Array.isArray(value) || !value.every(isValidMaterialDraft)) {
    if (value !== null && typeof window !== 'undefined') {
      window.localStorage.removeItem(MATERIAL_DRAFTS_KEY);
    }
    return [] as ProcurementMaterial[];
  }

  const filtered = filterKnownTestMaterials(value).map(normalizeMaterialDraft);
  if (JSON.stringify(filtered) !== JSON.stringify(value)) {
    writeJson(MATERIAL_DRAFTS_KEY, filtered);
  }

  return filtered;
}

export function saveStoredMaterialDrafts(materials: ProcurementMaterial[]) {
  writeJson(MATERIAL_DRAFTS_KEY, materials.map(normalizeMaterialDraft));
}

export function getHiddenMockMaterialIds() {
  const value = readJson<unknown>(HIDDEN_MOCK_MATERIAL_IDS_KEY);

  if (!Array.isArray(value) || !value.every(item => typeof item === 'string')) {
    if (value !== null && typeof window !== 'undefined') {
      window.localStorage.removeItem(HIDDEN_MOCK_MATERIAL_IDS_KEY);
    }
    return [] as string[];
  }

  return value;
}

export function saveHiddenMockMaterialIds(ids: string[]) {
  writeJson(HIDDEN_MOCK_MATERIAL_IDS_KEY, ids);
}