using Hcs.Broker.Api.Payload.HouseManagement;
using Hcs.Broker.Api.Request.Exception;
using Hcs.Broker.Internal;
using Hcs.Service.Async.HouseManagement;

namespace Hcs.Broker.Api.Request.HouseManagement
{
    internal class ImportHouseUODataRequest(Client client) : HouseManagementRequestBase(client)
    {
        protected override bool CanBeRestarted => false;

        internal async Task<bool> ExecuteAsync(ImportLivingHouseUODataPayload payload, CancellationToken token)
        {
            // TODO: Добавить проверку пейлоада

            // http://open-gkh.ru/HouseManagement/importHouseUORequest.html
            var request = new importHouseUORequest
            {
                Id = Constants.SIGNED_XML_ELEMENT_ID,
                version = "13.2.3.2",
                Item = GetLivingHouseFromPayload(payload)
            };

            var result = await SendAndWaitResultAsync(request, async asyncClient =>
            {
                var response = await asyncClient.importHouseUODataAsync(CreateRequestHeader(), request);
                return response.AckRequest.Ack;
            }, token);

            result.Items.OfType<ErrorMessageType>().ToList().ForEach(error =>
            {
                throw RemoteException.CreateNew(error.ErrorCode, error.Description);
            });

            var importResults = result.Items.OfType<getStateResultImportResult>();
            var commonResults = GetCommonResults(importResults);
            foreach (var commonResult in commonResults)
            {
                if (commonResult.ItemElementName == ItemChoiceType26.ImportHouseUO)
                {
                    return commonResult.Item is OGFImportStatusType;
                }
            }

            return false;
        }

        private importHouseUORequestLivingHouse GetLivingHouseFromPayload(ImportLivingHouseUODataPayload payload)
        {
            var livingHouse = new importHouseUORequestLivingHouseLivingHouseToCreate()
            {
                TransportGUID = Guid.NewGuid().ToString(),
                BasicCharacteristicts = new HouseBasicUOType()
                {
                    FIASHouseGuid = payload.fiasHouseGuid.ToString(),
                    TotalSquare = payload.totalSquare,
                    State = new nsiRef()
                    {
                        Code = payload.state.Code,
                        GUID = payload.state.GUID
                    },
                    LifeCycleStage = new nsiRef()
                    {
                        Code = payload.lifeCycleStage.Code,
                        GUID = payload.lifeCycleStage.GUID
                    },
                    UsedYear = payload.usedYear,
                    FloorCount = payload.floorCount,
                    OKTMO = payload.oktmo,
                    OlsonTZ = new nsiRef()
                    {
                        Code = payload.olsonTZ.Code,
                        GUID = payload.olsonTZ.GUID
                    },
                    CulturalHeritage = payload.culturalHeritage,
                    OGFData = payload.ogfData,
                    // TODO: Разобраться с кадастровым номером
                    Items = [true, payload.conditionalNumber],
                    ItemsElementName = [ItemsChoiceType3.NoCadastralNumber, ItemsChoiceType3.ConditionalNumber]
                }
            };

            if (!payload.isMunicipalProperty)
            {
                livingHouse.BasicCharacteristicts.IsMunicipalProperty = false;
                livingHouse.BasicCharacteristicts.IsMunicipalPropertySpecified = true;
            }

            if (!payload.isRegionProperty)
            {
                livingHouse.BasicCharacteristicts.IsRegionProperty = false;
                livingHouse.BasicCharacteristicts.IsRegionPropertySpecified = true;
            }

            if (payload.hasBlocks)
            {
                livingHouse.HasBlocks = true;
                livingHouse.HasBlocksSpecified = true;
            }

            if (payload.hasMultipleHousesWithSameAddress)
            {
                livingHouse.HasMultipleHousesWithSameAddress = true;
                livingHouse.HasMultipleHousesWithSameAddressSpecified = true;
            }

            return new importHouseUORequestLivingHouse()
            {
                Item = livingHouse
            };
        }
    }
}
