module Billing
  module Stripe
    class CheckoutSession
      VALID_PLANS = %w[premium_light premium_full].freeze

      def initialize(club:, user:, plan_slug: "premium_light", interval: PriceCatalog::DEFAULT_INTERVAL)
        @club = club
        @user = user
        @plan_slug = plan_slug.to_s
        @interval = PriceCatalog.normalize_interval(interval)
      end

      def url
        raise "Stripe non configurato" unless MatchLiveTv.stripe_enabled?
        raise "Piano non valido" unless VALID_PLANS.include?(@plan_slug)

        price_id = PriceCatalog.price_id(plan_slug: @plan_slug, interval: @interval)

        customer_id = ensure_customer_id!
        CustomerSync.call(club: @club, customer_id: customer_id)

        session = ::Stripe::Checkout::Session.create(
          mode: "subscription",
          customer: customer_id,
          line_items: [{ price: price_id, quantity: 1 }],
          success_url: success_url,
          cancel_url: cancel_url,
          metadata: {
            club_id: @club.id,
            user_id: @user.id,
            plan_slug: @plan_slug,
            billing_interval: @interval
          },
          subscription_data: {
            metadata: {
              club_id: @club.id,
              plan_slug: @plan_slug,
              billing_interval: @interval
            }
          },
          billing_address_collection: "required",
          customer_update: { address: "auto", name: "auto" },
          allow_promotion_codes: true
        )
        session.url
      end

      def portal_url
        raise "Stripe non configurato" unless MatchLiveTv.stripe_enabled?

        customer_id = ensure_customer_id!
        CustomerSync.call(club: @club, customer_id: customer_id)
        session = ::Stripe::BillingPortal::Session.create(
          customer: customer_id,
          return_url: billing_url
        )
        session.url
      end

      private

      def ensure_customer_id!
        sub = @club.subscription || @club.build_subscription(plan: Plan["free"], status: "active")
        return sub.stripe_customer_id if sub.stripe_customer_id.present?

        customer = ::Stripe::Customer.create(
          email: @user.email,
          name: @club.billing_legal_name.presence || @club.name,
          metadata: { club_id: @club.id }
        )
        sub.update!(stripe_customer_id: customer.id)
        customer.id
      end

      def success_url
        "#{billing_url}?checkout=success&session_id={CHECKOUT_SESSION_ID}"
      end

      def cancel_url
        "#{billing_url}?checkout=canceled"
      end

      def billing_url
        "#{MatchLiveTv.app_public_url.chomp('/')}/clubs/#{@club.id}/billing"
      end
    end
  end
end
