# send as utc
# start_date start_time end_date end_time

module Promotions
  class ScheduledVod < Promotions::Base
    attributes :user_id, :login, :priority, :title, :image_url,
               :inserted_at, :updated_at, :sponsored, :reporter,
               :id, :vod_id, :description_raw, :description_rendered,
               :languages, :start_date, :start_date_part, :start_time_part,
               :end_date, :end_date_part, :end_time_part

    validates :vod_id, :priority, :title, :description_raw, :image_url, :start_date, :end_date, presence: true
    validate :validate_languages

    self.base_path = '/admin/vods'
    self.entity = 'scheduled_vod'
    self.ignored_audit_updates = [:id, :user_id]

    def initialize(params = {}, options = {})
      super
      unless @start_date.nil?
        start_date = DateTime.strptime(@start_date, '%Y-%m-%dT%H:%M:%S%z')
        @start_time_part = start_date.strftime('%H:%M')
        @start_date_part = start_date.strftime('%Y-%m-%d')
      end

      unless @end_date.nil?
        end_date = DateTime.strptime(@end_date, '%Y-%m-%dT%H:%M:%S%z')
        @end_time_part = end_date.strftime('%H:%M')
        @end_date_part = end_date.strftime('%Y-%m-%d')
      end
      set_start_date
      set_end_date
    end

    # !(v === false) because if v = false then v.blank? === true, therefore the change is not tracked
    def update_body
      set_end_date
      set_start_date
      params = attributes.except(:inserted_at, :login, :reporter, :updated_at, :user_id, :id, :start_date_part, :start_time_part, :end_date_part, :end_time_part).delete_if{ |k, v| v.blank? && !(v === false) }
      {scheduled_vod: params}
    end

    def save_body
      params = attributes.except(:reporter, :id, :description_rendered, :start_date_part, :start_time_part, :end_date_part, :end_time_part)
      {scheduled_vod: params}
    end

    def validate_languages
      @languages = @languages.to_s.split(',')
      # if languages is not an array and an element does not match regex or all languages in array are blank add error
      if (!@languages.is_a?(Array) || @languages.detect{|language| !/\A[a-z]+(-[a-z]+)?\z/.match(language)}) && !@languages.all?(&:blank?)
        errors.add(:languages, 'Invalid language format. Acceptable languages should be languages like en, en-gb, en,en-gb')
      elsif @languages.all?(&:blank?)
        @languages = nil
      end
    end

    def validate_url?
      begin
        URI.parse(image_url) && !image_url.host.nil?
      rescue URI::InvalidURIError
        false
      end
    end

    # still defined in each service level class because the definition of attributes rewrites the instantiation
    # of the base level attributes
    def sponsored
      self.class.booleanize @sponsored
    end

    def priority
      @priority.to_i
    end

    def duplicate
      new_record = self.class.new
      new_record.attributes = self.attributes.except(:id, :updated_at, :inserted_at)
      new_record
    end
    private

    def set_end_date
      unless @end_date_part.nil? && @end_time_part.nil?
        begin
          @end_date = DateTime.strptime("#{@end_date_part}T#{@end_time_part}", "%Y-%m-%dT%H:%M").to_s(:db) + "Z"
        rescue
          errors.add(:end_date, 'Invalid End Date Format: YYYY-MM-DD HH:mm expected')
        end
      end
    end

    def set_start_date
      unless @start_date_part.nil? && @start_time_part.nil?
        begin
          @start_date = DateTime.strptime("#{@start_date_part}T#{@start_time_part}", "%Y-%m-%dT%H:%M").to_s(:db) + "Z"
        rescue
          errors.add(:start_date, 'Invalid Start Date Format: YYYY-MM-DD HH:mm expected')
        end
      end
    end
  end
end
