#encoding: utf-8
class CsvExportController < ApplicationController
  require 'csv'
  include CsvExportHelper
  include ApplicationHelper
  before_action :login_required

  def index
    datensatz = params[:datensatz]
    puts "CsvExportController läuft; datensatz = "+datensatz.to_s
    puts "  übrigens: params = "+params.to_s

    @all = 0

    if datensatz == 'all'
      @all = 1
      csv_content = Array.new
      csv_content.concat(erstelle_csv_daten(nil, nil, nil, 'agglomerations', sort = true))
      csv_content.concat(erstelle_csv_daten(nil, nil, nil, 'plants', sort = true))
      csv_content.concat(erstelle_csv_daten(nil, nil, nil, 'discharge_points', sort = true))
      csv_content.concat(erstelle_csv_daten(nil, nil, nil, 'federal_state_info', sort = true))
      csv_content.concat(zusatztabelle("agglomerations", nil, ["#Da"], sort = true))
    elsif params[:where].nil?
      csv_content = erstelle_csv_daten(nil, nil, nil, datensatz)
      if csv_content.is_a? String
        render :text => "Fehler: #{csv_content}" and return false
      end      
    else
      where, spalten = case params[:where]
        when 'agg_query' then [AgglomerationsAbfrageController.form_where_mit_parameter(session), AgglomerationsAbfrageController.form_spalten(session)]
        when 'pl_query' then [PlantsAbfrageController.form_where_mit_parameter(session), PlantsAbfrageController.form_spalten(session)]
        when 'dp_query' then [EinleitstellenAbfrageController.form_where_mit_parameter(session), EinleitstellenAbfrageController.form_spalten(session)]
        when /^qs_[a-z0-9]+$/ then [InkonsistenzenController.where(session),nil]
      end
      whereparam = where[1]
      where      = where[0]
      csv_content = erstelle_csv_daten(where, whereparam, spalten, datensatz)
      if csv_content.is_a? String
        render :text => "Fehler: #{csv_content}" and return false
      end
    end
    rescue_pusher=[]
    begin
      csv_data = CSV.generate({:col_sep => ";", :encoding => "ISO-8859-1"}) do |csv|
        csv << ["#Ziso8859-1"]
        csv << ['#Fde']
        csv_content.each do |csv_ausgabezeile|
          csv << csv_ausgabezeile
          rescue_pusher << "***"+csv_ausgabezeile.to_s
        end
      end
    rescue
      render :text => rescue_pusher.to_s
    end

    @outfile = Time.now.strftime("%Y-%m-%d") + "_#{datensatz}_#{theUser(session).loginname}" +  ".csv"
    csv_data.encode!("ISO-8859-1")
#    render :text => csv_data, :content_type => 'text/plain; charset=ISO-8859-1'
    send_data csv_data,
      :type => 'text/csv; charset=ISO-8859-1',
      :disposition => "attachment; filename=#{@outfile}"
  end

  protected

  # wenn spalten == nil ist, werden alle spalten ausgegeben
  # wenn where == nil ist, wird nur nach berichtszeitraum (und Nutzer-Bundesland) gefiltert
  def erstelle_csv_daten (where, whereparam, spalten, datensatz, sort=FALSE)
    # no export eu coordinate columns
    eu_coord_columns = ['ag_long_eu', 'ag_lat_eu', 'pl_eu_long', 'pl_eu_lat', 'dp_eu_long', 'dp_eu_lat']

    # if where is nil, this means all should be collected, but from the current reporting period
    where ||= " AND #{datensatz}.rep_code = '#{ReportingPeriod.get_current.key_report}'"

    #hole daten und spalten aus der datenbank
    return "Es wurden keine Spalten angegeben!" if spalten && spalten.empty? #Fehler wenn Spalten-array leer ist. Kein Fehler wenn er nil ist, da das alle Spalten heisst
    puts "Generica.new("+datensatz.to_s+", "+session[:user].to_s+")"
    puts "   gen.find_for_csv("+where.to_s+", "+whereparam.to_s+", "+spalten.to_s+", :all)"

    if datensatz == 'discharge_points'
      puts "Export von #{datensatz}"
    end
    @gen = Generica.new(datensatz, session[:user], for_import = false, for_export = true)
    data = @gen.find_for_csv(where, whereparam, spalten, :all, sort)
    return [] if data.empty?
    @columns = data.first.columns

    # fülle spaltennamen für spätere csv
    csv_keys = []                   #beinhaltet uba-keys für export, damit die daten reimportiert werden können
    csv_human_names = []            #beinhaltet menschenlesbare spaltennamen analog zu csv_keys, wird als kommentarzeile verwendet
    haben_will = false          #sollen zugeordnete Anlagen oder Agglomerationen mitexportiert werden? wird in der folgenden schleife auf ja gesetzt wenn es soll
    if datensatz == 'discharge_points'
      puts "Export von #{datensatz}"
    end
    @columns.each do |c|
      if eu_coord_columns.include?(c['uba_key'])
        next
      end
      csv_keys.push(c['uba_key'])
      csv_human_names.push(c['human_name'])
      # when reference_type 13 is included (plant belonging to dp, then federal state of plant has to be included)
      # 13 is currently not assigned. The respective uba_key "bl_code_ref" now has 11, as some others do.
      # But mlt changed call to generica initialisation with for_export = true so we shoud get all columns here:
      if c['reference_type'].to_i == 13
        csv_keys.push('bl_code_ref')
        csv_human_names.push('Bundesland der Anlage')
      end
      # sollen zugeordnete Anlagen oder Agglomerationen mitexportiert werden? (wird nur für einzelne tabellen berücksichtigt, nicht beim gesamtexport
      haben_will = true if ['agglomerations','plants'].include?(c['col_name'])
    end
    
    # formatiere daten aus datenbank und fülle array mit Dateninhalt des CSVs
    csv_inhalt = Array.new
    ids = Array.new  #benötigt für zusatztabelle agg_plant
    data.each do |zeile|
      ids.push(zeile.id)  #benötigt für zusatztabelle agg_plant
      csv_zeile = Array.new
      @columns.each do |zelle|
        if eu_coord_columns.include?(zelle['uba_key'])
          next
        end
        inhalt = zeile[zelle]
        inhalt = '' if inhalt.blank?
        inhalt = de_numberise(inhalt) if zelle.is_double?
        inhalt = inhalt.to_s
        inhalt = inhalt[0..inhalt.length-2] if inhalt[inhalt.length-1] == 32 # wenn leerzeichen am Ende sind werden sie abgeschnitten
#        csv_zeile.push(conv.iconv(inhalt))
        csv_zeile.push(inhalt)
        if zelle['reference_type'].to_i == 13
          csv_zeile.push(zeile['plant_fed_state'])
        end
      end
      csv_inhalt.push(csv_zeile)
    end

    #werden nur bestimmte (dp) oder alle (da) daten exportiert
    csv_da = spalten ? ["#Dp"] : ["#Da"]

    # exportiere agg_plant_relations wenn kein gesamtexport ausgeführt wird aber Anlagen oder Agglomerationen mitexportiert werden
    csv_zusatz = nil
    if @all==0 and haben_will
      csv_zusatz = zusatztabelle(datensatz, ids, csv_da)
    end

    # erstelle ergebnis-array
    csv_erg = Array.new
    csv_erg.push(["# von #{theUser(session).loginname} automatisch erstellte CSV-Datei der '#{datensatz}'."]) #tabellenbeschreibung
    csv_erg.push(csv_da)            # werden nur bestimmte (dp) oder alle (da) Daten exportiert
    csv_erg.push(csv_keys)          # exportiere spaltennamen (uba_key)
    csv_human_names[0] = "# " + csv_human_names[0]    # sorge dafür, dass die menschenlesbaren spaltennamen nur kommentare sind
    csv_erg.push(csv_human_names)   # exportiere menschenlesbare spaltennamen
    csv_erg.concat(csv_inhalt)      # exportiere inhalt

    csv_erg.concat(csv_zusatz) if csv_zusatz
    
    return  csv_erg
  end


  #end of erstelle_csv_daten ----------------------------------------------------------------------------------------



  def zusatztabelle (datensatz, ids, csv_da, sort = false)
    # mlt: Ich mache mal einen inner join aus den plants-joins, sonst baut der Export Mist:
    sql_string = "SELECT DISTINCT afs.federal_key afsk, agglomerations.agg_key, pfs.federal_key pfsk, plants.pl_key, agg_percent_plant
FROM agglomerations_plants
JOIN agglomerations ON agglomeration_id = agglomerations.id
JOIN l_federal_state afs ON agglomerations.federal_state_id = afs.id
JOIN plants ON plant_id = plants.id
JOIN l_federal_state pfs ON plants.federal_state_id = pfs.id
"
    table_ref = if ids.nil?
      states = theUser(session).get_states_for_read
      state_placeholders = states.collect{|v| '?'}.join(", ")
      where =  " WHERE (agglomerations.federal_state_id in (#{state_placeholders})
           OR plants.federal_state_id in (#{state_placeholders}))
          AND agglomerations.rep_code = ?"
      if sort
        order_by = ' ORDER BY afs.federal_key, agglomerations.agg_key'
      else
        order_by = ''
      end
      table_ref = ActiveRecord::Base.query_sql(sql_string+where+order_by,*states,*states,ReportingPeriod.get_current.key_report)
    else 
      where = " WHERE #{datensatz}.id in (#{ids.collect{|v| '?'}.join(" , ")})"
      table_ref = ActiveRecord::Base.query_sql(sql_string+where,*ids)
    end


    #ergebnis = [["bl_code_agg", "agg_eu_key", "bl_code_pl", "pl_eu_key", "agg_percent_plant"]]
    ergebnis = Array.new
    ergebnis.push(['# Zuordnung agglomerations - plants'])
    ergebnis.push(csv_da)
    ergebnis.push(["bl_code_agg", "agg_key", "bl_code_pl", "pl_ID", "agg_percent_plant"])

    table_ref.each do |zeile|
      if !zeile[4].nil?
        zeile[4] = zeile[4].to_s
        zeile[4].gsub!('.',',')
      end
      ergebnis.push(zeile)
    end

    return ergebnis
  end

end
