# frozen_string_literal: true

class Api::V1::Maps::HexagonsController < ApiController
  skip_before_action :authenticate_api_key, if: :public_sharing_request?

  def index
    context = resolve_hexagon_context

    result = Maps::HexagonRequestHandler.new(
      params: params,
      user: context[:user] || current_api_user,
      stat: context[:stat],
      start_date: context[:start_date],
      end_date: context[:end_date]
    ).call

    render json: result
  rescue ActionController::ParameterMissing => e
    render json: { error: "Missing required parameter: #{e.param}" }, status: :bad_request
  rescue ActionController::BadRequest => e
    render json: { error: e.message }, status: :bad_request
  rescue ActiveRecord::RecordNotFound => e
    render json: { error: 'Shared stats not found or no longer available' }, status: :not_found
  rescue Stats::CalculateMonth::PostGISError => e
    render json: { error: e.message }, status: :bad_request
  rescue StandardError => _e
    handle_service_error
  end

  def bounds
    context = resolve_hexagon_context

    result = Maps::BoundsCalculator.new(
      user: context[:user] || context[:target_user],
      start_date: context[:start_date],
      end_date: context[:end_date]
    ).call

    if result[:success]
      render json: result[:data]
    else
      render json: {
        error: result[:error],
        point_count: result[:point_count]
      }, status: :not_found
    end
  rescue ActiveRecord::RecordNotFound => e
    render json: { error: 'Shared stats not found or no longer available' }, status: :not_found
  rescue ArgumentError => e
    render json: { error: e.message }, status: :bad_request
  rescue Maps::BoundsCalculator::NoUserFoundError => e
    render json: { error: e.message }, status: :not_found
  rescue Maps::BoundsCalculator::NoDateRangeError => e
    render json: { error: e.message }, status: :bad_request
  end

  private

  def resolve_hexagon_context
    return resolve_public_sharing_context if public_sharing_request?

    resolve_authenticated_context
  end

  def resolve_public_sharing_context
    stat = Stat.find_by(sharing_uuid: params[:uuid])
    raise ActiveRecord::RecordNotFound unless stat&.public_accessible?

    {
      user: stat.user,
      start_date: Date.new(stat.year, stat.month, 1).beginning_of_day.iso8601,
      end_date: Date.new(stat.year, stat.month, 1).end_of_month.end_of_day.iso8601,
      stat: stat
    }
  end

  def resolve_authenticated_context
    {
      user: current_api_user,
      start_date: params[:start_date],
      end_date: params[:end_date],
      stat: nil
    }
  end

  def handle_service_error
    render json: { error: 'Failed to generate hexagon grid' }, status: :internal_server_error
  end

  def public_sharing_request?
    params[:uuid].present?
  end
end
