using DocumentFormat.OpenXml.Packaging;

namespace Fast.Web.Logic.ReportSources;

class Trades : ReportSourceBase
{
    public Trades(MyDbContext context, SpreadsheetDocument wb, string reportName, int dataSourceId, int filterId, string filterName, List<ReportFilterParameter> filterParams, int userInfoId)
        : base(context, wb, reportName, dataSourceId, filterId, filterName, filterParams, userInfoId) { }

    public override async Task<List<ReportFilterParameter>> Run()
    {
        var query = (from q in db.VwRptDeals select q);

        string paramName;

        paramName = "Book";
        if (HasParam(paramName))
        {
            await FixInvalidFilterParams(paramName);
            var idList = GetIdList(paramName);
            query = query.Where(x => x.BookId.HasValue && idList.Contains(x.BookId.Value));
        }

        paramName = "Buy/Sell";
        if (HasParam(paramName))
        {
            var buySellValue = GetBuySellValue(paramName);
            query = query.Where(x => x.BuyButtonId.HasValue && x.BuyButtonId.Value == buySellValue);
        }

        paramName = "Counterparty";
        if (HasParam(paramName))
        {
            await FixInvalidFilterParams(paramName);
            var idList = GetIdList(paramName);
            query = query.Where(x => x.CounterPartyId.HasValue && idList.Contains(x.CounterPartyId.Value));
        }

        paramName = "Deal Purpose";
        if (HasParam(paramName))
        {
            await FixInvalidFilterParams(paramName);
            var idList = GetIdList(paramName);
            query = query.Where(x => x.DealPurposeId.HasValue && idList.Contains(x.DealPurposeId.Value));
        }

        paramName = "Internal Entity";
        if (HasParam(paramName))
        {
            await FixInvalidFilterParams(paramName);
            var idList = GetIdList(paramName);
            query = query.Where(x => x.InternalEntityId.HasValue && idList.Contains(x.InternalEntityId.Value));
        }

        paramName = "Pipeline";
        if (HasParam(paramName))
        {
            await FixInvalidFilterParams(paramName);
            var idList = GetIdList(paramName);
            query = query.Where(x => x.PipelineId.HasValue && (idList.Contains(x.PipelineId.Value) || idList.Contains(x.PipelineSourceDeliveryId ?? 0)));
        }

        paramName = "Point/Hub";
        if (HasParam(paramName))
        {
            await FixInvalidFilterParams(paramName);
            var idList = GetIdList(paramName);
            query = query.Where(x => x.PointId.HasValue && idList.Contains(x.PointId.Value));
        }

        paramName = "Portfolio";
        if (HasParam(paramName))
        {
            await FixInvalidFilterParams(paramName);
            var idList = GetIdList(paramName);
            query = query.Where(x => x.PortfolioId.HasValue && idList.Contains(x.PortfolioId.Value));
        }

        paramName = "Region";
        if (HasParam(paramName))
        {
            await FixInvalidFilterParams(paramName);
            var idList = GetIdList(paramName);
            query = query.Where(x => x.RegionId.HasValue && idList.Contains(x.RegionId.Value));
        }

        paramName = "Strategy";
        if (HasParam(paramName))
        {
            await FixInvalidFilterParams(paramName);
            var idList = GetIdList(paramName);
            query = query.Where(x => x.StrategyId.HasValue && idList.Contains(x.StrategyId.Value));
        }

        paramName = "Trader";
        if (HasParam(paramName))
        {
            await FixInvalidFilterParams(paramName);
            var idList = GetIdList(paramName);
            query = query.Where(x => x.TraderId.HasValue && idList.Contains(x.TraderId.Value));
        }

        paramName = "Transaction Type";
        if (HasParam(paramName))
        {
            await FixInvalidFilterParams(paramName);
            var idList = GetIdList(paramName);
            query = query.Where(x => x.TransactionTypeId.HasValue && idList.Contains(x.TransactionTypeId.Value));
        }

        paramName = "Position Date";
        if (!HasParam(paramName))
        {
            var dateRange = new DateRange(Enums.DateStyle.DateRange, Util.Date.FirstDayOfMonth(DateTime.Today), Util.Date.LastDayOfMonth(DateTime.Today));
            AddDateRangeParam(paramName, dateRange);
        }
        var positionDateExp = GetDateRangeExpression<VwRptDeal>(paramName, "StartDate", "EndDate", false);
        query = query.Where(positionDateExp);

        paramName = "Trade Date";
        if (HasParam(paramName))
        {
            var exp = GetDateRangeExpression<VwRptDeal>(paramName, "TradeDate", true);
            query = query.Where(exp);
        }

        var result = await query.ToListAsync();
        FillSheet("Trades", result);

        return GetNewFilterParams();
    }
}
