using System;
using System.Linq;
using Valg.Eva.Skanning.Scan.Presentation.ReadSoftModel;
using Valg.Eva.Skanning.Scan.Presentation.ScanInProgress;
using Valg.EVA.Skanning.Identity;
using Valg.EVA.Skanning.Scan.ReadSoftContracts.Events;
using Valg.EVA.Skanning.Scan.ReadSoftContracts.Model;
using Valg.EVA.Skanning.Services.Scan;
using Valg.EVA.Skanning.ServicesModel.ServiceContracts.Scan.Write;
using Valg.EVA.Skanning.UserInterfaceElements;
using ScannedField = Valg.EVA.Skanning.ServicesModel.ServiceContracts.Scan.Write.ScannedField;
using ScannedImages = Valg.EVA.Skanning.ServicesModel.ServiceContracts.Scan.Write.ScannedImages;

namespace Valg.Eva.Skanning.Scan.Presentation.MainWindow
{
    
    
    
    
    
    
    
    
    
    
    public class ScanFormFinishedEventHandler : ViewModelBase
    {
        private readonly IScannedBallotPaperMapper scannedBallotPaperMapper;
        private readonly IScanService scanService;
        private readonly IIdentityProvider identityProvider;

        public ScanFormFinishedEventHandler(IScannedBallotPaperMapper scannedBallotPaperMapper, IScanService scanService, IIdentityProvider identityProvider)
        {
            this.scannedBallotPaperMapper = scannedBallotPaperMapper;
            this.scanService = scanService;
            this.identityProvider = identityProvider;
        }

        public void SaveBallotPaper(ScanFormFinishedEventArgs eventArgs, BoxScanningSession currentScanningSession)
        {
            if (!currentScanningSession.LastDatabaseCallFailed)
            {
                var scannableBallotPaperType = ScannableBallotPaperType.GetFromFormDefinition(eventArgs.Form.Name);

                var scannedBallotPaper = scannedBallotPaperMapper.MapScannedBallotPaper(eventArgs.Form, scannableBallotPaperType);

                var scannedFields = scannedBallotPaper.ScannedFields.Select(f => new ScannedField
                {
                    FieldIndex = f.FieldIndex,
                    FieldType = f.FieldType,
                    NeedsVerification = f.NeedsVerification,
                    Value = f.Value
                }).ToArray();

                var scannedImages = new ScannedImages
                {
                    Back = scannedBallotPaper.ScannedImages.Back,
                    Front = scannedBallotPaper.ScannedImages.Front,
                    BackRotationDegrees = scannedBallotPaper.ScannedImages.BackRotationDegrees,
                    FrontRotationDegrees = scannedBallotPaper.ScannedImages.FrontRotationDegrees
                };

                var parameters = new SaveScannedBallotPaperParameters(scannedBallotPaper.BallotPaperType,
                    scannedFields,
                    scannedImages,
                    identityProvider.GetCurrentUserName(),
                    currentScanningSession.Box.BoxCounting.BarcodeLong,
                    currentScanningSession.Box.BoxCounting.BarcodeShort,
                    currentScanningSession.CountingId,
                    currentScanningSession.Box.BoxCounting.Id,
                    currentScanningSession.Box.BoxCounting.ConcurrencyToken,
                    currentScanningSession.CountingEmlAreaContextId,
                    scannedBallotPaper.ScannedOrder);

                SaveScannedBallotPaperResult result = scanService.SaveScannedBallotPaper(parameters);

                if (result.HasDatabaseErrors)
                {
                    currentScanningSession.LastDatabaseCallFailed = true;
                    PublishEvent<SaveDataFailedEvent, EventArgs>(EventArgs.Empty);
                }
                else if (result.BoxCountingIsNotAcceptingScans || result.BoxCountingDoesNotExist)
                {
                    PublishEvent<BoxIsDeletedDuringScanEvent, EventArgs>(EventArgs.Empty);
                }
                else
                {
                    currentScanningSession.AnotherBallotWasScanned(scannedBallotPaper.ScannedImages.Front, scannedBallotPaper.ScannedImages.FrontRotationDegrees);
                    PublishEvent<AnotherBallotWasScannedEvent, EventArgs>(EventArgs.Empty);
                }
            }
        }
    }
}
