defmodule BlockScoutWeb.IssuerProfile do
  @moduledoc """
  Blockscout 定制模块：发行方档案页 (P0)
  聚合某发行方的所有券批次、保障资金、信用评级
  """

  alias Explorer.SmartContract.Reader

  @treasury_abi [
    %{
      "name" => "getGuaranteeBalance",
      "type" => "function",
      "stateMutability" => "view",
      "inputs" => [%{"name" => "issuer", "type" => "address"}],
      "outputs" => [%{"name" => "", "type" => "uint256"}]
    }
  ]

  @coupon_factory_abi [
    %{
      "name" => "getIssuerBatches",
      "type" => "function",
      "stateMutability" => "view",
      "inputs" => [%{"name" => "issuer", "type" => "address"}],
      "outputs" => [%{"name" => "", "type" => "uint256[]"}]
    }
  ]

  @doc "获取发行方完整档案"
  def get_issuer_profile(issuer_address, contracts) do
    %{
      address: issuer_address,
      batches: get_issuer_batches(issuer_address, contracts.coupon_factory),
      guarantee_fund: get_guarantee_balance(issuer_address, contracts.treasury),
      total_coupons_issued: count_total_issued(issuer_address, contracts.coupon_factory),
      active_coupons: count_active_coupons(issuer_address, contracts.coupon_factory),
      compliance_status: get_compliance_status(issuer_address, contracts.compliance),
      credit_rating: calculate_credit_rating(issuer_address, contracts)
    }
  end

  @doc "获取发行方的所有券批次"
  def get_issuer_batches(issuer_address, factory_contract) do
    case Reader.query_contract(factory_contract, @coupon_factory_abi, %{
           "getIssuerBatches" => [issuer_address]
         }) do
      %{"getIssuerBatches" => {:ok, [batch_ids]}} ->
        Enum.map(batch_ids, fn batch_id ->
          %{
            batch_id: batch_id,
            details: BlockScoutWeb.CouponView.get_batch_summary(batch_id, factory_contract)
          }
        end)

      _ ->
        []
    end
  end

  @doc "获取保障资金余额"
  def get_guarantee_balance(issuer_address, treasury_contract) do
    case Reader.query_contract(treasury_contract, @treasury_abi, %{
           "getGuaranteeBalance" => [issuer_address]
         }) do
      %{"getGuaranteeBalance" => {:ok, [balance]}} ->
        %{raw: balance, formatted: format_stable_amount(balance)}

      _ ->
        %{raw: 0, formatted: "0.00"}
    end
  end

  @doc "计算发行方信用评级 (A-D)"
  def calculate_credit_rating(issuer_address, contracts) do
    guarantee = get_guarantee_balance(issuer_address, contracts.treasury)
    total_issued = count_total_issued(issuer_address, contracts.coupon_factory)
    redemption_rate = get_redemption_rate(issuer_address, contracts)

    cond do
      guarantee.raw > total_issued * 0.5 and redemption_rate > 0.95 -> "A"
      guarantee.raw > total_issued * 0.3 and redemption_rate > 0.85 -> "B"
      guarantee.raw > total_issued * 0.1 and redemption_rate > 0.70 -> "C"
      true -> "D"
    end
  end

  # ── 私有函数 ──

  defp count_total_issued(_issuer, _factory), do: 0
  defp count_active_coupons(_issuer, _factory), do: 0
  defp get_compliance_status(_issuer, _compliance), do: :compliant
  defp get_redemption_rate(_issuer, _contracts), do: 1.0

  defp format_stable_amount(amount) when is_integer(amount) do
    # 稳定币 6 位精度
    :erlang.float_to_binary(amount / 1_000_000, decimals: 2)
  end

  defp format_stable_amount(_), do: "0.00"
end
