class Pumi::DataSource::NCDD

def add_data(row)

def add_data(row)
  data[row.administrative_unit.group] ||= {}
  data[row.administrative_unit.group][row.code] = existing_data.dig(row.administrative_unit.group, row.code) || {}
  data[row.administrative_unit.group][row.code]["name"] = existing_data.dig(row.administrative_unit.group, row.code, "name") || {}
  data[row.administrative_unit.group][row.code]["name"].merge!(
    "km" => row.name_km,
    "latin" => row.name_latin
  )
  data[row.administrative_unit.group][row.code].merge!(
    "administrative_unit" => {
      "km" => row.administrative_unit.km,
      "latin" => row.administrative_unit.latin,
      "en" => row.administrative_unit.en,
      "ungegn" => row.administrative_unit.ungegn
    }
  )
end

def build_row(row)

def build_row(row)
  code = parse_location_code(row)
  name_latin = row.fetch("name_latin")
  name_latin = MISSPELLINGS.find { |m| m.incorrect_text == name_latin }&.correct_text || name_latin
  Row.new(
    code:,
    name_km: row.fetch("name_km"),
    name_latin:,
    type: row.fetch("type") || MISSING_DATA.dig(code, :type)
  )
end

def data

def data
  @data ||= {}
end

def default_data_files

def default_data_files
  [
    DataFile.new(:districts),
    DataFile.new(:communes),
    DataFile.new(:villages)
  ]
end

def initialize(data_files: default_data_files)

def initialize(data_files: default_data_files)
  @existing_data = data_files.each_with_object({}) do |data_file, result|
    result[data_file.type] = data_file.read
  end
end

def load_data!(source_dir: "tmp", output_dir: "data")

def load_data!(source_dir: "tmp", output_dir: "data")
  source_files(source_dir).each do |file|
    parse_source_file(file)
  end
  write_data!(output_dir)
end

def parse_location_code(row)

def parse_location_code(row)
  code = row.fetch("code")
  return if code.to_s.gsub(/\D/, "").empty?
  code = code.rjust(code.length + 1, "0") if code.length.odd?
  code
end

def parse_source_file(file)

def parse_source_file(file)
  CSV.read(file, headers: CSV_HEADERS).each do |csv_row|
    row = build_row(csv_row)
    next unless row.code
    next if row.administrative_unit.code_length != row.code.length
    add_data(row)
  end
end

def source_files(source_dir)

def source_files(source_dir)
  Pathname.glob("#{source_dir}/*.csv").select(&:file?)
end

def write_data!(output_dir)

def write_data!(output_dir)
  return if data.empty?
  ADMINISTRATIVE_UNITS.values.map(&:group).uniq do |data_group|
    DataFile.new(data_group).write(data.fetch(data_group), data_directory: output_dir)
  end
end