using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MairuiSdk.Exceptions;
using MairuiSdk.Http;

namespace MairuiSdk
{
    public class TimeRangeQuery
    {
        public string St { get; set; }
        public string Et { get; set; }
        public int? Lt { get; set; }
    }

    public class MairuiClient : IDisposable
    {
        public static readonly IReadOnlyList<string> FinancialTables = new[]
        {
            "balance", "income", "cashflow", "pershareindex", "capital", "hm", "topholder", "flowholder"
        };
        public static readonly IReadOnlyList<string> Indicators = new[] { "macd", "ma", "boll", "kdj" };
        public static readonly IReadOnlyList<string> PoolTypes = new[] { "ztgc", "dtgc", "qsgc", "cxgc", "zbgc" };
        public static readonly IReadOnlyList<string> HscpSlugs = new[]
        {
            "gsjj", "sszs", "ljds", "ljgg", "ljjj", "sdgd", "ltgd", "gdbh", "jnfh", "jnzf",
            "jjxs", "jjcg", "yjyg", "cwzb", "jdlr", "jdxj"
        };

        private string _licence;
        private readonly HttpClientTransport _http;

        public MairuiClient(string licence, string baseUrl = null, int connectSec = 5, int readSec = 60, int maxRetries = 3)
        {
            var lic = (licence ?? "").Trim();
            if (string.IsNullOrEmpty(lic)) throw new MairuiApiException("licence 不能为空");
            _licence = lic;
            _http = new HttpClientTransport(baseUrl, connectSec, readSec, maxRetries);
        }

        public void Dispose() => _http.Dispose();
        public void Close() => Dispose();

        public void SetLicence(string licence)
        {
            var lic = (licence ?? "").Trim();
            if (string.IsNullOrEmpty(lic)) throw new MairuiApiException("licence 不能为空");
            _licence = lic;
        }

        public string Licence => _licence;

        private async Task<object> GetAsync(IEnumerable<string> parts, TimeRangeQuery q, IDictionary<string, string> extra, CancellationToken ct)
        {
            var path = "/" + string.Join("/", parts.Where(p => !string.IsNullOrEmpty(p)).Select(HttpClientTransport.QuotePath));
            var query = HttpClientTransport.BuildQuery(q?.St, q?.Et, q?.Lt, extra);
            return await _http.GetJsonAsync(path, query.Count > 0 ? query : null, ct).ConfigureAwait(false);
        }

        private List<string> Lic(params string[] parts)
        {
            var list = parts.ToList();
            list.Add(_licence);
            return list;
        }

        public async Task<List<T>> MapAsync<T>(Func<object, Task<T>> fn, IList<object> items, int maxWorkers = 8, CancellationToken ct = default)
        {
            if (items == null || items.Count == 0) return new List<T>();
            var workers = Math.Max(1, Math.Min(maxWorkers, items.Count));
            using (var sem = new SemaphoreSlim(workers))
            {
                var tasks = items.Select(async (item, i) =>
                {
                    await sem.WaitAsync(ct).ConfigureAwait(false);
                    try { return await fn(item).ConfigureAwait(false); }
                    finally { sem.Release(); }
                });
                return (await Task.WhenAll(tasks).ConfigureAwait(false)).ToList();
            }
        }

        // --- 股票列表 ---
        public Task<object> StockListAsync(CancellationToken ct = default) => GetAsync(Lic("hslt", "list"), null, null, ct);
        public Task<object> NewStockCalendarAsync(CancellationToken ct = default) => GetAsync(Lic("hslt", "new"), null, null, ct);
        public Task<object> SectorsListAsync(CancellationToken ct = default) => GetAsync(Lic("hslt", "sectorslist"), null, null, ct);
        public Task<object> PrimarySectorsListAsync(CancellationToken ct = default) => GetAsync(Lic("hslt", "primarylist"), null, null, ct);
        public Task<object> SectorDetailAsync(string sectorName, CancellationToken ct = default) => GetAsync(Lic("hslt", "sectors", sectorName), null, null, ct);

        public Task<object> StockHistoryAsync(string code, string period = "d", string dividend = "n", TimeRangeQuery q = null, CancellationToken ct = default)
            => GetAsync(Lic("hsstock", "history", code, PeriodOr(period), DivOr(dividend)), q, null, ct);

        public Task<object> StockLatestAsync(string code, string period = "d", string dividend = "n", int? lt = null, CancellationToken ct = default)
            => GetAsync(Lic("hsstock", "latest", code, PeriodOr(period), DivOr(dividend)), new TimeRangeQuery { Lt = lt }, null, ct);

        public Task<object> StockVipHistoryAsync(string code, string period = "d", string dividend = "n", TimeRangeQuery q = null, CancellationToken ct = default)
            => GetAsync(Lic("hsstock", "vip", code, PeriodOr(period), DivOr(dividend)), q, null, ct);

        public Task<object> StockStoppriceAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default)
            => GetAsync(Lic("hsstock", "stopprice", "history", code), q, null, ct);

        public Task<object> StockIndicatorsAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default)
            => GetAsync(Lic("hsstock", "indicators", code), q, null, ct);

        public Task<object> StockIndicatorAsync(string indicator, string code, string period = "d", string dividend = "n", TimeRangeQuery q = null, CancellationToken ct = default)
        {
            var ind = indicator.Trim().ToLowerInvariant();
            if (!Indicators.Contains(ind)) throw new MairuiApiException($"indicator 须为 {string.Join(",", Indicators)}，收到: {indicator}");
            return GetAsync(Lic("hsstock", "history", ind, code, PeriodOr(period), DivOr(dividend)), q, null, ct);
        }

        public Task<object> StockMacdAsync(string code, string period = "d", string dividend = "n", TimeRangeQuery q = null, CancellationToken ct = default)
            => StockIndicatorAsync("macd", code, period, dividend, q, ct);
        public Task<object> StockMaAsync(string code, string period = "d", string dividend = "n", TimeRangeQuery q = null, CancellationToken ct = default)
            => StockIndicatorAsync("ma", code, period, dividend, q, ct);
        public Task<object> StockBollAsync(string code, string period = "d", string dividend = "n", TimeRangeQuery q = null, CancellationToken ct = default)
            => StockIndicatorAsync("boll", code, period, dividend, q, ct);
        public Task<object> StockKdjAsync(string code, string period = "d", string dividend = "n", TimeRangeQuery q = null, CancellationToken ct = default)
            => StockIndicatorAsync("kdj", code, period, dividend, q, ct);

        public Task<object> StockRealTimeAsync(string code, CancellationToken ct = default) => GetAsync(Lic("hsstock", "real", "time", code), null, null, ct);
        public Task<object> StockRealFiveAsync(string code, CancellationToken ct = default) => GetAsync(Lic("hsstock", "real", "five", code), null, null, ct);
        public Task<object> StockSsjyAsync(string code, CancellationToken ct = default) => GetAsync(Lic("hsrl", "ssjy", code), null, null, ct);
        public Task<object> StockSsjyAllAsync(CancellationToken ct = default) => GetAsync(Lic("hsrl", "ssjy", "all"), null, null, ct);
        public Task<object> StockRealAllAsync(CancellationToken ct = default) => GetAsync(Lic("hsrl", "real", "all"), null, null, ct);

        public Task<object> StockSsjyMoreAsync(object stockCodes, CancellationToken ct = default)
        {
            string codes;
            if (stockCodes is string s) codes = s;
            else if (stockCodes is IEnumerable<string> list) codes = string.Join(",", list.Select(x => x.Trim()).Where(x => x.Length > 0));
            else throw new MairuiApiException("stock_codes 须为 string 或 IEnumerable<string>");
            return GetAsync(Lic("hsrl", "ssjy_more"), null, new Dictionary<string, string> { ["stock_codes"] = codes }, ct);
        }

        public Task<object> StockZbjyAsync(string code, CancellationToken ct = default) => GetAsync(Lic("hsrl", "zbjy", code), null, null, ct);
        public Task<object> StockTransactionAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default)
            => GetAsync(Lic("hsstock", "history", "transaction", code), q, null, ct);

        public Task<object> StockFinancialAsync(string table, string code, TimeRangeQuery q = null, CancellationToken ct = default)
        {
            var t = table.Trim().ToLowerInvariant();
            if (!FinancialTables.Contains(t)) throw new MairuiApiException($"table 须为 {string.Join(",", FinancialTables)}，收到: {table}");
            return GetAsync(Lic("hsstock", "financial", t, code), q, null, ct);
        }

        public Task<object> StockBalanceAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => StockFinancialAsync("balance", code, q, ct);
        public Task<object> StockIncomeAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => StockFinancialAsync("income", code, q, ct);
        public Task<object> StockCashflowAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => StockFinancialAsync("cashflow", code, q, ct);
        public Task<object> StockPershareindexAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => StockFinancialAsync("pershareindex", code, q, ct);
        public Task<object> StockCapitalAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => StockFinancialAsync("capital", code, q, ct);
        public Task<object> StockShareholderCountAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => StockFinancialAsync("hm", code, q, ct);
        public Task<object> StockTopHoldersAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => StockFinancialAsync("topholder", code, q, ct);
        public Task<object> StockFlowHoldersAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => StockFinancialAsync("flowholder", code, q, ct);
        public Task<object> StockInstrumentAsync(string code, CancellationToken ct = default) => GetAsync(Lic("hsstock", "instrument", code), null, null, ct);

        public Task<object> CompanyAsync(string slug, string code, CancellationToken ct = default)
        {
            var s = slug.Trim().ToLowerInvariant();
            if (!HscpSlugs.Contains(s)) throw new MairuiApiException($"slug 须为 {string.Join(",", HscpSlugs)}，收到: {slug}");
            return GetAsync(Lic("hscp", s, code), null, null, ct);
        }

        public Task<object> CompanyProfileAsync(string code, CancellationToken ct = default) => CompanyAsync("gsjj", code, ct);
        public Task<object> CompanyIndexesAsync(string code, CancellationToken ct = default) => CompanyAsync("sszs", code, ct);
        public Task<object> CompanyDirectorsAsync(string code, CancellationToken ct = default) => CompanyAsync("ljds", code, ct);
        public Task<object> CompanyExecutivesAsync(string code, CancellationToken ct = default) => CompanyAsync("ljgg", code, ct);
        public Task<object> CompanySupervisorsAsync(string code, CancellationToken ct = default) => CompanyAsync("ljjj", code, ct);
        public Task<object> CompanyTop10HoldersAsync(string code, CancellationToken ct = default) => CompanyAsync("sdgd", code, ct);
        public Task<object> CompanyTop10FloatHoldersAsync(string code, CancellationToken ct = default) => CompanyAsync("ltgd", code, ct);
        public Task<object> CompanyHolderChangeAsync(string code, CancellationToken ct = default) => CompanyAsync("gdbh", code, ct);
        public Task<object> CompanyDividendsAsync(string code, CancellationToken ct = default) => CompanyAsync("jnfh", code, ct);
        public Task<object> CompanySeoAsync(string code, CancellationToken ct = default) => CompanyAsync("jnzf", code, ct);
        public Task<object> CompanyUnlockAsync(string code, CancellationToken ct = default) => CompanyAsync("jjxs", code, ct);
        public Task<object> CompanyFundHoldingAsync(string code, CancellationToken ct = default) => CompanyAsync("jjcg", code, ct);
        public Task<object> CompanyEarningsForecastAsync(string code, CancellationToken ct = default) => CompanyAsync("yjyg", code, ct);
        public Task<object> CompanyFinancialIndexAsync(string code, CancellationToken ct = default) => CompanyAsync("cwzb", code, ct);
        public Task<object> CompanyQuarterProfitAsync(string code, CancellationToken ct = default) => CompanyAsync("jdlr", code, ct);
        public Task<object> CompanyQuarterCashflowAsync(string code, CancellationToken ct = default) => CompanyAsync("jdxj", code, ct);

        public Task<object> StockPoolAsync(string pool, string date, CancellationToken ct = default)
        {
            var p = pool.Trim().ToLowerInvariant();
            if (!PoolTypes.Contains(p)) throw new MairuiApiException($"pool 须为 {string.Join(",", PoolTypes)}，收到: {pool}");
            return GetAsync(Lic("hslt", p, date), null, null, ct);
        }

        public Task<object> LimitUpPoolAsync(string date, CancellationToken ct = default) => StockPoolAsync("ztgc", date, ct);
        public Task<object> LimitDownPoolAsync(string date, CancellationToken ct = default) => StockPoolAsync("dtgc", date, ct);
        public Task<object> StrongPoolAsync(string date, CancellationToken ct = default) => StockPoolAsync("qsgc", date, ct);
        public Task<object> NewStockPoolAsync(string date, CancellationToken ct = default) => StockPoolAsync("cxgc", date, ct);
        public Task<object> BrokenBoardPoolAsync(string date, CancellationToken ct = default) => StockPoolAsync("zbgc", date, ct);

        public Task<object> ConceptTreeAsync(CancellationToken ct = default) => GetAsync(Lic("hszg", "list"), null, null, ct);
        public Task<object> ConceptsOfStockAsync(string code, CancellationToken ct = default) => GetAsync(Lic("hszg", "zg", code), null, null, ct);
        public Task<object> StocksOfConceptAsync(string conceptCode, CancellationToken ct = default) => GetAsync(Lic("hszg", "gg", conceptCode), null, null, ct);
        public Task<object> StockInteractiveqaAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => GetAsync(Lic("hsstock", "interactiveqa", code), q, null, ct);
        public Task<object> StockAnnouncementAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => GetAsync(Lic("hsstock", "announcement", code), q, null, ct);

        public Task<object> IndexListAsync(CancellationToken ct = default) => GetAsync(Lic("hsindex", "list"), null, null, ct);
        public Task<object> IndexHistoryAsync(string code, string period = "d", TimeRangeQuery q = null, CancellationToken ct = default)
            => GetAsync(Lic("hsindex", "history", code, PeriodOr(period)), q, null, ct);
        public Task<object> IndexLatestAsync(string code, string period = "d", int? lt = null, CancellationToken ct = default)
            => GetAsync(Lic("hsindex", "latest", code, PeriodOr(period)), new TimeRangeQuery { Lt = lt }, null, ct);

        public Task<object> IndexIndicatorAsync(string indicator, string code, string period = "d", TimeRangeQuery q = null, CancellationToken ct = default)
        {
            var ind = indicator.Trim().ToLowerInvariant();
            if (!Indicators.Contains(ind)) throw new MairuiApiException($"indicator 须为 {string.Join(",", Indicators)}，收到: {indicator}");
            return GetAsync(Lic("hsindex", "history", ind, code, PeriodOr(period)), q, null, ct);
        }

        public Task<object> IndexMacdAsync(string code, string period = "d", TimeRangeQuery q = null, CancellationToken ct = default) => IndexIndicatorAsync("macd", code, period, q, ct);
        public Task<object> IndexMaAsync(string code, string period = "d", TimeRangeQuery q = null, CancellationToken ct = default) => IndexIndicatorAsync("ma", code, period, q, ct);
        public Task<object> IndexBollAsync(string code, string period = "d", TimeRangeQuery q = null, CancellationToken ct = default) => IndexIndicatorAsync("boll", code, period, q, ct);
        public Task<object> IndexKdjAsync(string code, string period = "d", TimeRangeQuery q = null, CancellationToken ct = default) => IndexIndicatorAsync("kdj", code, period, q, ct);
        public Task<object> IndexRealTimeAsync(string code, CancellationToken ct = default) => GetAsync(Lic("hsindex", "real", "time", code), null, null, ct);

        public Task<object> BjStockListAsync(CancellationToken ct = default) => GetAsync(Lic("bj", "list", "all"), null, null, ct);
        public Task<object> BjIndexListAsync(CancellationToken ct = default) => GetAsync(Lic("bj", "list", "index"), null, null, ct);
        public Task<object> BjStockRealTimeAsync(string code, CancellationToken ct = default) => GetAsync(Lic("bj", "stock", "real", "time", code), null, null, ct);
        public Task<object> BjStockRealFiveAsync(string code, CancellationToken ct = default) => GetAsync(Lic("bj", "stock", "real", "five", code), null, null, ct);
        public Task<object> BjIndexRealTimeAsync(string code, CancellationToken ct = default) => GetAsync(Lic("bj", "index", "real", "time", code), null, null, ct);
        public Task<object> BjHistoryAsync(string code, string period = "d", string dividend = "n", TimeRangeQuery q = null, CancellationToken ct = default)
            => GetAsync(Lic("bj", "history", code, PeriodOr(period), DivOr(dividend)), q, null, ct);

        public Task<object> BjFinancialAsync(string table, string code, TimeRangeQuery q = null, CancellationToken ct = default)
        {
            var t = table.Trim().ToLowerInvariant();
            if (!FinancialTables.Contains(t)) throw new MairuiApiException($"table 须为 {string.Join(",", FinancialTables)}，收到: {table}");
            return GetAsync(Lic("bj", "financial", t, code), q, null, ct);
        }

        public Task<object> BjBalanceAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => BjFinancialAsync("balance", code, q, ct);
        public Task<object> BjIncomeAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => BjFinancialAsync("income", code, q, ct);
        public Task<object> BjCashflowAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => BjFinancialAsync("cashflow", code, q, ct);
        public Task<object> BjPershareindexAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => BjFinancialAsync("pershareindex", code, q, ct);
        public Task<object> BjCapitalAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => BjFinancialAsync("capital", code, q, ct);
        public Task<object> BjShareholderCountAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => BjFinancialAsync("hm", code, q, ct);
        public Task<object> BjTopHoldersAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => BjFinancialAsync("topholder", code, q, ct);
        public Task<object> BjFlowHoldersAsync(string code, TimeRangeQuery q = null, CancellationToken ct = default) => BjFinancialAsync("flowholder", code, q, ct);

        public Task<object> FundListAsync(CancellationToken ct = default) => GetAsync(Lic("fd", "list", "all"), null, null, ct);
        public Task<object> EtfListAsync(CancellationToken ct = default) => GetAsync(Lic("fd", "list", "etf"), null, null, ct);
        public Task<object> FundRealTimeAsync(string code, CancellationToken ct = default) => GetAsync(Lic("fd", "real", "time", code), null, null, ct);
        public Task<object> StarStockListAsync(CancellationToken ct = default) => GetAsync(Lic("kc", "list", "all"), null, null, ct);
        public Task<object> StarRealTimeAsync(string code, CancellationToken ct = default) => GetAsync(Lic("kc", "real", "time", code), null, null, ct);
        public Task<object> StarRealFiveAsync(string code, CancellationToken ct = default) => GetAsync(Lic("kc", "real", "five", code), null, null, ct);





        // === SDK_GENERATED_BEGIN_v1_2_0 ===
        // catalog-driven; do not hand-edit

        // --- 沪深数据中心 ---

        public Task<object> HsdcJrtsAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hitc", "jrts"), null, null, ct);

        public Task<object> HsdcRzrqzlAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hitc", "rzrqzl"), null, null, ct);

        public Task<object> HsdcRzrqmxAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hitc", "rzrqmx"), null, null, ct);

        public Task<object> HsdcDzjyAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hitc", "dzjy"), null, null, ct);

        public Task<object> HsdcJjxsAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hitc", "jjxs"), null, null, ct);

        public Task<object> HsdcDxsyAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hitc", "dxsy"), null, null, ct);

        public Task<object> HsdcLsfhAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hitc", "lsfh"), null, null, ct);

        public Task<object> HsdcHilhMrxqAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hilh", "mrxq"), null, null, ct);

        public Task<object> HsdcHilhXwmxAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hilh", "xwmx"), null, null, ct);

        public Task<object> HsdcHimkJdzgzdAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "jdzgzd"), null, null, ct);

        public Task<object> HsdcHimkPzxgAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "pzxg"), null, null, ct);

        public Task<object> HsdcHimkPzxdAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "pzxd"), null, null, ct);

        public Task<object> HsdcHimkCjzzAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "cjzz"), null, null, ct);

        public Task<object> HsdcHimkCjzjAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "cjzj"), null, null, ct);

        public Task<object> HsdcHimkLxflAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "lxfl"), null, null, ct);

        public Task<object> HsdcHimkLxslAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "lxsl"), null, null, ct);

        public Task<object> HsdcHimkLxszAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "lxsz"), null, null, ct);

        public Task<object> HsdcHimkLxxdAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "lxxd"), null, null, ct);

        public Task<object> HsdcHimkZzdAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "zzd"), null, null, ct);

        public Task<object> HsdcHimkYzdAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "yzd"), null, null, ct);

        public Task<object> HsdcHimkZqsgAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "zqsg"), null, null, ct);

        public Task<object> HsdcHimkMqsgAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "mqsg"), null, null, ct);

        public Task<object> HsdcHimkLtszphAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "ltszph"), null, null, ct);

        public Task<object> HsdcHimkSylAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "syl"), null, null, ct);

        public Task<object> HsdcHimkSjlAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "sjl"), null, null, ct);

        public Task<object> HsdcHimkRoeAsync(CancellationToken ct = default) =>
            GetAsync(Lic("himk", "roe"), null, null, ct);

        public Task<object> HsdcHicwLrAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hicw", "lr"), null, null, ct);

        public Task<object> HsdcHibkZjhhyAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hibk", "zjhhy"), null, null, ct);

        public Task<object> HsdcHibkGnbkAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hibk", "gnbk"), null, null, ct);

        public Task<object> HsdcJlrAsync(CancellationToken ct = default) =>
            GetAsync(Lic("higg", "jlr"), null, null, ct);

        public Task<object> HsdcJlrlAsync(CancellationToken ct = default) =>
            GetAsync(Lic("higg", "jlrl"), null, null, ct);

        public Task<object> HsdcZljlrAsync(CancellationToken ct = default) =>
            GetAsync(Lic("higg", "zljlr"), null, null, ct);

        public Task<object> HsdcZljlrlAsync(CancellationToken ct = default) =>
            GetAsync(Lic("higg", "zljlrl"), null, null, ct);

        public Task<object> HsdcShzlrAsync(CancellationToken ct = default) =>
            GetAsync(Lic("higg", "shzlr"), null, null, ct);

        public Task<object> HsdcShjlrlAsync(CancellationToken ct = default) =>
            GetAsync(Lic("higg", "shjlrl"), null, null, ct);

        public Task<object> HsdcZjhAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hizj", "zjh"), null, null, ct);

        public Task<object> HsdcBkAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hizj", "bk"), null, null, ct);

        public Task<object> HsdcGgzlAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hizj", "ggzl"), null, null, ct);

        public Task<object> HsdcLxlrAsync(CancellationToken ct = default) =>
            GetAsync(Lic("hizj", "lxlr"), null, null, ct);

        public Task<object> HsdcNbzjLxglAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "lxgl"), null, null, ct);

        public Task<object> HsdcNbzjBxlsAsync(string jd, CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "bxls", jd), null, null, ct);

        public Task<object> HsdcNbzjNxlsAsync(string jd, CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "nxls", jd), null, null, ct);

        public Task<object> HsdcNbzjBxzlAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "bxzl"), null, null, ct);

        public Task<object> HsdcNbzjNxzlAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "nxzl"), null, null, ct);

        public Task<object> HsdcNbzjHgtcAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "hgtc"), null, null, ct);

        public Task<object> HsdcNbzjSgtcAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "sgtc"), null, null, ct);

        public Task<object> HsdcNbzjGgthAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "ggth"), null, null, ct);

        public Task<object> HsdcNbzjGgtsAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "ggts"), null, null, ct);

        public Task<object> HsdcNbzjAhAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "ah"), null, null, ct);

        public Task<object> HsdcNbzjHgtsAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "hgts"), null, null, ct);

        public Task<object> HsdcNbzjSgtsAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "sgts"), null, null, ct);

        public Task<object> HsdcNbzjHcjdAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "hcjd"), null, null, ct);

        public Task<object> HsdcNbzjScjdAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "scjd"), null, null, ct);

        public Task<object> HsdcNbzjBxpmAsync(string zq, CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "bxpm", zq), null, null, ct);

        public Task<object> HsdcNbzjHgpmAsync(string zq, CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "hgpm", zq), null, null, ct);

        public Task<object> HsdcNbzjSgpmAsync(string zq, CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "sgpm", zq), null, null, ct);

        public Task<object> HsdcNbzjHglsAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "hgls"), null, null, ct);

        public Task<object> HsdcNbzjShlsAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "shls"), null, null, ct);

        public Task<object> HsdcNbzjGhlsAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "ghls"), null, null, ct);

        public Task<object> HsdcNbzjGslsAsync(CancellationToken ct = default) =>
            GetAsync(Lic("ht", "nbzj", "gsls"), null, null, ct);

        public Task<object> HsdcListAsync(CancellationToken ct = default) =>
            GetAsync(Lic("kzz", "list"), null, null, ct);

        public Task<object> HsdcComparisonAsync(CancellationToken ct = default) =>
            GetAsync(Lic("kzz", "comparison"), null, null, ct);

        public Task<object> HsdcSpotAsync(CancellationToken ct = default) =>
            GetAsync(Lic("kzz", "spot"), null, null, ct);


        // --- 基金数据中心 ---

        public Task<object> FundcPmKfjzgAsync(CancellationToken ct = default) =>
            GetAsync(Lic("js", "pm", "kfjzg", "kfsjj_gpxjj_zsx"), null, null, ct);

        public Task<object> FundcPmKfjzqAsync(CancellationToken ct = default) =>
            GetAsync(Lic("js", "pm", "kfjzq", "kfsjj_hbxjj_hba"), null, null, ct);

        public Task<object> FundcPmFbjzAsync(CancellationToken ct = default) =>
            GetAsync(Lic("js", "pm", "fbjz", "kfsjj_fbqy_ctfj"), null, null, ct);

        public Task<object> FundcPmKfpmAsync(CancellationToken ct = default) =>
            GetAsync(Lic("js", "pm", "kfpm", "kfsjj_gpxjj_zsx"), null, null, ct);

        public Task<object> FundcPmFbpmAsync(CancellationToken ct = default) =>
            GetAsync(Lic("js", "pm", "fbpm", "kfsjj_fbqy_ctfj"), null, null, ct);

        public Task<object> FundcPmFzyjAsync(CancellationToken ct = default) =>
            GetAsync(Lic("js", "pm", "fzyj", "kfsjj_fjgs_wjzqx"), null, null, ct);

        public Task<object> FundcJfKffhAsync(CancellationToken ct = default) =>
            GetAsync(Lic("js", "jf", "kffh", "kfsjj_gpxjj_zsx"), null, null, ct);

        public Task<object> FundcJfFzfhAsync(CancellationToken ct = default) =>
            GetAsync(Lic("js", "jf", "fzfh", "kfsjj_fjgs_wjzqx"), null, null, ct);

        public Task<object> FundcGmKfgmAsync(CancellationToken ct = default) =>
            GetAsync(Lic("js", "gm", "kfgm", "kfsjj_gpxjj_zsx"), null, null, ct);

        public Task<object> FundcGmFbgmAsync(CancellationToken ct = default) =>
            GetAsync(Lic("js", "gm", "fbgm", "kfsjj_fbqy_ctfj"), null, null, ct);

        public Task<object> FundcGmFzgmAsync(CancellationToken ct = default) =>
            GetAsync(Lic("js", "gm", "fzgm", "kfsjj_fjgs_wjzqx"), null, null, ct);

        public Task<object> FundcOtherJjzcAsync(string yyyy_j, CancellationToken ct = default) =>
            GetAsync(Lic("js", "other", "jjzc", yyyy_j), null, null, ct);

        public Task<object> FundcOtherZcbdAsync(string yyyy_j, CancellationToken ct = default) =>
            GetAsync(Lic("js", "other", "zcbd", yyyy_j), null, null, ct);

        public Task<object> FundcOtherDxjgAsync(CancellationToken ct = default) =>
            GetAsync(Lic("js", "other", "dxjg", "yh"), null, null, ct);


        // --- 基金行情档案 ---

        public Task<object> Fundf10AllAsync(CancellationToken ct = default) =>
            GetAsync(Lic("jj", "all"), null, null, ct);

        public Task<object> Fundf10GzlbAsync(CancellationToken ct = default) =>
            GetAsync(Lic("jj", "gzlb"), null, null, ct);

        public Task<object> Fundf10PzzzgzAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "pzzzgz", code), null, null, ct);

        public Task<object> Fundf10HqzksjzAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "hqzksjz", code), null, null, ct);

        public Task<object> Fundf10JjyjAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "jjyj", code), null, null, ct);

        public Task<object> Fundf10JjfhAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "jjfh", code), null, null, ct);

        public Task<object> Fundf10JjgmAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "jjgm", code), null, null, ct);

        public Task<object> Fundf10FbsAsync(CancellationToken ct = default) =>
            GetAsync(Lic("jj", "fbs"), null, null, ct);

        public Task<object> Fundf10EtfAsync(CancellationToken ct = default) =>
            GetAsync(Lic("jj", "etf"), null, null, ct);

        public Task<object> Fundf10LofAsync(CancellationToken ct = default) =>
            GetAsync(Lic("jj", "lof"), null, null, ct);

        public Task<object> Fundf10JjgkAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "jjgk", code), null, null, ct);

        public Task<object> Fundf10ZrjlAsync(CancellationToken ct = default) =>
            GetAsync(Lic("jj", "zrjl"), null, null, ct);

        public Task<object> Fundf10LsjzAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "lsjz", code), null, null, ct);

        public Task<object> Fundf10FhpsAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "fhps", code), null, null, ct);

        public Task<object> Fundf10JdtjAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "jdtj", code), null, null, ct);

        public Task<object> Fundf10JdzfmxAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "jdzfmx", code), null, null, ct);

        public Task<object> Fundf10GpccAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "gpcc", code), null, null, ct);

        public Task<object> Fundf10ZqccAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "zqcc", code), null, null, ct);

        public Task<object> Fundf10HypzAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "hypz", code), null, null, ct);

        public Task<object> Fundf10ZcpzAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "zcpz", code), null, null, ct);

        public Task<object> Fundf10GmbdAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "gmbd", code), null, null, ct);

        public Task<object> Fundf10CyrjgAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("jj", "cyrjg", code), null, null, ct);


        // --- 量化因子 ---

        public Task<object> FactorListAsync(CancellationToken ct = default) =>
            GetAsync(Lic("factor", "list"), null, null, ct);

        public Task<object> FactorCategoriesAsync(CancellationToken ct = default) =>
            GetAsync(Lic("factor", "categories"), null, null, ct);

        public Task<object> FactorValuationAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("factor", "valuation", code), null, null, ct);

        public Task<object> FactorQualityAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("factor", "quality", code), null, null, ct);

        public Task<object> FactorGrowthAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("factor", "growth", code), null, null, ct);

        public Task<object> FactorMomentumAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("factor", "momentum", code), null, null, ct);

        public Task<object> FactorCapitalAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("factor", "capital", code), null, null, ct);

        public Task<object> FactorSignalAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("factor", "signal", code), null, null, ct);

        public Task<object> FactorRiskAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("factor", "risk", code), null, null, ct);

        public Task<object> FactorDividendAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("factor", "dividend", code), null, null, ct);

        public Task<object> FactorScaleAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("factor", "scale", code), null, null, ct);

        public Task<object> FactorSentimentAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("factor", "sentiment", code), null, null, ct);

        public Task<object> FactorAllAsync(string code, CancellationToken ct = default) =>
            GetAsync(Lic("factor", "all", code), null, null, ct);

        public Task<object> FactorRankAsync(string factor_id, CancellationToken ct = default) =>
            GetAsync(Lic("factor", "rank", factor_id), null, null, ct);

        public Task<object> FactorTopAsync(string factor_id, string arg, CancellationToken ct = default) =>
            GetAsync(Lic("factor", "top", factor_id, arg), null, null, ct);

        public Task<object> FactorHistoryAsync(string factor_id, string code, CancellationToken ct = default) =>
            GetAsync(Lic("factor", "history", factor_id, code), null, null, ct);

        public Task<object> FactorPercentileAsync(string factor_id, string code, CancellationToken ct = default) =>
            GetAsync(Lic("factor", "percentile", factor_id, code), null, null, ct);

        // === SDK_GENERATED_END_v1_2_0 ===

        private static string PeriodOr(string period) => string.IsNullOrEmpty(period) ? "d" : period;
        private static string DivOr(string dividend) => string.IsNullOrEmpty(dividend) ? "n" : dividend;
    }
}
