using IWS5.Core.Enums;
using IWS5.Core.EventTrigger;
using IWS5.Core.Models.TriggerAction;
using IWS5.DatabaseAccess.Interfaces;
using Microsoft.Data.SqlClient;
using Newtonsoft.Json;

namespace IWS5.Services.EventTrigger;

public class AssignFolderFieldValueFromQueryTriggerProcessor(
    IFieldDefinitionRepository fieldDefinitionRepository,
    IFieldInstanceStringRepository fieldInstanceStringRepository,
    IFieldInstanceNumberRepository fieldInstanceNumberRepository,
    IFieldInstanceDateRepository fieldInstanceDateRepository,
    ICustomQueryRepository customQueryRepository) : ITriggerProcessor
{
    public async Task<bool> ProcessTrigger(string triggerAction, int workItemId)
    {
        var model = JsonConvert.DeserializeObject<AssignFolderFieldValueFromQueryTriggerAction>(triggerAction);
        var fieldDefinition = await fieldDefinitionRepository.FindAsync(fd => fd.FieldId == model.FieldId &&  fd.ProcessId == model.ProcessId);

        var dataType = (FieldInstanceType)fieldDefinition.DataType;

        var newFieldValue = await customQueryRepository
            .ExecuteScalarStringOrDefaultAsync(model.SqlQuery, new SqlParameter("@workItemId", workItemId));

        if (string.IsNullOrWhiteSpace(newFieldValue)) 
            return true;
        
        var wasUpdated = false;
        
        switch (dataType)
        {
            case FieldInstanceType.Date:
                if(DateTime.TryParse(newFieldValue, out var date))
                    wasUpdated = await fieldInstanceDateRepository.UpdateOrInsertValueAsync(workItemId, model.FieldId, date);
                else
                    return false;
                break;
            case FieldInstanceType.Number:
                if (decimal.TryParse(newFieldValue, out var number))
                    wasUpdated = await fieldInstanceNumberRepository.UpdateOrInsertValueAsync(workItemId, model.FieldId, number);
                else
                    return false;
                break;
            case FieldInstanceType.String:
                wasUpdated = await fieldInstanceStringRepository.UpdateOrInsertValueAsync(workItemId, model.FieldId, newFieldValue);
                break;
        }

        return wasUpdated;
    }
}