module Billing
  class IssueInvoice
    class Error < StandardError; end

    def self.call(invoice:, pdf: nil)
      new(invoice: invoice, pdf: pdf).call
    end

    def initialize(invoice:, pdf: nil)
      @invoice = invoice
      @pdf = pdf
    end

    def call
      raise Error, "Carica il file PDF della fattura" if @pdf.blank? && !@invoice.pdf.attached?

      attach_pdf!(@pdf) if @pdf.present?
      raise Error, "PDF mancante" unless @invoice.pdf.attached?

      recipient = @invoice.club.billing_email.presence
      raise Error, "Email di fatturazione non configurata per la società" if recipient.blank?

      @invoice.update!(status: "issued")

      Billing::InvoiceMailer.with(invoice: @invoice).invoice_pdf.deliver_now
      @invoice.update!(status: "sent", emailed_at: Time.current)

      @invoice
    end

    def attach_pdf!(upload)
      if upload.respond_to?(:tempfile)
        @invoice.pdf.attach(
          io: upload.tempfile,
          filename: upload.original_filename,
          content_type: upload.content_type.presence || "application/pdf"
        )
      elsif upload.is_a?(Hash)
        @invoice.pdf.attach(**upload)
      elsif upload.is_a?(StringIO)
        @invoice.pdf.attach(io: upload, filename: "fattura.pdf", content_type: "application/pdf")
      else
        @invoice.pdf.attach(upload)
      end
    end
  end
end
