/**
 * CSV Import Utilities
 * Parses exported CSV rows back into annotation payloads by matching atlas and
 * trait headers against the schema used by the frontend import workflow.
 */
const normalize = (text) => 
  text?.toString().toLowerCase().trim().replace(/_/g, ' ') || '';

const HEADER_ALIASES = {
  modelId: ['model (external id)'],
  annotatorName: ['anotátor', 'annotator'],
  fileHash: ['souborový hash', 'file hash'],
  atlasName: ['metodika (atlas)', 'atlas'],
  checkerName: ['zkontroloval', 'checked by', 'checker'],
};

const findHeaderIndex = (headers, aliases, fallbackIndex) => {
  const foundIndex = headers.findIndex((header) => aliases.includes(normalize(header)));
  return foundIndex >= 0 ? foundIndex : fallbackIndex;
};

export const parseCSVToAnnotation = async (file, megaSchema, lang, allAtlases = []) => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = (e) => {
      try {
        let content = e.target.result;
        if (content.startsWith('\uFEFF')) content = content.substring(1);

        const lines = content.split(/\r?\n/).filter(line => line.trim() !== "");
        if (lines.length < 2) throw new Error("Soubor je prázdný.");

        const headers = lines[0].split(";").map(h => h.replace(/^"|"$/g, '').trim());
        const modelIdIndex = findHeaderIndex(headers, HEADER_ALIASES.modelId, 1);
        const annotatorIndex = findHeaderIndex(headers, HEADER_ALIASES.annotatorName, 2);
        const fileHashIndex = findHeaderIndex(headers, HEADER_ALIASES.fileHash, 3);
        const atlasIndex = findHeaderIndex(headers, HEADER_ALIASES.atlasName, 5);
        const checkerIndex = findHeaderIndex(headers, HEADER_ALIASES.checkerName, -1);
        const reservedIndexes = new Set([0, modelIdIndex, annotatorIndex, fileHashIndex, 4, atlasIndex]);
        if (checkerIndex >= 0) reservedIndexes.add(checkerIndex);

        const atlasContextLookup = {};
        
        megaSchema.forEach(category => {
          const aId = String(category.atlas_id);
          if (!atlasContextLookup[aId]) atlasContextLookup[aId] = {};

          category.znaky?.forEach(trait => {
            const traitData = {
              id: trait.id,
              options: {}
            };

            trait.options?.forEach(opt => {
              if (opt.label_cs) traitData.options[normalize(opt.label_cs)] = opt.label_cs;
              if (opt.label_en) traitData.options[normalize(opt.label_en)] = opt.label_cs;
            });

            atlasContextLookup[aId][normalize(trait.id)] = traitData;
            atlasContextLookup[aId][normalize(trait.label_cs)] = traitData;
            atlasContextLookup[aId][normalize(trait.label_en)] = traitData;
          });
        });

        const allAnnotations = lines.slice(1).map((line) => {
          const rowData = line.split(";").map(v => v.replace(/^"|"$/g, '').trim());
          const atlasNameInCsv = rowData[atlasIndex];
          const checkerName = checkerIndex >= 0 ? rowData[checkerIndex] : '';

          const atlasObj = allAtlases.find(a => 
              String(a.id) === atlasNameInCsv || a.nazev_cs === atlasNameInCsv || a.nazev_en === atlasNameInCsv
          );
          
          const currentAtlasId = atlasObj ? String(atlasObj.id) : null;
          const traitLookup = atlasContextLookup[currentAtlasId] || {};
          const values = {};
          
          for (let i = 0; i < headers.length; i++) {
            if (reservedIndexes.has(i)) continue;

            const headerLabel = normalize(headers[i]);
            const valueLabel = rowData[i];

            if (!valueLabel) continue;

            const traitInfo = traitLookup[headerLabel];
            
            if (traitInfo) {
              const normVal = normalize(valueLabel);
              const originalLabelCs = traitInfo.options[normVal];

              values[traitInfo.id] = originalLabelCs !== undefined ? originalLabelCs : valueLabel;
            }
          }

          return {
            modelId: rowData[modelIdIndex],
            annotatorName: rowData[annotatorIndex],
            fileHash: rowData[fileHashIndex],
            atlasId: currentAtlasId,
            atlasName: atlasNameInCsv,
            checkerName,
            isChecked: Boolean(checkerName),
            values
          };
        });

        resolve(allAnnotations);
      } catch (err) { reject(err); }
    };
    reader.readAsText(file);
  });
};