# frozen_string_literal: true

# Validates that a granblue_id has accessible images on the Granblue Fantasy game server.
# Used to verify that a summon ID is valid before creating a database record.
#
# @example Validate a summon ID
#   validator = SummonImageValidator.new("2040001000")
#   if validator.valid?
#     puts validator.image_urls
#   else
#     puts validator.error_message
#   end
class SummonImageValidator
  BASE_URL = 'https://prd-game-a-granbluefantasy.akamaized.net/assets_en/img/sp/assets/summon'

  SIZES = {
    main: 'ls',
    grid: 'party_sub',
    square: 's'
  }.freeze

  attr_reader :granblue_id, :error_message, :image_urls

  def initialize(granblue_id)
    @granblue_id = granblue_id.to_s
    @error_message = nil
    @image_urls = {}
  end

  # Validates the granblue_id by checking if the main image is accessible.
  #
  # @return [Boolean] true if valid, false otherwise
  def valid?
    return invalid_format unless valid_format?

    check_image_accessibility
  end

  # Checks if a summon with this granblue_id already exists in the database.
  #
  # @return [Boolean] true if exists, false otherwise
  def exists_in_db?
    Summon.exists?(granblue_id: @granblue_id)
  end

  private

  def valid_format?
    @granblue_id.present? && @granblue_id.match?(/^\d{10}$/)
  end

  def invalid_format
    @error_message = 'Invalid granblue_id format. Must be a 10-digit number.'
    false
  end

  def check_image_accessibility
    # Summons use the raw granblue_id without variant suffix for base image
    variant_id = @granblue_id

    # Build image URLs for all sizes
    SIZES.each do |size_name, directory|
      url = "#{BASE_URL}/#{directory}/#{variant_id}.jpg"
      @image_urls[size_name] = url
    end

    # Check if the main image is accessible via HEAD request
    main_url = @image_urls[:main]

    begin
      uri = URI.parse(main_url)
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      http.open_timeout = 5
      http.read_timeout = 5
      # Skip CRL verification in development (Akamai CDN can have CRL issues locally)
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE if Rails.env.development?

      request = Net::HTTP::Head.new(uri.request_uri)
      response = http.request(request)

      if response.code == '200'
        true
      else
        @error_message = "No images found for this granblue_id (HTTP #{response.code})"
        false
      end
    rescue Net::OpenTimeout, Net::ReadTimeout => e
      @error_message = "Request timed out while validating image URL: #{e.message}"
      false
    rescue StandardError => e
      @error_message = "Failed to validate image URL: #{e.message}"
      false
    end
  end
end
