# encoding: utf-8

class Image < ActiveRecord::Base
  include ThinkingSphinx::Scopes

  belongs_to :provider
  belongs_to :pp_category
  has_many   :provider_response_to_requests, dependent: :destroy
  has_many   :light_box_images, dependent: :destroy
  has_many   :light_boxes, through: :light_box_images
  has_many   :reportage_photos, dependent: :destroy, primary_key: :ms_image_id, foreign_key: :photo_ms_id
  has_many   :reportages, through: :reportage_photos
  has_many   :statistics, dependent: :destroy

  validates :provider_id, presence: true

  scope :order_by_light_box_image_id_desc, -> { order('light_box_images.id DESC') }
  scope :order_by_light_box_position_desc, -> { order('light_box_images.position DESC') }

  def self.searchable_fields
    [:file_name, :original_filename, :creator, :rights, :credit, :source, :instructions, :title, :subject, :city, :state, :country, :headline,
     :description, :reportage, :normalized_credit,  :category, :supplemental_category]
  end

  def provider_name
    self.provider.name
  end

  def hd_size
    "#{max_avail_width} x #{max_avail_height}"
  end

  def max_size
    #dpi = UserSession.find.user.title.dpi
    #dpi ||= '75'
    #dpi = dpi.to_i
    dpi = 300
    "#{sprintf('%g',(max_avail_width.to_f / dpi.to_f * 2.54).round(2))} x #{sprintf('%g',(max_avail_height.to_f / dpi.to_f * 2.54).round(2))}"
  end

  def provider_conditions
    self.provider.provider_conditions
  end

  def localised_reception_date
    I18n.l(reception_date) unless reception_date.blank?
  end

  def localised_date_created
    # no time zone for the picture date metadata
    I18n.l(date_created) unless date_created.blank?
  end

  # Return medium_location or thumb_location value based on RSS_IMAGE_FORMAT value
  def rss_image_location
    __send__("#{RSS_IMAGE_FORMAT.to_s}_location")
  end

  def providers_authorizations
    user =  UserSession.find.user
    permissions_list =[]
    if user.is_superadmin?
      permissions_list = PermissionLabel.all
    else
      title_provider_group = TitleProviderGroup.find_by_provider_id_and_title_provider_group_name_id(self.provider_id, user.providers_group.id)
      permissions_list = title_provider_group.permission_labels if title_provider_group
    end

    permissions_list
  end

  def has_right(user,label)
    providers_authorizations.any?{|auth| auth.label == label}
  end

  def delete_from_fs(*relative_path)
    relative_path.each do |f|
      begin
        if File.exists?("#{Rails.root}/public/#{f}")
          File.delete("#{Rails.root}/public/#{f}")
        else
          DELETE_LOG.warn("#{Time.now.to_s} - Warning : file #{f} not found.")
        end
      rescue Exception => e
        DELETE_LOG.error("#{Time.now.to_s} - Error : #{e} while removing #{f}")
      end
    end
  end

  before_destroy do |im|
    im_pathes = [im.medium_location, im.thumb_location]
    im_pathes << im.hires_location unless im.provider.input_dir.blank?
    im.delete_from_fs( *im_pathes)
  end

  def delete_hr
    img_ms_image_id = self.ms_image_id
    prov_string_key = self.provider.string_key
    img_file_name = self.file_name
    self.destroy
    MessageToMs::PutMessageRec.sendMessageRecord('DELETE_HR', img_ms_image_id, prov_string_key) if (Server.itself?(PIXADMIN_SERVER_NAME) || (Server.itself?(VINGTMINUTES_SERVER_NAME) && prov_string_key.start_with?('20min_')))
    DELETE_LOG.info("#{Time.now.to_s} : #{img_file_name} deleted.")
  end

  def deletion_for_stats(send_pp2=false)
    LightBoxImage.where(image_id: self.id).destroy_all
    ReportagePhoto.where(photo_ms_id: self.ms_image_id).destroy_all
    self.update(content_error: 1)
    if send_pp2 && Server.itself?(PIXADMIN_SERVER_NAME)
      DELETE_LOG.info("#{Time.now.to_s} : deleting #{self.file_name} (HR only, LR kept for stats - move to pp2)")
      MessageToMs::PutMessageRec.sendMessageRecord('MOVED_TO_PP2', self.ms_image_id, self.provider.string_key)
    else
      DELETE_LOG.info("#{Time.now.to_s} : deleting #{self.file_name} (HR only, LR kept for stats)")
      MessageToMs::PutMessageRec.sendMessageRecord('DELETE_HR', self.ms_image_id, self.provider.string_key) if (Server.itself?(PIXADMIN_SERVER_NAME) || (Server.itself?(VINGTMINUTES_SERVER_NAME) && self.provider.string_key.start_with?('20min_')))
    end
  end

  def moved_to_pp2
    img_ms_image_id = self.ms_image_id
    prov_string_key = self.provider.string_key
    img_file_name = self.file_name
    self.destroy
    MessageToMs::PutMessageRec.sendMessageRecord('MOVED_TO_PP2', img_ms_image_id, prov_string_key) if Server.itself?(PIXADMIN_SERVER_NAME)
    DELETE_LOG.info("#{Time.now.to_s} : #{img_file_name} deleted (moved to PP2).")
  end

  def self.delete_PA_only
    puts "******** Effacement photos PA_only #{Time.now}"
    ic = 0
    imgs = []
    purge_date = Time.now.midnight-1.month
    self.where('hires_location like ? and updated_at < ?', '%PA_only%', purge_date).find_each do |i|
      DELETE_LOG.info("#{Time.now.to_s} : #{im.file_name} tagged as PA_only is going to be deleted (pictures controls purge).")
      i.delete_hr
      ic += 1
    end
    puts "******** Fin : #{ic} effacements"
  end

  def self.envoi_MS(id)
    im = Image.find(id)
    content_label = "2:55,2:105,2:120,2:101,2:90,2:80,2:110,2:115,2:116,2:25,2:40\n"
    content_data = im.date_created.nil? ? "\"\" ," : "\"" + im.date_created.to_s + "\","
    content_data += im.headline.nil? ? "\"\" ," : "\"" + im.headline + "\","
    content_data += im.description.nil? ? "\"\" ," : "\"" + im.description + "\","
    content_data += im.country.nil? ? "\"\" ," : "\"" + im.country + "\","
    content_data += im.city.nil? ? "\"\" ," : "\"" + im.city + "\","
    content_data += im.creator.nil? ? "\"\" ," : "\"" + im.creator + "\","
    content_data += im.credit.nil? ? "\"\" ," : "\"" + im.credit + "\","
    content_data += im.source.nil? ? "\"\" ," : "\"" + im.source + "\","
    content_data += im.rights.nil? ? "\"\" ," : "\"" + im.rights + "\","
    content_data += im.subject.nil? ? "\"\" ," : "\"" + im.subject + "\","
    content_data += im.instructions.nil? ? "\"\" ," : "\"" + im.instructions + "\","
    content_data = content_data.squish
    content = content_label + content_data

    config_db_ms = Rails.configuration.database_configuration['ms_db']
    client = Mysql2::Client.new(host: config_db_ms['host'], database: config_db_ms['database'], username: config_db_ms['username'], password: config_db_ms['password'])
    client.query("insert into MetadataFromPA set mdfpa_pic_id=#{im.ms_image_id}, mdfpa_csv='#{Mysql2::Client.escape(content)}', mdfpa_created_at=now()")
    client.close
  end

  def self.send_to_MS(params,util,session_pixtech)
    begin
      if params[:serv_dest] == 'PP2'
        server = 'PixPalace 2'
        img_flow_to_check = 1
        server_checked = 'PixPalace'
      else
        server = 'PixPalace'
        img_flow_to_check = 2
        server_checked = 'PixPalace 2'
      end
      lb = ''
      nb_ims = 0
      imgs = []
      imgs_rejected = []
      imgs_not_found = []
      CSV.foreach(params[:pictures_list]) do |i|
        nb_ims += 1
        im = Image.where(original_filename: i, provider_id: Provider.find_by(string_key: params[:author])).select(:id,:ms_image_id,:original_filename,:file_name,:creator,:provider_id,:content_error,:flow,:hires_location).first
        if im.nil?
          imgs_not_found << i
        else
          if im.provider.is_pixtech_author? && im.content_error === false
            if  img_flow_to_check == im.flow
              imgs_rejected << im
            else
              imgs << im
            end
          end
        end
      end
      imgs.compact!
      imgs.sort
      if imgs.count > 0
        config_db_ms = Rails.configuration.database_configuration['ms_db']
        client = Mysql2::Client.new(host: config_db_ms['host'], database: config_db_ms['database'], username: config_db_ms['username'], password: config_db_ms['password'])
        imgs.each do |i|
          csv = "3:238\r\n\"#{params[:serv_dest]}\""
          case params[:serv_dest]
          when 'PP'
            i.update(flow: 1)
          when 'PP2'
            i.update(flow: 2)
          end
          client.query("insert into MetadataFromPA set mdfpa_pic_id=#{i.ms_image_id}, mdfpa_csv='#{Mysql2::Client.escape(csv)}', mdfpa_created_at=now()")
        end
        client.close
      end
      UserMailer.warn_pixtech(imgs, imgs_rejected, util, lb, server, server_checked, session_pixtech, nb_ims, params[:original_listname], imgs_not_found).deliver_now
    rescue => error
      AdminMailer.error_report(Server.find_by_is_self(true).name, 'send_to_MS', error)
    end
  end
  # handle_asynchronously :send_to_MS

  private

  sphinx_scope(:by_date_created) {
    {order: 'date_created DESC'}
  }

  sphinx_scope(:by_asc_created) {
    {order: 'date_created ASC'}
  }

  sphinx_scope(:by_updated_at) {
    {order: 'updated_at DESC'}
  }

  sphinx_scope(:by_asc_updated_at) {
    {order: 'updated_at ASC'}
  }

  sphinx_scope(:by_random) {
    {order: 'RAND()'}
  }

  sphinx_scope(:by_n_per_agency) {
    {group_by: 'provider_id', order_group_by: 'reception_date desc'}
  }

  sphinx_scope(:by_relevance) {
    {}
  }

  sphinx_scope(:by_original_filename) {
    {order: 'original_filename ASC'}
  }

  sphinx_scope(:by_asc_filename) {
    {order: 'original_filename DESC'}
  }

  sphinx_scope(:by_reception_date) {
    {order: 'reception_date DESC'}
  }

  sphinx_scope(:by_asc_date) {
    {order: 'reception_date ASC'}
  }

  sphinx_scope(:by_created_at) {
    {order: 'created_at DESC'}
  }

  sphinx_scope(:by_asc_created_at) {
    {order: 'created_at ASC'}
  }


  def self.since_conditions(since_txt)
    #to_i is automagicaly converting time, the only way to dispell magic I found is this
    current_time = Time.now
    #current_time -= current_time.utc_offset
    upper_bound = 2145913199 # = 2037-12-31
    case since_txt
    when '10_minutes'
      (current_time - 10.minutes).to_i..current_time.to_i
    when '1_hour'
      (current_time - 1.hours).to_i..current_time.to_i
    when '1_day'
      (current_time - 1.day).to_i..current_time.to_i
    when '1_week'
      (current_time - 1.weeks).to_i..current_time.to_i
    when '1_month'
      (current_time - 1.months).to_i..current_time.to_i
    when '3_month'
      (current_time - 3.months).to_i..current_time.to_i
    end
  end



  def self.params_to_conditions(params)
    conditions = {}
    params.each do |k,v|
      conditions[k.to_sym] = Pixways::SearchesHelper.filter_keywords(v) if ( !v.blank? && Image.searchable_fields.include?(k.to_sym) )
    end
    conditions
  end

  def self.params_to_with(params, from=0, current_user_id=nil)
    with = {}

    unless from == 1
      if current_user_id.blank?
        if params['providers'].blank? || params['providers'].count == 0
          current = UserSession.find.user
          providers_list = current.providers.collect{|e| e.id}
        else
          providers_list = params['providers'].keys.collect!{|e| e.to_i}
        end
      else
        if params['provider_id'].blank? || params['provider_id'].count == 0
          current = User.find(current_user_id)
          providers_list = current.providers.collect{|e| e.id}
        else
          providers_list = params['provider_id']
        end
      end
      with[:provider_id] = providers_list.blank? ? 0 : providers_list
    end

    with[:black_and_white] = params['b_and_w'].to_i unless params['b_and_w'].blank? || params['b_and_w'] == 'all'

    if params['ratio'] == 'square'
      with[:ratio] = 0.98..1.02
    elsif params['ratio'] == 'horizontal'
      with[:ratio] = 1.02..9999.0
    elsif params['ratio'] == 'vertical'
      with[:ratio] = 0.01..0.98
    elsif params['ratio'] == 'panoramic'
      with[:ratio] = 1.7..9999.0
    end

    if params['flow'] == 'pp1'
      with[:flow] = 1
    elsif params['flow'] == 'not_pp1'
      with[:flow] = [0,2]
    elsif params['flow'] == 'pp2'
      with[:flow] = 2
    elsif params['flow'] == 'not_pp2'
      with[:flow] = [0,1]
    elsif params['flow'] == 'none'
      with[:flow] = 0
    elsif params['flow'] != 'all' && !params['flow'].blank?
      if params['flow'].include?(',')
        with[:flow] = params['flow'].split(',').map(&:to_i)
      else
        with[:flow] = params['flow']
      end
    end

    if params['media_typ'] == 'photos'
      with[:fonds] = 0
    elsif params['media_typ'] == 'videos'
      with[:fonds] = 1
    end

    with[:private_image]  = 0
    with[:content_error]  = 0

    with[:pp_category_id] = params['pp_category_id'] unless params['pp_category_id'].blank? || params['pp_category_id']=='all' #|| params['pp_category_id']==['all'] #for multiple selection

    with[:updated_at] = Pixways::SearchesHelper.dates_to_range('',params['search_time']) if params['search_time']
    if params[:search_since] && params[:search_since] != 'all'
      with[:reception_date] = Image.since_conditions(params[:search_since])
    end
    with[:reception_date] = Pixways::SearchesHelper.dates_to_range(params['reception_date_begin'], params['reception_date_end']) unless (params['reception_date_begin'].blank? && params['reception_date_end'].blank?)
    with[:date_created]   = Pixways::SearchesHelper.dates_to_range(params['date_created_begin'], params['date_created_end'])     unless (params['date_created_begin'].blank? && params['date_created_end'].blank?)

    with
  end

  def self.uploads_to_csv(ims)
    export = ''
    export.encode!('UTF-8')
    CSV(export, {col_sep: ';'}) do |csv|
      csv << [
        'date',
        'nom fichier',
        'ville',
        'photographe',
        'titre',
        'crédit'
      ]
      ims.each do |i|
        csv << [I18n.l(i.updated_at), i.original_filename, i.provider.name, i.creator, i.normalized_credit]
      end
    end
    export
  end

  def self.export_to_csv(medias_res, session_provhd, current_user, session_pixtech, session_service_name, session_creator_word)
    export = ''
    export.encode!('UTF-8')
    CSV(export, {col_sep: ';'}) do |csv|
      if current_user.is_superadmin?
        csv << Image.searchable_fields.collect do |k|
          case k.to_s
          when 'file_name'
            I18n.t("file_name",service_name: session_service_name)
          when 'creator'
            I18n.t("creator_iptc",creator_word: session_creator_word).capitalize
          else
            I18n.t(k)
          end
        end
      elsif current_user.is_provider_admin? && !session_pixtech.blank?
        fields_to_export = Pixways.get_pixtech_param_value(session_pixtech,'search_export_fields')
        csv << fields_to_export.split(',').collect{|k| I18n.t(k)} unless fields_to_export.blank?
      end
      i = 0
      medias_res.each do |m|
        if current_user.is_superadmin?
          csv << Image.searchable_fields.collect{|k| m.send(k)}
          i += 1
        elsif current_user.is_provider_admin? && !session_pixtech.blank? && !fields_to_export.blank?
          csv << fields_to_export.split(',').collect{|k| m.send(k)}
          i += 1
        elsif session_provhd[m.provider_id]==1
          csv << [m.original_filename]
          i += 1
        end
      end
      csv << [I18n.t(:export_empty)] if i==0
    end
    export
  end

  def self.export_authors_list(authors, creator_word, provider_word, session_pixtech, show_providers_panel)
    export = ''
    export = "\xEF\xBB\xBF" #add BOM so Excel knows it is UTF-8 encoding
    CSV(export, {col_sep: ';', encoding: 'UTF-8'}) do |csv|
      if Server.itself?(PIXADMIN_SERVER_NAME)
        if Pixways.get_pixtech_param_value(session_pixtech,'use_numadh')=='true'
          csv << [I18n.t(creator_word).capitalize, I18n.t(provider_word,count:1), "Numéro d'adhérent", 'Adresse email', 'Nb de photos base interne', 'Nb de photos PP1', 'Nb de photos PP2']
          authors.each do |k, v|
            csv << [v[0],v[1],v[2],v[7],v[3],v[4],v[5]]
          end
        elsif Pixways.get_pixtech_param_value(session_pixtech,'automatic_images_flow')=='true'
          csv << [I18n.t(creator_word).capitalize, I18n.t(provider_word,count:1), 'Nombre de photos']
          authors.each do |k, v|
            csv << [v[0],v[1],v[3]]
          end
        else
          csv << [I18n.t(creator_word).capitalize, I18n.t(provider_word,count:1), 'Adresse email', 'Nb de photos base interne', 'Nb de photos PP1', 'Nb de photos PP2']
          authors.each do |k, v|
            csv << [v[0],v[1],v[7],v[3],v[4],v[5]]
          end
        end
      else
        if show_providers_panel
          csv << [I18n.t(creator_word).capitalize, I18n.t(provider_word,count:1), 'Nombre de photos']
          authors.each do |k, v|
            csv << [k[2],k[1],v]
          end
        else
          csv << [I18n.t(creator_word).capitalize, 'Nombre de photos']
          authors.each do |k, v|
            csv << [k,v]
          end
        end
      end
    end
    export
  end

end