class WeatherArt < ApplicationRecord
  extend FriendlyId
  friendly_id :weather_date, use: :slugged

  belongs_to :city
  has_one_attached :image

  has_many :visits, class_name: "Ahoy::Visit", foreign_key: :weather_art_id
  has_many :events, class_name: "Ahoy::Event", foreign_key: :weather_art_id

  validates :weather_date, presence: true
  validates :city_id, presence: true

  scope :latest, ->(limit = 100) {
    order(created_at: :desc).limit(limit)
  }

  scope :by_popularity, ->(limit = 100) {
    if ActiveRecord::Base.connection.adapter_name.downcase == "sqlite"
      joins("LEFT JOIN ahoy_events ON json_extract(ahoy_events.properties, '$.weather_art_id') = weather_arts.id
             AND json_extract(ahoy_events.properties, '$.event_type') = 'weather_art_view'")
        .group("weather_arts.id")
        .select("weather_arts.*, COUNT(ahoy_events.id) as visit_count")
        .order("visit_count DESC").limit(limit)
    else
      joins("LEFT JOIN ahoy_events ON (ahoy_events.properties::jsonb->>'weather_art_id')::integer = weather_arts.id
             AND ahoy_events.properties::jsonb->>'event_type' = 'weather_art_view'")
        .group("weather_arts.id")
        .select("weather_arts.*, COUNT(ahoy_events.id) as visit_count")
        .order("visit_count DESC").limit(limit)
    end
  }

  scope :random, ->(limit = 3) {
    if ActiveRecord::Base.connection.adapter_name.downcase == "postgresql"
      # PostgreSQL 优化版本
      order(Arel.sql("RANDOM()")).limit(limit)
    elsif ActiveRecord::Base.connection.adapter_name.downcase == "mysql2"
      # MySQL 优化版本
      order(Arel.sql("RAND()")).limit(limit)
    else
      # SQLite 或其他数据库的通用版本
      order(Arel.sql("RANDOM()")).limit(limit)
    end
  }

  def should_generate_new_friendly_id?
    weather_date_changed? || city_id_changed? || super
  end

  def to_s
    "#{city.name} - #{weather_date.strftime('%Y-%m-%d')}"
  end

  def self.ransackable_associations(auth_object = nil)
    [ "city", "image_attachment", "image_blob" ]
  end

  def self.ransackable_attributes(auth_object = nil)
    [ "city_id", "cloud", "created_at", "description", "feeling_temp", "humidity", "id", "id_value", "precipitation", "pressure", "prompt", "temperature", "updated_at", "visibility", "weather_date", "wind_scale", "wind_speed" ]
  end

  def view_count
    if ActiveRecord::Base.connection.adapter_name.downcase == "sqlite"
      Ahoy::Event.where("json_extract(properties, '$.event_type') = 'weather_art_view' AND json_extract(properties, '$.weather_art_id') = ?", self.id).count
    else
      Ahoy::Event.where("properties::jsonb->>'event_type' = 'weather_art_view' AND (properties::jsonb->>'weather_art_id')::integer = ?", self.id).count
    end
  end

  def formatted_time(type = :date, use_local_timezone = false)
    # 获取时区
    timezone_info = city&.country&.timezones.present? ?
                      eval(self.city.country.timezones).first :
                      { "zoneName" => "UTC", "gmtOffsetName" => "UTC+00:00" }

    # 设置时区对象
    time_zone = ActiveSupport::TimeZone[timezone_info["zoneName"]] ||
      ActiveSupport::TimeZone["UTC"]

    case type
    when :date
      # 格式化日期
      self&.weather_date&.strftime("%B %d, %Y")
    when :time
      # 获取时间
      time = updated_at

      if use_local_timezone
        # 使用本地时区
        local_time = time.in_time_zone(time_zone)
        "#{local_time.strftime('%H:%M')} #{timezone_info['gmtOffsetName']}"
      else
        # 使用 UTC
        "#{time.utc.strftime('%H:%M')} UTC"
      end
    end
  end

  def image_url
    image.attached? ? image.blob : nil
  end

  def webp_image
    return nil unless image.attached?

    image.variant(
      format: "webp",
      saver: {
        quality: 100,
        strip: true,   # 移除元数据以减小文件大小
        interlace: "plane"  # 渐进式加载
      }
    )
  end

  # 添加图片变体处理
  PREVIEW_DIMENSIONS = {
    big: [ 1792, 1024 ],
    medium: [ 896, 512 ],
    small: [ 448, 256 ]
  }.freeze
  def preview_image(size = :medium)
    return nil unless image.attached?

    width, height = PREVIEW_DIMENSIONS[size] || PREVIEW_DIMENSIONS[:medium]

    image.variant(
      resize_to_limit: [ width, height ],
      format: "webp",
      saver: {
        quality: 75,
        strip: true,   # 移除元数据以减小文件大小
        interlace: "plane"  # 渐进式加载
      }
    )
  end

  def watermarked_image
    return nil unless image.attached?

    overlay_text = create_overlay_text

    image.variant(
      composite: [ {
                    input: overlay_text,
                    gravity: "southeast"
                  } ]
    )
  end

  private

  def create_overlay_text
    {
      create: {
        width: 400,
        height: 100,
        background: [ 0, 0, 0, 0.5 ]  # 半透明黑色背景
      },
      "svg-overlay": %(
        <svg width="400" height="100">
          <text x="20" y="40"
                style="fill: white; font-family: Arial; font-size: 20px;">
            #{city.name} - #{weather_date.strftime('%Y-%m-%d')}
          </text>
          <text x="20" y="70"
                style="fill: white; font-family: Arial; font-size: 20px;">
            © todayaiweather.com
          </text>
        </svg>
      )
    }
  end

  def create_text_layer(font_size)
    text = [
      weather_date.strftime("%Y-%m-%d"),
      "#{temperature}°C, #{description}",
      "#{city.name}, #{city.country.name}, #{city.country.region.name}",
      "© todayaiweather.com"
    ].join("\n")

    {
      create: {
        width: 600,
        height: 200,
        background: [ 0, 0, 0, 0 ]
      },
      "svg-overlay": %(
        <svg width="600" height="200">
          <style>
            .text {
              font-family: Arial, sans-serif;
              font-size: #{font_size}px;
            }
            .shadow {
              fill: white;
              stroke: black;
              stroke-width: 2px;
              paint-order: stroke fill;
            }
          </style>
          <text x="20" y="#{font_size + 10}" class="text shadow">#{weather_date.strftime('%Y-%m-%d')}</text>
          <text x="20" y="#{font_size * 2 + 20}" class="text shadow">#{temperature}°C, #{description}</text>
          <text x="20" y="#{font_size * 3 + 30}" class="text shadow">#{city.name}, #{city.country.name}</text>
          <text x="20" y="#{font_size * 4 + 40}" class="text shadow">© todayaiweather.com</text>
        </svg>
      )
    }
  end

  def watermark_command(font_size:, stroke_width:, spacing:)
    date_str = weather_date.strftime("%Y-%m-%d")
    weather_info = "#{temperature}°C, #{description}"
    location_info = "#{city.name}, #{city.country.name}, #{city.country.region.name}"
    copyright = "© todayaiweather.com"

    "gravity southeast " \
      "fill white " \
      "font Arial " \
      "pointsize #{font_size} " \
      "stroke black " \
      "strokewidth #{stroke_width} " \
      "text 30,#{spacing * 12} '#{copyright}' " \
      "text 30,#{spacing * 8} '#{location_info}' " \
      "text 30,#{spacing * 4} '#{weather_info}' " \
      "text 30,#{spacing} '#{date_str}'"
  end

  def watermark_text
    date_str = weather_date.strftime("%Y-%m-%d")
    weather_info = "#{temperature}°C, #{description}"
    location_info = "#{city.name}, #{city.country.name}, #{city.country.region.name}"
    copyright = "© todayaiweather.com"

    [
      "text 30,120 '#{copyright}'",
      "text 30,80 '#{location_info}'",
      "text 30,40 '#{weather_info}'",
      "text 30,0 '#{date_str}'"
    ].join(" ")
  end
end