using System.Collections.Generic;
using System.Linq;
using iRIS.Framework.Common.ExtensionMethods;
using iRIS.InsuranceCore.Code.InsuranceProductsDocumentsProviders;
using iRIS.InsuranceCore.Code.Link2;
using iRIS.InsuranceCore.Entities;
using iRIS.Printing.Code.Queries;
using iRIS.Printing.Entities;

namespace iRIS.KaskoCore.Code.Implementations;

public class KaskoLink2PrintDocumentsProvider : Link2PrintDocumentsProvider
{
    private const string Link2KaskoPolicyCode = "LINK2_POLICY_AUTO_KASKO";
    private const string AdditionalAgreementFormCode = "Kasko_Additional_Agreement";
    private const string ModificationStatementFormCode = "Kasko_Modification_Statement";

    private const string InvoicePolicyCode = "INVOICE_AUTO_KASKO";
    private readonly string[] _kidPrintingFormCodes =
    {
        "KASKO_KID_NoPolicy",
        "LINK2_KID_KASKO"
    };

    public KaskoLink2PrintDocumentsProvider(
        IQueryPrintingStores printingStoresInfo,
        IQueryPrintingFormInfos printingFormsInfo,
        IEnumerable<ILink2PrintingDocumentsAvailabilityChecker> printDocumentsAvailabilyCheckers)
        : base(printingStoresInfo, printingFormsInfo, printDocumentsAvailabilyCheckers)
    {
    }

    public override List<PrintDocumentParameters> FindAvailablePrintDocumentPrintParameters(
        Basket basket,
        Deal deal,
        PrintDocumentFilter filter)
    {
        var printingData = GetPrintingDataForDeal(deal);
        var printingDatasAvailable = FilterPrintDataByAvailabilityCheck(printingData, basket, deal);

        printingDatasAvailable = printingDatasAvailable
          .WhereIf(!string.IsNullOrEmpty(filter.PrintDocumentCode), x => FilterByPrintingFormCode(x, filter, printingDatasAvailable))
          .WhereIf(!string.IsNullOrEmpty(filter.PrintDocumentType), x => FilterByPrintingFormTypeCode(x, filter, printingDatasAvailable))
          .ToList();

        return printingDatasAvailable
                .Select(pd => new PrintDocumentParameters
                {
                    IsPreview = pd.Status.IsPreview,
                    PrintingFormId = pd.PrintingForm.EntityId,
                    PrintingGroup = pd.PrintingStore.PrintingGroup
                })
                .ToList();
    }

    private bool FilterByPrintingFormTypeCode(
        (PrintingStore PrintingStore, PrintingFormInfo PrintingForm, PrintDocumentAvailabilityStatus Status) printingData,
        PrintDocumentFilter filter,
        List<(PrintingStore PrintingStore, PrintingFormInfo PrintingForm, PrintDocumentAvailabilityStatus Status)> printingDatas)
    {
        if (printingData.PrintingForm.PrintingFormTypeCode == filter.PrintDocumentType)
        {
            return true;
        }

        return SetPrintingGroupIfNeedCombineKidAndKaskoPolicy(printingData, printingDatas);
    }

    private bool FilterByPrintingFormCode(
        (PrintingStore PrintingStore, PrintingFormInfo PrintingForm, PrintDocumentAvailabilityStatus Status) printingData,
        PrintDocumentFilter filter,
        List<(PrintingStore PrintingStore, PrintingFormInfo PrintingForm, PrintDocumentAvailabilityStatus Status)> printingDatas)
    {
        if (filter.PrintDocumentCode == InvoicePolicyCode && _kidPrintingFormCodes.Contains(printingData.PrintingForm.Code))
        {
            return false;
        }

        if (printingData.PrintingForm.Code == filter.PrintDocumentCode)
        {
            return true;
        }

        if (CombineAdditionalAgreementAndModificationStatement(printingData, printingDatas))
        {
            return true;
        }

        return SetPrintingGroupIfNeedCombineKidAndKaskoPolicy(printingData, printingDatas);
    }

    private bool SetPrintingGroupIfNeedCombineKidAndKaskoPolicy(
        (PrintingStore PrintingStore, PrintingFormInfo PrintingForm, PrintDocumentAvailabilityStatus Status) printingData,
        List<(PrintingStore PrintingStore, PrintingFormInfo PrintingForm, PrintDocumentAvailabilityStatus Status)> printingDatas)
    {
        if (!_kidPrintingFormCodes.Contains(printingData.PrintingForm.Code))
        {
            return false;
        }

        var kaskoPrintingForm = printingDatas
               .FirstOrDefault(x => x.PrintingForm.Code == Link2KaskoPolicyCode);

        if (kaskoPrintingForm.PrintingForm != null
            && kaskoPrintingForm.Status.IsPreview)
        {
            printingData.PrintingStore.PrintingGroup = 1;
            kaskoPrintingForm.PrintingStore.PrintingGroup = 1;

            return true;
        }

        return false;
    }

    private bool CombineAdditionalAgreementAndModificationStatement(
    (PrintingStore PrintingStore, PrintingFormInfo PrintingForm, PrintDocumentAvailabilityStatus Status) printingData,
    List<(PrintingStore PrintingStore, PrintingFormInfo PrintingForm, PrintDocumentAvailabilityStatus Status)> printingDatas)
    {
        if (printingData.PrintingForm.Code != ModificationStatementFormCode)
        {
            return false;
        }

        var modificationPrintingForm = printingDatas
            .FirstOrDefault(x => x.PrintingForm.Code == AdditionalAgreementFormCode);

        if (modificationPrintingForm.PrintingForm != null)
        {
            printingData.PrintingStore.PrintingGroup = 1;
            modificationPrintingForm.PrintingStore.PrintingGroup = 1;

            return true;
        }

        return false;
    }
}