class Draft < ApplicationRecord
  EXPIRES_IN = 3.days
  KEY_MAX_LEN = 12

  icons = [
    Forecast::WEATHER_SYM_CLEAR_N,
    Forecast::WEATHER_SYM_CLEAR_D,
    Forecast::WEATHER_SYM_RAIN,
    Forecast::WEATHER_SYM_SNOW,
    Forecast::WEATHER_SYM_CLOUD,
    Forecast::WEATHER_SYM_THUNDER,
  ]
  icons += icons.map {|i1| icons.map {|i2| i1 == i2 ? nil : i1+i2 }}.flatten.compact
  icons -= [
    Forecast::WEATHER_SYM_CLEAR_N+Forecast::WEATHER_SYM_CLEAR_D,
    Forecast::WEATHER_SYM_CLEAR_D+Forecast::WEATHER_SYM_CLEAR_N,
  ]
  ICONS = icons.freeze

  FILENAME_MAP = {
    Forecast::WEATHER_SYM_CLEAR_N => 'ClearN',
    Forecast::WEATHER_SYM_CLEAR_D => 'ClearD',
    Forecast::WEATHER_SYM_RAIN    => 'Rain',
    Forecast::WEATHER_SYM_SNOW    => 'Snow',
    Forecast::WEATHER_SYM_CLOUD   => 'Cloud',
    Forecast::WEATHER_SYM_THUNDER => 'Thunder',
  }
  FILENAME_MAP.freeze

  enum day_frame: {white: '@builtin/white', black: '@builtin/black'}, _prefix: 'day_frame'
  belongs_to :user, required: false
  before_save :renew_expire
  after_initialize :set_key
  validates :title, length: { maximum: 60 }
  validates :url, format: { with: %r{\Ahttps?://[a-z0-9-]+(\.[a-z0-9-]+)+}i }, allow_blank: true
  validates :key, uniqueness: true

  icon_styles = {}
  [500, 250, 120, 64].each do |size|
    icon_styles["webp#{size}"] = {geometry: "#{size}x#{size}>", format: "webp", convert_options: "-quality 75"}
    icon_styles["png#{size}"] = {geometry: "#{size}x#{size}>", format: "png"}
  end

  ICONS.each do |i|
    has_attached_file "wi_#{i}", styles: icon_styles.symbolize_keys
    validates_attachment "wi_#{i}",
    content_type: {content_type: /\Aimage\/.*\z/},
    size: { less_than: 20.megabyte }
  end

  def name
    title
  end

  def renew_expire
    self.expires_at = Time.now + EXPIRES_IN
  end

  def set_key(force = false)
    return true if key.present? && !force
    loop do
      self.key = (SecureRandom.random_number(('z'*KEY_MAX_LEN).to_i(36)) + 1).to_s(36).scan(/.{1,4}/).join("-")
      check_cond = {key: self.key}
      persisted? and check_cond[:id] = self.id
      break unless Draft.where(check_cond).exists?
    end
  end

  def to_param
    key
  end

  def theme_definition
    ThemeDefinition.new(draft: self)
  end

  def theme_image_archive
    ICONS.find { |ic| public_send("wi_#{ic}?") } or return nil
    path = _zip_tmp_path('theme-archive')
    Zip::File.open(path, Zip::File::CREATE) do |zf|
      ICONS.each do |ic|
        public_send("wi_#{ic}?") or next
        zf.add "wi-#{ic.chars.map{|c| FILENAME_MAP[c]}.join('_')}.webp", public_send("wi_#{ic}").path(:webp500)
      end
    end
    path
  end

  def orig_archive
    ICONS.find { |ic| public_send("wi_#{ic}?") } or return nil
    path = _zip_tmp_path('orig-archive')
    Zip::File.open(path, Zip::File::CREATE) do |zf|
      ICONS.each do |ic|
        public_send("wi_#{ic}?") or next
        attach = public_send("wi_#{ic}")
        zf.add "Weather_#{ic.chars.map{|c| FILENAME_MAP[c]}.join('-')}#{File.extname(attach.path)}", attach.path
      end
    end
    path
  end

  def as_json(opts = {})
    ret = super(opts)
    ret["path"] = Rails.application.routes.url_helpers.draft_path(self, format: :json)
    ICONS.each do |i|
      public_send("wi_#{i}?") or next
      ret["wi_#{i}_url"] = public_send("wi_#{i}").url(opts[:weather_image_style] || :png120)
    end
    ret
  end

  def img_blank?
    !img_present?
  end

  def img_present?
    ICONS.each do |i|
      public_send("wi_#{i}?") and return true
    end
    return false
  end
end
