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 ImportAccountDataRequest(Client client) : HouseManagementRequestBase(client)
    {
        protected override bool CanBeRestarted => false;

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

            // http://open-gkh.ru/HouseManagement/importAccountRequest.html
            var request = new importAccountRequest
            {
                Id = Constants.SIGNED_XML_ELEMENT_ID,
                version = "10.0.1.1",
                Account = [GetAccountFromPayload(payload)]
            };

            var result = await SendAndWaitResultAsync(request, async asyncClient =>
            {
                var response = await asyncClient.importAccountDataAsync(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.ImportAccount)
                {
                    return commonResult.Item is getStateResultImportResultCommonResultImportAccount;
                }
            }

            return false;
        }

        private importAccountRequestAccount GetAccountFromPayload(ImportAccountDataPayload payload)
        {
            var account = new importAccountRequestAccount()
            {
                TransportGUID = Guid.NewGuid().ToString(),
                AccountNumber = payload.accountNumber,
                AccountGUID = payload.accountGUID,
                AccountReasons = payload.accountReasons,
                Item = true,
                Accommodation = payload.accomodations,
                PayerInfo = payload.payerInfo
            };

            switch (payload.accountType)
            {
                case ImportAccountDataPayload.AccountType.UO:
                    account.ItemElementName = ItemChoiceType8.isUOAccount;
                    break;

                case ImportAccountDataPayload.AccountType.RSO:
                    account.ItemElementName = ItemChoiceType8.isRSOAccount;
                    break;

                case ImportAccountDataPayload.AccountType.CR:
                    account.ItemElementName = ItemChoiceType8.isCRAccount;
                    break;

                case ImportAccountDataPayload.AccountType.RC:
                    account.ItemElementName = ItemChoiceType8.isRCAccount;
                    break;

                case ImportAccountDataPayload.AccountType.OGVorOMS:
                    account.ItemElementName = ItemChoiceType8.isOGVorOMSAccount;
                    break;

                case ImportAccountDataPayload.AccountType.TKO:
                    account.ItemElementName = ItemChoiceType8.isTKOAccount;
                    break;
            }

            if (payload.livingPersonsNumber.HasValue)
            {
                account.LivingPersonsNumber = payload.livingPersonsNumber.Value.ToString();
            }

            if (payload.totalSquare.HasValue)
            {
                account.TotalSquare = payload.totalSquare.Value;
                account.TotalSquareSpecified = true;
            }

            if (payload.residentialSquare.HasValue)
            {
                account.ResidentialSquare = payload.residentialSquare.Value;
                account.ResidentialSquareSpecified = true;
            }

            if (payload.heatedArea.HasValue)
            {
                account.HeatedArea = payload.heatedArea.Value;
                account.HeatedAreaSpecified = true;
            }

            return account;
        }
    }
}
