# frozen_string_literal: true

module Api
  module V1
    class ArtifactsController < Api::V1::ApiController
      before_action :set_artifact, only: %i[show download_image download_images download_status]

      # GET /artifacts
      def index
        @artifacts = Artifact.all
        @artifacts = @artifacts.where(rarity: params[:rarity]) if params[:rarity].present?
        @artifacts = @artifacts.where(proficiency: params[:proficiency]) if params[:proficiency].present?

        render json: ArtifactBlueprint.render(@artifacts, root: :artifacts)
      end

      # GET /artifacts/:id
      def show
        render json: ArtifactBlueprint.render(@artifact)
      end

      # POST /artifacts/grade
      # Grades artifact skills without persisting. Accepts skill data and returns grade/recommendation.
      #
      # @param artifact_id [String] Optional - ID of base artifact (for quirk detection)
      # @param skill1 [Hash] Skill data with modifier, strength, level
      # @param skill2 [Hash] Skill data with modifier, strength, level
      # @param skill3 [Hash] Skill data with modifier, strength, level
      # @param skill4 [Hash] Skill data with modifier, strength, level
      def grade
        artifact_data = build_gradeable_artifact
        grader = ArtifactGrader.new(artifact_data)

        render json: { grade: grader.grade }
      end

      # POST /artifacts/:id/download_image
      # Synchronously downloads a single image size for the artifact
      #
      # @param size [String] Required - 'square' or 'wide'
      # @param force [Boolean] Optional - Force re-download even if exists
      def download_image
        size = params[:size]
        force = params[:force] == true || params[:force] == 'true'

        unless %w[square wide].include?(size)
          return render json: { error: "Invalid size. Must be 'square' or 'wide'" }, status: :bad_request
        end

        service = ArtifactImageDownloadService.new(@artifact, force: force, size: size, storage: :s3)
        result = service.download

        if result.success?
          render json: { success: true, images: result.images }
        else
          render json: { success: false, error: result.error }, status: :unprocessable_entity
        end
      end

      # POST /artifacts/:id/download_images
      # Asynchronously downloads all images for the artifact via background job
      #
      # @param options.force [Boolean] Optional - Force re-download even if exists
      # @param options.size [String] Optional - 'square', 'wide', or 'all' (default)
      def download_images
        options = params[:options] || {}
        force = options[:force] == true || options[:force] == 'true'
        size = options[:size] || 'all'

        DownloadArtifactImagesJob.perform_later(@artifact.id, force: force, size: size)

        render json: {
          status: 'queued',
          message: "Image download queued for artifact #{@artifact.granblue_id}",
          artifact_id: @artifact.id
        }, status: :accepted
      end

      # GET /artifacts/:id/download_status
      # Returns the current status of a background download job
      def download_status
        status = DownloadArtifactImagesJob.status(@artifact.id)
        render json: status
      end

      private

      def set_artifact
        @artifact = Artifact.find(params[:id])
      rescue ActiveRecord::RecordNotFound
        render_not_found_response('artifact')
      end

      def build_gradeable_artifact
        base_artifact = params[:artifact_id].present? ? Artifact.find_by(id: params[:artifact_id]) : nil

        # Build a simple struct that responds to what ArtifactGrader needs
        OpenStruct.new(
          skill1: grade_params[:skill1] || {},
          skill2: grade_params[:skill2] || {},
          skill3: grade_params[:skill3] || {},
          skill4: grade_params[:skill4] || {},
          artifact: base_artifact || OpenStruct.new(quirk?: false)
        )
      end

      def grade_params
        params.permit(
          :artifact_id,
          skill1: %i[modifier strength level],
          skill2: %i[modifier strength level],
          skill3: %i[modifier strength level],
          skill4: %i[modifier strength level]
        )
      end
    end
  end
end
