# frozen_string_literal: true

# Signs the url
class IamSigner
  require "google/cloud/storage"
  require "google/apis/iamcredentials_v1"

  def initialize(service_account_email)
    @service_account_email = service_account_email
    @iam_service = Google::Apis::IamcredentialsV1::IAMCredentialsService.new
    @iam_service.authorization = Google::Auth.get_application_default(["https://www.googleapis.com/auth/cloud-platform"])
  end

  def sign(digest_or_string, string_to_sign = nil)
    # If two arguments, the second one is the string to sign
    # If one argument, it should be the string to sign
    actual_string = string_to_sign || digest_or_string

    sign_blob_request = Google::Apis::IamcredentialsV1::SignBlobRequest.new(
      payload: actual_string
    )

    response = @iam_service.sign_service_account_blob(
      "projects/-/serviceAccounts/#{@service_account_email}",
      sign_blob_request
    )

    response.signed_blob
  end

  def client_email
    @service_account_email
  end

  def issuer
    @service_account_email
  end
end

# Sprint GCS Class
class SprintGCS
  require "google/cloud/storage"

  def self.signed_upload_url(path:, content_type:, expires_in: 10 * 60)
    service_account_email = "191960276900-compute@developer.gserviceaccount.com"
    signer = IamSigner.new(service_account_email)

    object_key = path
    storage = Google::Cloud::Storage.new
    bucket_name = "sprint-qualplatform"
    file = storage.bucket(bucket_name).file(path)
    file ||= storage.bucket(bucket_name).create_file(StringIO.new(""), path) # optional pre-create to avoid 404s
    url = storage.signed_url(
      bucket_name,
      object_key,
      method: "PUT",
      headers: { "Content-Type" => content_type },
      version: :v4,
      expires: expires_in,
      issuer: service_account_email,
      signer:
    )
    {
      headers: { "Content-Type" => content_type },
      url:,
      object_key:
    }
  end

  def self.signed_url(bucket_name:, file_path:, expires_in: 60.minutes)
    service_account_email = "191960276900-compute@developer.gserviceaccount.com"
    signer = IamSigner.new(service_account_email)

    storage = Google::Cloud::Storage.new
    bucket = storage.bucket(bucket_name)
    file = bucket.file(file_path)

    url = file.signed_url(
      version: :v4,
      method: "GET",
      expires: 900,
      issuer: service_account_email,
      signer:
    )
  rescue StandardError => e
    Rails.logger.fatal("Error: #{e.inspect}")
    ""
  end

  def self.download(bucket_name:, file_path:)
    storage = Google::Cloud::Storage.new(project_id: Rails.application.credentials.gcs.project)
    bucket  = storage.bucket(bucket_name)
    file    = bucket.file(file_path)

    raise "File not found in GCS: #{file_path}" unless file

    # Define the local destination path
    local_path = Rails.root.join("tmp", File.basename(file_path))

    # Download the file to local_path
    file.download(local_path)

    local_path.to_s
  end

  def self.upload(file:, path:, bucket_name: "sprint-qualplatform")
    storage = Google::Cloud::Storage.new(
      project_id: Rails.application.credentials.gcs.project
    )
    bucket = storage.bucket bucket_name
    blob = bucket.create_file file, path
    blob.public_url
  end
end
