using e_suite.API.Common.models;
using e_suite.API.Common.repository;
using e_suite.Database.Audit;
using e_suite.Database.Core;
using e_suite.Database.Core.Extensions;
using e_suite.Database.Core.Tables.CustomFields;
using e_suite.Database.Core.Tables.Domain;
using e_suite.Database.Core.Tables.Forms;
using e_suite.Database.Core.Tables.Glossaries;
using eSuite.Core.Miscellaneous;
using Microsoft.EntityFrameworkCore;
using Sequence = e_suite.Database.Core.Tables.Sequences.Sequence;

namespace e_suite.Modules.CustomFieldsManager.Repository;

public class CustomFieldReferenceObjectRepository : RepositoryBase, ICustomFieldReferenceObjectRepository
{
#pragma warning disable IDE0290
    public CustomFieldReferenceObjectRepository(IEsuiteDatabaseDbContext databaseDbContext) : base(databaseDbContext)
    {
    }
#pragma warning restore IDE0290

    public async Task<Sequence?> GetSequenceByGeneralRefIdAsync(IGeneralIdRef idRef, CancellationToken cancellationToken)
        => await DatabaseDbContext.Sequences.FindByGeneralIdRefAsync(idRef, cancellationToken);

    public async Task<FormTemplate?> GetFormTemplateByGeneralRefIdAsync(IGeneralIdRef idRef, CancellationToken cancellationToken)
        => await DatabaseDbContext.FormTemplates.FindByGeneralIdRefAsync(idRef, cancellationToken);

    public async Task<Glossary?> GetGlossaryByGeneralRefIdAsync(IGeneralIdRef idRef, CancellationToken cancellationToken)
        => await DatabaseDbContext.Glossaries.FindByGeneralIdRefAsync(idRef, cancellationToken);

    public async Task<Domain?> GetDomainByGeneralRefIdAsync(IGeneralIdRef idRef, CancellationToken cancellationToken)
        => await DatabaseDbContext.Domains.FindByGeneralIdRefAsync(idRef, cancellationToken);

    public async Task CreateFormReferenceAsync(AuditUserDetails auditUserDetails, long customField, long formId, CancellationToken cancellationToken)
    {
        var customFieldSequence = new CustomFieldSequence
        {
            CustomFieldId = customField,
            SequenceId = formId
        };
        await DatabaseDbContext.CustomFieldSequences.AddAsync(customFieldSequence, cancellationToken);
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }

    public async Task CreateGlossaryReferenceAsync(AuditUserDetails auditUserDetails, long customField, long glossaryId, CancellationToken cancellationToken)
    {
        var customFieldGlossary = new CustomFieldGlossary
        {
            CustomFieldId = customField,
            GlossaryId = glossaryId,
        };
        await DatabaseDbContext.CustomFieldGlossaries.AddAsync(customFieldGlossary, cancellationToken);
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }

    public Task CreateDomainReferenceAsync(AuditUserDetails auditUserDetails, long customField, long formId, CancellationToken cancellationToken)
    {
        throw new NotImplementedException();
    }

    public async Task CreateSequenceReferenceAsync(AuditUserDetails auditUserDetails, long customField, long sequenceId, CancellationToken cancellationToken)
    {
        var customFieldsequence = new CustomFieldSequence
        {
            CustomFieldId = customField,
            SequenceId = sequenceId
        };
        await DatabaseDbContext.CustomFieldSequences.AddAsync(customFieldsequence, cancellationToken);
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }

    public async Task DeleteFormReferenceAsync(AuditUserDetails auditUserDetails, long cusotmFieldId, CancellationToken cancellationToken)
    {
        var refObj = await DatabaseDbContext.CustomFieldFormTemplate.FirstOrDefaultAsync(cf => cf.CustomFieldId == cusotmFieldId, cancellationToken);
        if (refObj is not null)
        {
            DatabaseDbContext.CustomFieldFormTemplate.Remove(refObj);
            await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
        }
    }

    public async Task DeleteGlossaryReferenceAsync(AuditUserDetails auditUserDetails, long customFieldId, CancellationToken cancellationToken)
    {
        var refObj = await DatabaseDbContext.CustomFieldGlossaries.FirstOrDefaultAsync(cf => cf.CustomFieldId == customFieldId, cancellationToken);
        if (refObj is not null)
        {
            DatabaseDbContext.CustomFieldGlossaries.Remove(refObj!);
            await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
        }
    }

    public Task DeleteDomainReferenceAsync(AuditUserDetails auditUserDetails, long customField, CancellationToken cancellationToken)
    {
        throw new NotImplementedException();
    }

    public async Task DeleteSequenceReferenceAsync(AuditUserDetails auditUserDetails, long customFieldId, CancellationToken cancellationToken)
    {
        var refObj = await DatabaseDbContext.CustomFieldSequences.FirstOrDefaultAsync(cf => cf.CustomFieldId == customFieldId, cancellationToken);
        if (refObj is not null)
        {
            DatabaseDbContext.CustomFieldSequences.Remove(refObj!);
            await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
        }
    }

    public async Task<CustomFieldFormTemplate?> GetFormReferenceAsync(long customFieldId, CancellationToken cancellationToken)
        => await DatabaseDbContext.CustomFieldFormTemplate.FirstOrDefaultAsync(cf => cf.CustomFieldId == customFieldId, cancellationToken);

    public async Task<CustomFieldSequence?> GetSequenceReferenceAsync(long customFieldId, CancellationToken cancellationToken)
        => await DatabaseDbContext.CustomFieldSequences.FirstOrDefaultAsync(cf => cf.CustomFieldId == customFieldId, cancellationToken);

    public async Task<CustomFieldGlossary?> GetGlossaryReferenceAsync(long customFieldId, CancellationToken cancellationToken)
        => await DatabaseDbContext.CustomFieldGlossaries.FirstOrDefaultAsync(cf => cf.CustomFieldId == customFieldId, cancellationToken);

    public async Task CreateCustomFieldNumbersAsync(
        AuditUserDetails auditUserDetails,
        CustomFieldNumber customFieldNumber,
        CancellationToken cancellationToken
    )
    {
        await DatabaseDbContext.CustomFieldNumber.AddAsync(customFieldNumber, cancellationToken);
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }

    public async Task EditCustomFieldNumbersAsync(
        AuditUserDetails auditUserDetails,
        CustomFieldNumber customFieldNumber,
        NumberFieldParameters numberFieldParameters,
        CancellationToken cancellationToken
    )
    {
        DatabaseDbContext.CustomFieldNumber.Update(customFieldNumber);
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }

    public async Task<CustomFieldNumber?> GetNumbersParametersAsync(long customFieldId, CancellationToken cancellationToken)
    {
        return await DatabaseDbContext.CustomFieldNumber.Where(x => x.CustomFieldId == customFieldId)
            .SingleOrDefaultAsync(cancellationToken);
    }

    public async Task DeleteCustomFieldNumbersAsync(AuditUserDetails auditUserDetails, CustomFieldNumber customFieldNumber, CancellationToken cancellationToken)
    {
        DatabaseDbContext.CustomFieldNumber.Remove(customFieldNumber!);
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }

    public async Task EditFormReferenceAsync(AuditUserDetails auditUserDetails, CustomFieldFormTemplate customFieldFormTemplate, CancellationToken cancellationToken)
    {
        DatabaseDbContext.CustomFieldFormTemplate.Update(customFieldFormTemplate);
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }

    public async Task EditGlossaryReferenceAsync(AuditUserDetails auditUserDetails, CustomFieldGlossary customFieldGlossary, CancellationToken cancellationToken)
    {
        DatabaseDbContext.CustomFieldGlossaries.Update(customFieldGlossary);
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }

    public Task EditDomainReferenceAsync(AuditUserDetails auditUserDetails, CustomFieldGlossary customFieldGlossary, CancellationToken cancellationToken)
    {
        throw new NotImplementedException();
    }

    public async Task EditSequenceReferenceAsync(AuditUserDetails auditUserDetails, CustomFieldSequence customFieldSequence, CancellationToken cancellationToken)
    {
        DatabaseDbContext.CustomFieldSequences.Update(customFieldSequence);
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }

    public async Task<CustomFieldText?> GetTextsParametersAsync(long customFieldId, CancellationToken cancellationToken)
    {
        return await DatabaseDbContext.CustomFieldText.Where(x => x.CustomFieldId == customFieldId)
            .SingleOrDefaultAsync(cancellationToken);
    }

    public async Task CreateCustomFieldTextsAsync(AuditUserDetails auditUserDetails, CustomFieldText customFieldText, CancellationToken cancellationToken)
    {
        await DatabaseDbContext.CustomFieldText.AddAsync(customFieldText, cancellationToken);
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }

    public async Task EditCustomFieldTextsAsync(AuditUserDetails auditUserDetails, CustomFieldText customFieldText, TextFieldParameters textFieldParameters, CancellationToken cancellationToken)
    {
        DatabaseDbContext.CustomFieldText.Update(customFieldText);
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }

    public async Task DeleteCustomFieldTextsAsync(AuditUserDetails auditUserDetails, CustomFieldText customFieldText, CancellationToken cancellationToken)
    {
        DatabaseDbContext.CustomFieldText.Remove(customFieldText!);
        await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
    }
}