module Public
  class ClubsController < WebBaseController
    include BrandingAttachments

    before_action :require_login!
    before_action :set_club, only: %i[show edit update billing checkout portal]
    before_action :require_billing_profile_for_premium_checkout!, only: :checkout

    def new
      redirect_to public_club_path(current_user.primary_club) if current_user.primary_club
    end

    def create
      if current_user.owned_clubs.exists?
        redirect_to public_club_path(current_user.primary_club), alert: "Hai già registrato una società"
        return
      end

      club = Club.new(club_params)
      attach_branding_logo(club)
      club.save!

      ClubMembership.create!(user: current_user, club: club, role: "owner")

      first_team_name = params.dig(:first_team, :name).presence || "Prima squadra"
      club.teams.create!(
        name: first_team_name,
        sport: club.sport
      )

      plan = params[:plan].presence_in(%w[free premium_light premium_full]) || "free"
      Billing::AssignPlan.call(club: club, plan_slug: plan)

      if plan.in?(%w[premium_light premium_full]) && MatchLiveTv.stripe_enabled?
        unless club.billing_profile_complete?
          redirect_to public_club_billing_profile_path(club, plan: plan, interval: checkout_interval_param),
                      alert: "Completa i dati di fatturazione prima di attivare un piano premium."
          return
        end

        interval = checkout_interval_param
        redirect_to public_club_checkout_path(club, plan: plan, interval: interval)
      else
        redirect_to public_club_path(club), notice: "Società e prima squadra create."
      end
    rescue ActiveRecord::RecordInvalid => e
      flash.now[:alert] = e.record.errors.full_messages.join(", ")
      render :new, status: :unprocessable_entity
    end

    def show
      require_club_owner!(@club)
      apply_checkout_flash!
      @entitlements_team = @club.teams.first
      @entitlements = @entitlements_team&.entitlements
      @teams = @club.teams.order(:name)
    end

    def edit
      require_club_owner!(@club)
    end

    def update
      require_club_owner!(@club)
      @club.assign_attributes(club_params)
      attach_branding_logo(@club)
      @club.save!
      redirect_to public_club_path(@club), notice: "Società aggiornata."
    rescue ActiveRecord::RecordInvalid => e
      flash.now[:alert] = e.record.errors.full_messages.join(", ")
      render :edit, status: :unprocessable_entity
    end

    def billing
      require_club_owner!(@club)
      sync_checkout_return!
      finalize_subscription_if_due!
      @subscription = @club.subscription&.reload
      apply_checkout_flash!
      @team = @club.teams.first!
      @entitlements = @team.entitlements
      @plans = Plan.ordered
      @payments = @club.billing_payments.recent.includes(:invoice).limit(50)
    end

    def checkout
      require_club_owner!(@club)
      unless MatchLiveTv.stripe_enabled?
        redirect_to public_club_billing_path(@club), alert: "Pagamenti non ancora configurati sul server"
        return
      end

      plan_slug = params[:plan].presence_in(%w[premium_light premium_full]) || "premium_light"
      interval = checkout_interval_param
      target_plan = Plan[plan_slug]
      sub = @club.subscription

      if sub&.stripe_subscription_id.present? && sub.active? &&
         sub.plan.slug == plan_slug && sub.billing_interval == interval
        redirect_to public_club_billing_path(@club),
                    notice: "Sei già su #{target_plan.name} (#{Billing::Stripe::PriceCatalog.label(plan_slug: plan_slug, interval: interval)})."
        return
      end

      if sub&.stripe_subscription_id.present? && sub.active?
        Billing::Stripe::ChangePlan.call(club: @club, plan_slug: plan_slug, interval: interval)
        redirect_to public_club_billing_path(@club),
                    notice: "Piano aggiornato a #{target_plan.name} (#{Billing::Stripe::PriceCatalog.label(plan_slug: plan_slug, interval: interval)}). Eventuale differenza gestita da Stripe."
      else
        url = Billing::Stripe::CheckoutSession.new(
          club: @club, user: current_user, plan_slug: plan_slug, interval: interval
        ).url
        redirect_to url, allow_other_host: true
      end
    rescue ArgumentError => e
      redirect_to public_club_billing_path(@club), alert: e.message
    rescue ::Stripe::StripeError => e
      Rails.logger.warn("[Stripe checkout] #{e.message}")
      redirect_to public_club_billing_path(@club), alert: "Errore Stripe: #{e.message}"
    end

    def portal
      require_club_owner!(@club)
      unless MatchLiveTv.stripe_enabled?
        redirect_to public_club_billing_path(@club), alert: "Portale pagamenti non configurato"
        return
      end

      url = Billing::Stripe::CheckoutSession.new(club: @club, user: current_user).portal_url
      redirect_to url, allow_other_host: true
    end

    private

    def set_club
      @club = current_user.owned_clubs.find(params[:id])
    end

    def club_params
      p = params.require(:club).permit(
        :name, :sport, :logo_url, :primary_color, :secondary_color,
        :billing_entity_type, :billing_legal_name, :billing_vat_number, :billing_fiscal_code,
        :billing_email, :billing_phone, :billing_address_line, :billing_city, :billing_province,
        :billing_postal_code, :billing_country, :billing_recipient_code, :billing_pec
      )
      p[:primary_color] = normalize_hex_color(p[:primary_color], "#e53935")
      p[:secondary_color] = normalize_hex_color(p[:secondary_color], "#ffffff")
      p
    end

    def require_billing_profile_for_premium_checkout!
      require_club_owner!(@club)
      plan_slug = params[:plan].presence_in(%w[premium_light premium_full])
      return if plan_slug.blank?
      return if @club.billing_profile_complete?

      redirect_to public_club_billing_profile_path(
        @club,
        plan: plan_slug,
        interval: params[:interval].presence
      ), alert: "Completa i dati di fatturazione prima di attivare un piano premium."
    end

    def checkout_interval_param
      Billing::Stripe::PriceCatalog.normalize_interval(params[:interval])
    rescue ArgumentError
      Billing::Stripe::PriceCatalog::DEFAULT_INTERVAL
    end

    def finalize_subscription_if_due!
      return unless MatchLiveTv.stripe_enabled?

      Billing::Stripe::FinalizeSubscription.call(club: @club)
    rescue ::Stripe::StripeError => e
      Rails.logger.warn("[Stripe finalize subscription] #{e.message}")
    end

    def sync_checkout_return!
      return unless params[:checkout] == "success"
      return unless MatchLiveTv.stripe_enabled?

      Billing::Stripe::CheckoutSync.call(
        club: @club,
        session_id: params[:session_id].presence
      )
    rescue ::Stripe::StripeError => e
      Rails.logger.warn("[Stripe checkout sync] #{e.message}")
    end

    def apply_checkout_flash!
      case params[:checkout]
      when "success"
        plan_name = @subscription&.plan&.name || "premium"
        flash.now[:notice] = "Pagamento completato! Piano attivo: #{plan_name}."
      when "canceled"
        flash.now[:alert] = "Pagamento annullato. Nessun addebito è stato effettuato."
      end
    end
  end
end
