private void InjectByRequest(CardResourceRequest request)
    {
        ICard card = _creator.CreateByRequest(request);

        if (!_requestsCards.ContainsKey(request))
        {
            _requestsCards[request] = new List <ICard>();
        }
        _requestsCards[request].Add(card);
        if (card != null)
        {
            CardProvide(card);
        }
        ResetProvidingTimer(request.Data);
    }
    public void StopRequestFor(ResourceCardData data)
    {
        CardResourceRequest reqToDelete = null;

        foreach (CardResourceRequest r in _requests)
        {
            if (r.Data == data)
            {
                reqToDelete = r;
                break;
            }
        }
        if (reqToDelete != null)
        {
            PauseProvidingTimer(data);
        }
        _requests.Remove(reqToDelete);
        // CheckRequests();
    }
    public void ProcessRequest(CardResourceRequest request)
    {
        CardResourceRequest reqToDisplace = null;

        foreach (CardResourceRequest r in _requests)
        {
            if (r.Data == request.Data)
            {
                reqToDisplace = r;
                break;
            }
        }
        _requests.Remove(reqToDisplace);
        _requests.Add(request);
        if (reqToDisplace == null)
        {
            DayTimer timer = InitProvidingTimer(request.Data);
            timer.AddTimerFinishedListener(() => InjectByRequest(request));
        }
        ResetProvidingTimer(request.Data);
        // CheckRequests();
    }
    public void StopRequestForCard(ICard card)
    {
        CardResourceRequest req = null;

        foreach (var item in _requestsCards)
        {
            if (item.Value.Contains(card))
            {
                req = item.Key;
                break;
            }
        }
        if (req != null)
        {
            _requestsCards.Remove(req);
            if (_requests.Contains(req))
            {
                PauseProvidingTimer(req.Data);
                _requests.Remove(req);
                CurrentRequestStopped(req.Data);
            }
        }
    }
    private void StartRequestProcessing(string name, int departmentIdx, int levelIdx, Dictionary <string, int> paramsIndices)
    {
        CardResourceRequest request = new CardResourceRequest();
        int resNum = -1;

        for (int i = 0; i < _cardsInUse.Count; i++)
        {
            if (_cardsInUse[i].CardName == name)
            {
                resNum = i;
                break;
            }
        }
        if (resNum == -1)
        {
            return;
        }

        // string department = _departmentsValues[departmentIdx];
        // Dictionary<string, int> paramsValues = new Dictionary<string, int>();
        // foreach (string paramName in paramsIndices.Keys)
        //     paramsValues[paramName] = _cardsParamsValues[resNum][paramName][paramsIndices[paramName]];

        List <int> parameters = paramsIndices.Values.ToList();

        request.Data = _cardsInUse[resNum];
        // request.Department = _departments.GetDepartment(departmentIdx);
        request.Department = departmentIdx;
        request.Level      = _levelValues[levelIdx];
        request.Parameters = new Dictionary <CardParameter, int>();
        for (int i = 0; i < paramsIndices.Count; i++)
        {
            request.Parameters[_cardsInUse[resNum].Parameters[i]] = parameters[i];
        }
        _provider.ProcessRequest(request);
    }
    public ICard CreateByRequest(CardResourceRequest request)
    {
        int maxLevel = _generalParameters.maxCardLevel;
        int sum      = request.Parameters.Values.Sum();
        int finalSum = sum * request.Level;
        int maxSum   = request.Parameters.Keys.Select(x => x.MaxValue).Sum();

        int x_min = (int)Math.Ceiling((double)finalSum / maxSum);
        int x_max = Math.Min(maxLevel, sum);
        int x_avg = (x_max + x_min) / 2;

        int x_from = Mathf.Clamp(x_avg - 2, 1, maxLevel);
        int x_to   = Mathf.Clamp(x_avg + 2, 1, maxLevel);
        int x_rdm  = Random.Range(x_from, x_to);

        int        baseSum   = (int)Math.Ceiling((double)finalSum / x_rdm);
        List <int> reqValues = request.Parameters.Values.ToList();
        int        minParam  = reqValues.Where(x => x != 0).DefaultIfEmpty().Min();;
        // foreach (int p in reqValues)
        //     if (p < minParam && p != 0)
        //         minParam = p;
        List <int> ratios = new List <int>();

        if (minParam != 0)
        {
            foreach (int p in reqValues)
            {
                ratios.Add((int)Math.Ceiling((double)p / minParam));
            }
        }
        else
        {
            ratios = reqValues;
        }
        int        ratiosSum = ratios.Sum();
        double     piece     = (double)baseSum / ratiosSum;
        List <int> argParams = new List <int>();

        for (int i = 0; i < request.Parameters.Count; i++)
        {
            int temp = (int)Math.Truncate((double)ratios[i] * piece);
            argParams.Add(Mathf.Clamp(temp, request.Data.Parameters[i].MinValue, request.Data.Parameters[i].MaxValue));
        }

        int restSum = (int)Math.Ceiling(baseSum * _generalParameters.requestRestParametersRate);

        restSum = Math.Max(restSum, _generalParameters.requestRestParametersMin);
        List <System.Tuple <int, int> > parametersLimits = new List <Tuple <int, int> >();
        int paramsNum = request.Data.RootParameter.MaxValue;

        foreach (CardParameter p in request.Parameters.Keys)
        {
            parametersLimits.Add(new System.Tuple <int, int>(paramsNum - 1, p.MaxValue));
        }
        List <int> paramsResult = ResourceBaseCardArgs.GenerateRandom(parametersLimits, restSum, restSum + 10);
        Dictionary <CardParameter, List <int> > argsParameters = new Dictionary <CardParameter, List <int> >();

        for (int i = 0; i < request.Parameters.Count; i++)
        {
            argsParameters[request.Data.Parameters[i]] = paramsResult.GetRange(i * (paramsNum - 1), (paramsNum - 1));
            argsParameters[request.Data.Parameters[i]].Insert(request.Department, argParams[i]);
        }

        var builder = _creator.CreateBuilder <ResourceBaseCard, ResourceBaseCardArgs>(request.Data);

        builder.Arguments.parameters = argsParameters;
        builder.Arguments.level      = x_rdm;
        var result = builder.CreateCard();

        return(result);
    }