import 'package:hooks_riverpod/hooks_riverpod.dart';

import '../../../common/domain/metal_type.dart';
import 'market_models.dart';

final mockMarketRepositoryProvider = Provider<MockMarketRepository>(
  (ref) => MockMarketRepository(),
);

class MockMarketRepository {
  MockMarketRepository();

  final DateTime _updatedAt = DateTime(2026, 6, 18, 16, 11);

  List<MetalQuote> getQuotes() {
    return [
      MetalQuote(
        metal: MetalType.gold,
        spotPrice: 943.05,
        changeAmount: 8.12,
        changePercent: 0.87,
        updatedAt: _updatedAt,
        sourceLabel: '行情聚合',
        basisLabel: '上海金现货参考价',
      ),
      MetalQuote(
        metal: MetalType.platinum,
        spotPrice: 384.20,
        changeAmount: -2.46,
        changePercent: -0.64,
        updatedAt: _updatedAt,
        sourceLabel: '行情聚合',
        basisLabel: '国际盘换算参考价',
      ),
      MetalQuote(
        metal: MetalType.silver,
        spotPrice: 15.75,
        changeAmount: 0.18,
        changePercent: 1.16,
        updatedAt: _updatedAt,
        sourceLabel: '行情聚合',
        basisLabel: '上海银现货参考价',
      ),
    ];
  }

  MetalQuote quoteFor(MetalType metal) =>
      getQuotes().firstWhere((quote) => quote.metal == metal);

  List<MarketPoint> chartFor(MetalType metal, MarketPeriod period) {
    final quote = quoteFor(metal);
    final points = <MarketPoint>[];
    final step = switch (period) {
      MarketPeriod.h24 => const Duration(hours: 2),
      MarketPeriod.d5 => const Duration(days: 1),
      MarketPeriod.m1 => const Duration(days: 3),
      MarketPeriod.m3 => const Duration(days: 9),
      MarketPeriod.y1 => const Duration(days: 30),
    };
    for (var i = 11; i >= 0; i--) {
      final drift = (i - 5.5) * quote.changeAmount / 10;
      final close = quote.spotPrice - drift;
      points.add(
        MarketPoint(
          time: _updatedAt.subtract(step * i),
          open: close - quote.changeAmount / 20,
          high: close + quote.spotPrice * 0.003,
          low: close - quote.spotPrice * 0.003,
          close: close,
        ),
      );
    }
    return points;
  }

  List<ExchangeChannel> channelsFor(MetalType metal, {double recycle = 0.97}) {
    final quote = quoteFor(metal);
    return switch (metal) {
      MetalType.gold => [
        _channel(
          'gold_spot',
          metal,
          '上海金现货',
          ExchangeChannelKind.spot,
          943.05,
          '上海金现货',
          '材料价值口径 · 非金店零售 / 回收价',
        ),
        _channel(
          'gold_bar',
          metal,
          '投资金条',
          ExchangeChannelKind.bar,
          955.00,
          '银行 / 品牌金条参考',
          '投资金条参考 · 通常含少量升水',
        ),
        _channel(
          'gold_ctf',
          metal,
          '周大福金店',
          ExchangeChannelKind.retail,
          1238.00,
          '品牌零售挂牌参考',
          '含工费与品牌溢价 · 以门店为准',
        ),
        _channel(
          'gold_lfx',
          metal,
          '老凤祥金店',
          ExchangeChannelKind.retail,
          1248.00,
          '品牌零售挂牌参考',
          '含工费与品牌溢价 · 以门店为准',
        ),
        _channel(
          'gold_td',
          metal,
          '黄金 T+D',
          ExchangeChannelKind.td,
          919.50,
          'SGE 递延参考',
          '交易品种参考 · 非实物购买价',
        ),
        _channel(
          'gold_recycle',
          metal,
          '回收参考',
          ExchangeChannelKind.recycle,
          quote.spotPrice * recycle,
          '材料价值 × 回收折扣',
          '实际以门店检测为准',
        ),
      ],
      MetalType.platinum => [
        _channel(
          'platinum_spot',
          metal,
          '铂金现货',
          ExchangeChannelKind.spot,
          384.20,
          '国际盘换算参考',
          '材料价值口径 · 非饰品零售价',
        ),
        _channel(
          'platinum_retail',
          metal,
          '铂金饰品',
          ExchangeChannelKind.retail,
          498.00,
          '零售挂牌参考',
          '含工费与品牌溢价',
        ),
        _channel(
          'platinum_recycle',
          metal,
          '回收参考',
          ExchangeChannelKind.recycle,
          quote.spotPrice * recycle,
          '材料价值 × 回收折扣',
          '实际以门店检测为准',
        ),
      ],
      MetalType.silver => [
        _channel(
          'silver_spot',
          metal,
          '白银现货',
          ExchangeChannelKind.spot,
          15.75,
          '上海银现货',
          '材料价值口径 · 非饰品零售价',
        ),
        _channel(
          'silver_retail',
          metal,
          '白银饰品',
          ExchangeChannelKind.retail,
          42.00,
          '零售挂牌参考',
          '含工费与品牌溢价',
        ),
        _channel(
          'silver_recycle',
          metal,
          '回收参考',
          ExchangeChannelKind.recycle,
          quote.spotPrice * recycle,
          '材料价值 × 回收折扣',
          '实际以门店检测为准',
        ),
      ],
    };
  }

  ExchangeChannel _channel(
    String id,
    MetalType metal,
    String name,
    ExchangeChannelKind kind,
    double price,
    String source,
    String hint,
  ) {
    return ExchangeChannel(
      id: id,
      metal: metal,
      name: name,
      kind: kind,
      pricePerGram: price,
      source: source,
      updatedAt: _updatedAt,
      hint: hint,
    );
  }
}
