# frozen_string_literal: true

module Api
  module V1
    class CollectionArtifactsController < ApiController
      # Read actions: look up user from params, check privacy
      before_action :set_target_user, only: %i[index show]
      before_action :check_collection_access, only: %i[index show]
      before_action :set_collection_artifact_for_read, only: %i[show]

      # Write actions: require auth, use current_user
      before_action :restrict_access, only: %i[create update destroy batch batch_destroy import preview_sync]
      before_action :set_collection_artifact_for_write, only: %i[update destroy]

      def index
        @collection_artifacts = @target_user.collection_artifacts.includes(:artifact)

        # Apply filters (array_param splits comma-separated values for OR logic)
        @collection_artifacts = @collection_artifacts.where(artifact_id: params[:artifact_id]) if params[:artifact_id]
        @collection_artifacts = @collection_artifacts.where(element: array_param(:element)) if params[:element]
        @collection_artifacts = @collection_artifacts.by_proficiency(array_param(:proficiency)) if params[:proficiency].present?
        @collection_artifacts = @collection_artifacts.joins(:artifact).where(artifacts: { rarity: array_param(:rarity) }) if params[:rarity]

        # Skill filters - each slot uses OR logic, slots combined with AND logic
        @collection_artifacts = @collection_artifacts.with_skill_in_slot(1, params[:skill1]) if params[:skill1].present?
        @collection_artifacts = @collection_artifacts.with_skill_in_slot(2, params[:skill2]) if params[:skill2].present?
        @collection_artifacts = @collection_artifacts.with_skill_in_slot(3, params[:skill3]) if params[:skill3].present?
        @collection_artifacts = @collection_artifacts.with_skill_in_slot(4, params[:skill4]) if params[:skill4].present?

        @collection_artifacts = @collection_artifacts.paginate(page: params[:page], per_page: params[:limit] || 50)

        render json: Api::V1::CollectionArtifactBlueprint.render(
          @collection_artifacts,
          root: :artifacts,
          meta: pagination_meta(@collection_artifacts)
        )
      end

      def show
        render json: Api::V1::CollectionArtifactBlueprint.render(
          @collection_artifact,
          view: :full
        )
      end

      def create
        @collection_artifact = current_user.collection_artifacts.build(collection_artifact_params)

        if @collection_artifact.save
          render json: Api::V1::CollectionArtifactBlueprint.render(
            @collection_artifact,
            view: :full
          ), status: :created
        else
          render_validation_error_response(@collection_artifact)
        end
      end

      def update
        if @collection_artifact.update(collection_artifact_params)
          render json: Api::V1::CollectionArtifactBlueprint.render(
            @collection_artifact,
            view: :full
          )
        else
          render_validation_error_response(@collection_artifact)
        end
      end

      def destroy
        @collection_artifact.destroy
        head :no_content
      end

      # POST /collection/artifacts/batch
      # Creates multiple collection artifacts in a single request
      def batch
        items = batch_artifact_params[:collection_artifacts] || []
        created = []
        errors = []

        ActiveRecord::Base.transaction do
          items.each_with_index do |item_params, index|
            collection_artifact = current_user.collection_artifacts.build(item_params)

            if collection_artifact.save
              created << collection_artifact
            else
              errors << {
                index: index,
                artifact_id: item_params[:artifact_id],
                error: collection_artifact.errors.full_messages.join(', ')
              }
            end
          end
        end

        status = errors.any? ? :multi_status : :created

        render json: Api::V1::CollectionArtifactBlueprint.render(
          created,
          root: :artifacts,
          meta: { created: created.size, errors: errors }
        ), status: status
      end

      # POST /collection/artifacts/import
      # Imports artifacts from game JSON data
      #
      # @param data [Hash] Game data containing artifact list
      # @param update_existing [Boolean] Whether to update existing artifacts (default: false)
      # @param is_full_inventory [Boolean] Whether this represents the user's complete inventory (default: false)
      # @param reconcile_deletions [Boolean] Whether to delete items not in the import (default: false)
      def import
        game_data = import_params[:data]

        unless game_data.present?
          return render json: { error: 'No data provided' }, status: :bad_request
        end

        service = ArtifactImportService.new(
          current_user,
          game_data,
          update_existing: import_params[:update_existing] == true,
          is_full_inventory: import_params[:is_full_inventory] == true,
          reconcile_deletions: import_params[:reconcile_deletions] == true,
          filter: import_params[:filter]
        )

        result = service.import

        status = result.success? ? :created : :multi_status

        render json: {
          success: result.success?,
          created: result.created&.size || 0,
          updated: result.updated&.size || 0,
          skipped: result.skipped&.size || 0,
          errors: result.errors || [],
          reconciliation: result.reconciliation
        }, status: status
      end

      # POST /collection/artifacts/preview_sync
      # Previews what would be deleted in a full sync operation
      #
      # @param data [Hash] Game data containing artifact list
      # @return [JSON] List of items that would be deleted
      def preview_sync
        game_data = import_params[:data]
        filter = import_params[:filter]

        unless game_data.present?
          return render json: { error: 'No data provided' }, status: :bad_request
        end

        service = ArtifactImportService.new(current_user, game_data, filter: filter)
        items_to_delete = service.preview_deletions

        render json: {
          will_delete: items_to_delete.map do |ca|
            {
              id: ca.id,
              game_id: ca.game_id,
              name: ca.artifact&.name_en,
              granblue_id: ca.artifact&.granblue_id,
              element: ca.element,
              level: ca.level
            }
          end,
          count: items_to_delete.size
        }
      end

      # DELETE /collection/artifacts/batch_destroy
      # Deletes multiple collection artifacts in a single request
      def batch_destroy
        ids = batch_destroy_params[:ids] || []
        deleted_count = current_user.collection_artifacts.where(id: ids).destroy_all.count

        render json: {
          meta: { deleted: deleted_count }
        }, status: :ok
      end

      private

      def set_target_user
        @target_user = User.find(params[:user_id])
      rescue ActiveRecord::RecordNotFound
        render json: { error: 'User not found' }, status: :not_found
      end

      def check_collection_access
        return if @target_user.nil?

        return if @target_user.collection_viewable_by?(current_user)

        render json: { error: 'You do not have permission to view this collection' }, status: :forbidden
      end

      def set_collection_artifact_for_read
        @collection_artifact = @target_user.collection_artifacts.find(params[:id])
      rescue ActiveRecord::RecordNotFound
        raise CollectionErrors::CollectionItemNotFound.new('artifact', params[:id])
      end

      def set_collection_artifact_for_write
        @collection_artifact = current_user.collection_artifacts.find(params[:id])
      rescue ActiveRecord::RecordNotFound
        raise CollectionErrors::CollectionItemNotFound.new('artifact', params[:id])
      end

      def collection_artifact_params
        params.require(:collection_artifact).permit(
          :artifact_id, :element, :proficiency, :level, :nickname, :reroll_slot,
          skill1: %i[modifier strength level],
          skill2: %i[modifier strength level],
          skill3: %i[modifier strength level],
          skill4: %i[modifier strength level]
        )
      end

      def batch_artifact_params
        params.permit(collection_artifacts: [
          :artifact_id, :element, :proficiency, :level, :nickname, :reroll_slot,
          { skill1: %i[modifier strength level] },
          { skill2: %i[modifier strength level] },
          { skill3: %i[modifier strength level] },
          { skill4: %i[modifier strength level] }
        ])
      end

      def import_params
        {
          update_existing: params[:update_existing],
          is_full_inventory: params[:is_full_inventory],
          reconcile_deletions: params[:reconcile_deletions],
          data: params[:data]&.to_unsafe_h,
          filter: params[:filter]&.to_unsafe_h
        }
      end

      def batch_destroy_params
        params.permit(ids: [])
      end

      def array_param(key)
        params[key]&.to_s&.split(',')
      end
    end
  end
end
