package org.msh.etbm.rest.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.commons.apidoc.annotations.ApiDoc;
import org.msh.etbm.commons.apidoc.annotations.ApiDocMethod;
import org.msh.etbm.rest.StandardResult;
import org.msh.etbm.rest.authentication.Authenticated;
import org.msh.etbm.services.mobile.MobileLoginService;
import org.msh.etbm.services.mobile.SyncDataService;
import org.msh.etbm.services.mobile.init.CaseData1Response;
import org.msh.etbm.services.mobile.model.DeletedEntityData;
import org.msh.etbm.services.mobile.model.TbCaseData;
import org.msh.etbm.services.mobile.sync.SyncCaseFollowupRequest;
import org.msh.etbm.services.mobile.sync.SyncCaseFollowupResponse;
import org.msh.etbm.services.mobile.sync.SyncDeletedEntityRequest;
import org.msh.etbm.services.mobile.sync.server.SyncCaseData2Response;
import org.msh.tb.entities.Tbunit;
import org.msh.tb.login.UserSession;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.List;
import java.util.Map;


/**
 * Created by rmemoria on 5/9/17.
 */
@Name("mobileSyncRest")
@Scope(ScopeType.APPLICATION)
@Path("/mobile")
@ApiDoc(
        group = "mobile",
        summary = "Return initialization data used in the mobile app initialization")
@AutoCreate
@Authenticated
public class MobileSyncRest {

    @In
    SyncDataService syncDataService;

    @In
    MobileLoginService mobileLoginService;

    @Path("/sync/serverindex")
    @Produces({MediaType.APPLICATION_JSON})
    @POST
    @ApiDocMethod(summary = "Respond with the current server index (last transaction id)",
            description = "This API is used basically by the mobile app to receive the current last transaction id (serverIndex)")
    public StandardResult getCurrentServerIndex() {
        return new StandardResult(true, mobileLoginService.calcLastTransaction());
    }

    @Path("/sync/cases")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    @POST
    @ApiDocMethod(summary = "Synchronize the given cases in the database",
            description = "This API is used basically by the mobile app to receive cases (new or modified) from " +
                    "the mobile and process them")
    public StandardResult syncCases(SyncCasesRequest req) {
        Tbunit unit = UserSession.getUserWorkspace().getTbunit();
        Map<String, Object> keys = syncDataService.syncCaseData(unit, req);
        return new StandardResult(true, keys);
    }

    @Path("/sync/casefollowup")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    @POST
    @ApiDocMethod(summary = "Synchronize the given cases followup data in the database",
            description = "This API is used basically by the mobile app to receive cases followup data from " +
                    "the mobile and process them")
    public StandardResult syncFollowupData(SyncCaseFollowupRequest req) {
        Tbunit unit = UserSession.getUserWorkspace().getTbunit();
        SyncCaseFollowupResponse resp = syncDataService.syncCaseFollowupData(unit, req);
        return new StandardResult(true, resp);
    }

    @Path("/sync/deletedentity")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    @POST
    @ApiDocMethod(summary = "Deletes on the server database the given entities",
            description = "This API is used basically by the mobile app to receive the deleted entities on mobile " +
                    "and process them")
    public StandardResult syncDeletedEntities(SyncDeletedEntityRequest req) {
        Tbunit unit = UserSession.getUserWorkspace().getTbunit();
        syncDataService.syncDeletedEntityData(unit, req);
        return new StandardResult(true, null);
    }

    @Path("/sync/server/deleted")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    @POST
    @ApiDocMethod(summary = "Synchronize the cases edited on server to mobile",
            description = "This API is used basically by the mobile app to receive cases (new or modified) from " +
                    "the server and process them")
    public List<DeletedEntityData> syncDeletedEntityFromServer(SyncFromServerRequest req) {
        Tbunit unit = UserSession.getUserWorkspace().getTbunit();
        return syncDataService.syncDeletedEntityFromServer(unit, req);
    }

    @Path("/sync/server/cases")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    @POST
    @ApiDocMethod(summary = "Synchronize the cases edited on server to mobile",
            description = "This API is used basically by the mobile app to receive cases (new or modified) from " +
                    "the server and process them")
    public List<TbCaseData> syncCasesFromServer(SyncFromServerRequest req) {
        Tbunit unit = UserSession.getUserWorkspace().getTbunit();
        return syncDataService.syncTbCaseDataFromServer(unit, req);
    }

    @Path("/sync/server/casedata/1")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    @POST
    @ApiDocMethod(summary = "Synchronize the case data edited on server to mobile",
            description = "This API is used basically by the mobile app to receive case data (new or modified) from " +
                    "the server and process them")
    public CaseData1Response syncCaseData1FromServer(SyncFromServerRequest req) {
        Tbunit unit = UserSession.getUserWorkspace().getTbunit();
        return syncDataService.syncCaseData1FromServer(unit, req);
    }

    @Path("/sync/server/casedata/2")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    @POST
    @ApiDocMethod(summary = "Synchronize the case data edited on server to mobile",
            description = "This API is used basically by the mobile app to receive case data (new or modified) from " +
                    "the server and process them")
    public SyncCaseData2Response syncCaseData2FromServer(SyncFromServerRequest req) {
        Tbunit unit = UserSession.getUserWorkspace().getTbunit();
        return syncDataService.syncCaseData2FromServer(unit, req);
    }
}
