package com.eshore.gringotts.web.domain.controller;

import com.eshore.gringotts.web.configuration.amis.AmisResponse;
import com.eshore.gringotts.web.domain.base.controller.SimpleControllerSupport;
import com.eshore.gringotts.web.domain.base.entity.FileInfo;
import com.eshore.gringotts.web.domain.base.entity.SimpleListItem;
import com.eshore.gringotts.web.domain.base.entity.SimpleSaveItem;
import com.eshore.gringotts.web.domain.entity.Confirmation;
import com.eshore.gringotts.web.domain.service.ConfirmationService;
import com.eshore.gringotts.web.domain.service.DataFileService;
import com.eshore.gringotts.web.domain.service.DataResourceService;
import com.fasterxml.jackson.core.JsonProcessingException;
import java.time.LocalDateTime;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.collections.api.factory.Sets;
import org.eclipse.collections.api.set.ImmutableSet;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author lanyuanxiaoyao
 * @date 2024-11-26
 */
@Slf4j
@RestController
@RequestMapping("confirmation")
public class ConfirmationController extends SimpleControllerSupport<Confirmation, ConfirmationController.SaveItem, ConfirmationController.ListItem, ConfirmationController.DetailItem> {
    private final ConfirmationService confirmationService;
    private final DataResourceService dataResourceService;
    private final DataFileService dataFileService;

    public ConfirmationController(ConfirmationService service, ConfirmationService confirmationService, DataResourceService dataResourceService, DataFileService dataFileService) {
        super(service);
        this.confirmationService = confirmationService;
        this.dataResourceService = dataResourceService;
        this.dataFileService = dataFileService;
    }

    @GetMapping("/submit/{id}")
    public AmisResponse<Object> submit(@PathVariable Long id) throws JsonProcessingException {
        confirmationService.submit(id);
        return AmisResponse.responseSuccess();
    }

    @GetMapping("/retract/{id}")
    public AmisResponse<Object> retract(@PathVariable Long id) {
        confirmationService.retract(id);
        return AmisResponse.responseSuccess();
    }

    @Override
    protected Confirmation fromSaveItem(SaveItem item) throws Exception {
        Confirmation confirmation = new Confirmation();
        confirmation.setId(item.getId());
        confirmation.setDescription(item.getDescription());
        confirmation.setTarget(dataResourceService.detailOrThrow(item.getTargetId()));
        confirmation.setEvidences(dataFileService.list(item.getEvidenceFiles().collect(FileInfo::getValue)).toSet());
        return confirmation;
    }

    @Override
    protected ListItem toListItem(Confirmation entity) {
        return new ListItem(entity);
    }

    @Override
    protected DetailItem toDetailItem(Confirmation entity) {
        return new DetailItem(entity);
    }

    @Data
    @EqualsAndHashCode(callSuper = true)
    public static class SaveItem extends SimpleSaveItem<Confirmation> {
        private Long targetId;
        private String description;
        private ImmutableSet<FileInfo> evidenceFiles;
    }

    @Data
    @EqualsAndHashCode(callSuper = true)
    public static final class ListItem extends SimpleListItem<Confirmation> {
        private String name;
        private String description;
        private String state;

        public ListItem(Confirmation confirmation) {
            this.setId(confirmation.getId());
            this.setName(confirmation.getTarget().getName());
            this.setDescription(confirmation.getDescription());
            this.setState(confirmation.getState().name());
            this.setCreatedUsername(confirmation.getCreatedUser().getUsername());
            this.setCreatedTime(confirmation.getCreatedTime());
        }
    }

    @Data
    @EqualsAndHashCode(callSuper = true)
    public static final class DetailItem extends SaveItem {
        private String targetName;
        private LocalDateTime createdTime;
        private String createdUsername;
        private LocalDateTime modifiedTime;
        private String modifiedUsername;

        public DetailItem(Confirmation confirmation) {
            this.setId(confirmation.getId());
            this.setTargetId(confirmation.getTarget().getId());
            this.setTargetName(confirmation.getTarget().getName());
            this.setDescription(confirmation.getDescription());
            this.setEvidenceFiles(Sets.immutable.ofAll(confirmation.getEvidences()).collect(FileInfo::new));
            this.setCreatedTime(confirmation.getCreatedTime());
            this.setCreatedUsername(confirmation.getCreatedUser().getUsername());
            this.setModifiedTime(confirmation.getModifiedTime());
            this.setModifiedUsername(confirmation.getModifiedUser().getUsername());
        }
    }
}
