package org.msh.etbm.services.mobile;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.msh.etbm.rest.mobile.SyncFromServerRequest;
import org.msh.etbm.services.mobile.init.CaseData1Response;
import org.msh.etbm.services.mobile.init.Step3InitGenerator;
import org.msh.etbm.services.mobile.init.Step4InitGenerator;
import org.msh.etbm.services.mobile.init.Step5InitGenerator;
import org.msh.etbm.services.mobile.model.DeletedEntityData;
import org.msh.etbm.services.mobile.model.TbCaseData;
import org.msh.etbm.services.mobile.sync.*;
import org.msh.etbm.rest.mobile.SyncCasesRequest;
import org.msh.etbm.services.mobile.sync.server.DeletedEntityDataGenerator;
import org.msh.etbm.services.mobile.sync.server.SyncCaseData2Response;
import org.msh.tb.entities.Tbunit;

import java.util.List;
import java.util.Map;

/**
 * Created by rmemoria on 5/9/17.
 */
@Name("syncDataService")
@AutoCreate
@Scope(ScopeType.APPLICATION)
public class SyncDataService {

    @In
    MobileLoginService mobileLoginService;

    @In
    SyncSummaryService syncSummaryService;

    public Map<String, Object> syncCaseData(final Tbunit unit, SyncCasesRequest req) {
        // consume it
        Map<String, Object> ret = callConsumer(unit, req.getCases(), CaseDataConsumer.class);

        // regiter a sync summary
        syncSummaryService.createSummary(unit, req);

        return ret;
    }

    public SyncCaseFollowupResponse syncCaseFollowupData(final Tbunit unit, SyncCaseFollowupRequest req) {
        SyncCaseFollowupResponse resp = new SyncCaseFollowupResponse();

        resp.setXpertExams(callConsumer(unit, req.getXpertExams(), ExamXpertConsumer.class));
        resp.setMicroscopyExams(callConsumer(unit, req.getMicroscopyExams(), ExamMicroscopyDataConsumer.class));
        resp.setCultureExams(callConsumer(unit, req.getCultureExams(), ExamCultureConsumer.class));
        resp.setDstExams(callConsumer(unit, req.getDstExams(), ExamDstConsumer.class));
        resp.setContacts(callConsumer(unit, req.getContacts(), ContactConsumer.class));
        resp.setHivExams(callConsumer(unit, req.getHivExams(), ExamHivConsumer.class));
        resp.setMedicalExaminations(callConsumer(unit, req.getMedicalExaminations(), MedicalExaminationConsumer.class));
        resp.setXrayExams(callConsumer(unit, req.getXrayExams(), ExamXRayConsumer.class));
        resp.setCaseSideEffects(callConsumer(unit, req.getCaseSideEffects(), CaseSideEffectConsumer.class));
        resp.setComorbidities(callConsumer(unit, req.getComorbidities(), CaseComorbidityConsumer.class));

        return resp;
    }

    public void syncDeletedEntityData(final Tbunit unit, SyncDeletedEntityRequest req) {
        callConsumer(unit, req.getDeletedEntities(), DeletedEntityConsumer.class);
    }

    private Map<String, Object> callConsumer(final Tbunit unit, List lst, Class<? extends SyncDataConsumer> consumer) {
        if (lst == null || lst.isEmpty()) {
            return null;
        }

        TransactionalBatchIterator iterator = new TransactionalBatchIterator();
        iterator.execute(unit, lst, consumer);
        return iterator.getKeys();
    }

    public List<DeletedEntityData> syncDeletedEntityFromServer(Tbunit unit, SyncFromServerRequest serverIndex) {
        DeletedEntityDataGenerator generator = new DeletedEntityDataGenerator();
        return generator.generate(unit, serverIndex);
    }

    public List<TbCaseData> syncTbCaseDataFromServer(Tbunit unit, SyncFromServerRequest serverIndex) {
        Step3InitGenerator generator = new Step3InitGenerator();
        return generator.generate(unit, serverIndex);
    }

    public CaseData1Response syncCaseData1FromServer(Tbunit unit, SyncFromServerRequest serverIndex) {
        Step4InitGenerator generator = new Step4InitGenerator();
        return generator.generate(unit, serverIndex);
    }

    public SyncCaseData2Response syncCaseData2FromServer(Tbunit unit, SyncFromServerRequest serverIndex) {
        Step5InitGenerator generator = new Step5InitGenerator();
        SyncCaseData2Response data = new SyncCaseData2Response();

        data.setCaseData(generator.generate(unit, serverIndex));
        data.setServerIndex(mobileLoginService.calcLastTransaction());

        return data;
    }
}
