import { Panel } from './Panel';
import { getRpcBaseUrl } from '@/services/rpc-client';
import { t } from '@/services/i18n';
import { joinSafeHtml, safeHtml } from '@/utils/sanitize';

import type { ListStablecoinMarketsResponse } from '@/generated/client/worldmonitor/market/v1/service_client';
import { getHydratedData } from '@/services/bootstrap';
import { MarketServiceClient } from '@/services/generated-rpc-clients';

type StablecoinResult = ListStablecoinMarketsResponse;

function formatLargeNum(v: number): string {
  if (v >= 1e12) return `$${(v / 1e12).toFixed(1)}T`;
  if (v >= 1e9) return `$${(v / 1e9).toFixed(1)}B`;
  if (v >= 1e6) return `$${(v / 1e6).toFixed(0)}M`;
  return `$${v.toLocaleString()}`;
}

function pegClass(status: string): string {
  if (status === 'ON PEG') return 'peg-on';
  if (status === 'SLIGHT DEPEG') return 'peg-slight';
  return 'peg-off';
}

function healthClass(status: string): string {
  if (status === 'HEALTHY') return 'health-good';
  if (status === 'CAUTION') return 'health-caution';
  return 'health-warning';
}

export class StablecoinPanel extends Panel {
  private data: StablecoinResult | null = null;
  private loading = true;
  private error: string | null = null;
  constructor() {
    super({ id: 'stablecoins', title: t('panels.stablecoins'), showCount: false, infoTooltip: t('components.stablecoins.infoTooltip') });
  }

  public async fetchData(): Promise<void> {
    const hydrated = getHydratedData('stablecoinMarkets') as StablecoinResult | undefined;
    if (hydrated?.stablecoins?.length) {
      this.data = hydrated;
      this.error = null;
      this.loading = false;
      this.renderPanel();
      void this.refreshFromRpc();
      return;
    }
    await this.refreshFromRpc();
  }

  private async refreshFromRpc(): Promise<void> {
    try {
      const client = new MarketServiceClient(getRpcBaseUrl(), { fetch: (...args) => globalThis.fetch(...args) });
      const fresh = await client.listStablecoinMarkets({ coins: [] });
      if (!this.element?.isConnected) return;
      if (fresh.stablecoins?.length || !this.data) {
        this.data = fresh;
        this.error = null;
        this.loading = false;
        this.renderPanel();
      }
    } catch (err) {
      if (this.isAbortError(err)) return;
      if (!this.element?.isConnected) return;
      if (!this.data) {
        console.warn('[Stablecoin] Fetch error:', err);
        this.error = t('common.noDataShort');
        this.loading = false;
        this.renderPanel();
      }
    }
  }

  private renderPanel(): void {
    if (this.loading) {
      this.showLoading(t('common.loadingStablecoins'));
      return;
    }

    if (this.error || !this.data) {
      this.showError(this.error || t('common.noDataShort'), () => void this.fetchData());
      return;
    }

    const d = this.data;
    if (!d.stablecoins?.length) {
      this.setSafeContent(safeHtml`<div class="panel-empty">${t('common.noDataShort')}</div>`);
      return;
    }

    const s = d.summary || { totalMarketCap: 0, totalVolume24h: 0, coinCount: 0, depeggedCount: 0, healthStatus: 'UNAVAILABLE' };

    const pegRows = joinSafeHtml(d.stablecoins.map(c => safeHtml`
      <div class="stable-row">
        <div class="stable-info">
          <span class="stable-symbol">${c.symbol}</span>
          <span class="stable-name">${c.name}</span>
        </div>
        <div class="stable-price">$${c.price.toFixed(4)}</div>
        <div class="stable-peg ${pegClass(c.pegStatus)}">
          <span class="peg-badge">${c.pegStatus}</span>
          <span class="peg-dev">${c.deviation.toFixed(2)}%</span>
        </div>
      </div>
    `));

    const supplyRows = joinSafeHtml(d.stablecoins.map(c => safeHtml`
      <div class="stable-supply-row">
        <span class="stable-symbol">${c.symbol}</span>
        <span class="stable-mcap">${formatLargeNum(c.marketCap)}</span>
        <span class="stable-vol">${formatLargeNum(c.volume24h)}</span>
        <span class="stable-change ${c.change24h >= 0 ? 'change-positive' : 'change-negative'}">${c.change24h >= 0 ? '+' : ''}${c.change24h.toFixed(2)}%</span>
      </div>
    `));

    this.setSafeContent(safeHtml`
      <div class="stablecoin-container">
        <div class="stable-health ${healthClass(s.healthStatus)}">
          <span class="health-label">${s.healthStatus}</span>
          <span class="health-detail">MCap: ${formatLargeNum(s.totalMarketCap)} | Vol: ${formatLargeNum(s.totalVolume24h)}</span>
        </div>
        <div class="stable-section">
          <div class="stable-section-title">${t('components.stablecoins.pegHealth')}</div>
          <div class="stable-peg-list">${pegRows}</div>
        </div>
        <div class="stable-section">
          <div class="stable-section-title">${t('components.stablecoins.supplyVolume')}</div>
          <div class="stable-supply-header">
            <span>${t('components.stablecoins.token')}</span><span>${t('components.stablecoins.mcap')}</span><span>${t('components.stablecoins.vol24h')}</span><span>${t('components.stablecoins.chg24h')}</span>
          </div>
          <div class="stable-supply-list">${supplyRows}</div>
        </div>
      </div>
    `);
  }
}
