package com.samsung.sample.approval.knox.controller;

import com.samsung.approval.ApprovalService;
import com.samsung.approval.annotation.ApprovalDocument;
import com.samsung.approval.entity.DynamicApprovalPath;
import com.samsung.approval.entity.RequiredApprovalUser;
import com.samsung.approval.enums.ApprovalDocStatus;
import com.samsung.authentication.Account;
import com.samsung.common.IdGenService;
import com.samsung.core.entity.PagingResult;
import com.samsung.core.exception.KnoxApprovalException;
import com.samsung.resource.FileManagerService;
import com.samsung.sample.approval.knox.KnoxApprovalSampleService;
import com.samsung.sample.approval.knox.dto.KnoxApprovalSampleSearchDto;
import com.samsung.sample.approval.knox.dto.KnoxApprovalSubmitDto;
import com.samsung.sample.approval.knox.entity.KnoxApprovalSampleDocument;
import com.samsung.template.TemplateConstants;
import com.samsung.user.entity.User;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@RestController
@RequestMapping("/sample/approval/knox")
public class KnoxApprovalSampleController {

    private final FileManagerService fileManagerService;

    private final IdGenService idGenService;

    private final KnoxApprovalSampleService knoxApprovalSampleService;

    private final ApprovalService approvalService;

    private final MessageSourceAccessor messageSourceAccessor;

    public KnoxApprovalSampleController(FileManagerService fileManagerService, IdGenService idGenService, KnoxApprovalSampleService knoxApprovalSampleService, ApprovalService approvalService, MessageSourceAccessor messageSourceAccessor) {
        this.fileManagerService = fileManagerService;
        this.idGenService = idGenService;
        this.knoxApprovalSampleService = knoxApprovalSampleService;
        this.approvalService = approvalService;
        this.messageSourceAccessor = messageSourceAccessor;
    }

    @Operation(summary = "결재문서 목록 조회(페이징)")
    @GetMapping("/sample-document-with-paging")
    public PagingResult<KnoxApprovalSampleDocument> getSampleApprovalDocumentPagingList(@ModelAttribute KnoxApprovalSampleSearchDto sampleSearchDto) {
        return knoxApprovalSampleService.getSampleApprovalDocumentPagingList(sampleSearchDto);
    }

    @Operation(summary = "결재 문서 상세 조회")
    @GetMapping("/sample-documents/{docId}")
    public KnoxApprovalSampleDocument getSampleApprovalDocument(@Parameter(description = "문서 ID") @PathVariable String docId) {

        // 문서 상세정보 조회.
        KnoxApprovalSampleDocument sampleApprovalDocument = knoxApprovalSampleService.getSampleApprovalDocument(docId);

        // 결재 상신전 문서의 결재경로, 필수결재자 여부 setting.
        if (ApprovalDocStatus.SAVED.equals(sampleApprovalDocument.getDocStatus())) {

            // 결재 경로 추가(재직중인 사용자만 추가).
            String docType = KnoxApprovalSampleDocument.class.getAnnotation(ApprovalDocument.class).docType();
            List<DynamicApprovalPath> dynamicApprovalPathList = approvalService.getDynamicApprovalPath(docType);
            List<DynamicApprovalPath> dynamicApprovalUserList = new ArrayList<>(0);

            for (DynamicApprovalPath dynamicApprovalPath : dynamicApprovalPathList) {
                if ("B".equals(dynamicApprovalPath.getEmployeeStatus())) {
                    dynamicApprovalUserList.add(dynamicApprovalPath);
                }
            }

            // 필수 결재자 존재 여부 확인.
            boolean checkExistRequiredApprovalUser = false;
            List<RequiredApprovalUser> requiredApprovalUserList = approvalService.getRequiredApprovalUserList(docType);
            if (!requiredApprovalUserList.isEmpty()) checkExistRequiredApprovalUser = true;

            sampleApprovalDocument.setDynamicApprovalUserList(dynamicApprovalUserList);
            sampleApprovalDocument.setExistRequiredApprovalUser(checkExistRequiredApprovalUser);
            sampleApprovalDocument.setRequiredApprovalUserList(requiredApprovalUserList);
        }

        sampleApprovalDocument.setAttachments(fileManagerService.getAttachFileList(docId, docId));

        return sampleApprovalDocument;
    }

    @Operation(summary = "결재 문서 저장")
    @PostMapping("/sample-documents")
    public KnoxApprovalSampleDocument saveDocument(@Parameter(description = "문서 제목") @RequestParam String title, @Parameter(description = "본문") @RequestParam String contents) {

        KnoxApprovalSampleDocument sampleApprovalDocument = new KnoxApprovalSampleDocument();
        String docId = idGenService.getNextStringId();
        sampleApprovalDocument.setDocId(docId);
        sampleApprovalDocument.setTitle(title);
        sampleApprovalDocument.setContents(contents);
        sampleApprovalDocument.setCreator(Objects.requireNonNull(Account.currentUser()).getUserName());

        knoxApprovalSampleService.insertSampleApprovalDocument(sampleApprovalDocument);
        return sampleApprovalDocument;
    }

    @Operation(summary = "결재 문서 수정")
    @PutMapping("/sample-documents/{docId}")
    public KnoxApprovalSampleDocument modifyDocument(@Parameter(description = "문서 ID") @PathVariable String docId, @Parameter(description = "본문") @RequestBody KnoxApprovalSampleDocument tempDoc) {

        knoxApprovalSampleService.modifySampleApprovalDocument(tempDoc);
        fileManagerService.updateFileRefId(docId, tempDoc.getAttachments(), docId);
        return tempDoc;
    }

    @Operation(summary = "결재 문서 삭제")
    @DeleteMapping("/sample-documents/{docId}")
    public void deleteDocument(@Parameter(description = "문서 ID") @PathVariable String docId) {

        KnoxApprovalSampleDocument sampleApprovalDocument = new KnoxApprovalSampleDocument();
        fileManagerService.updateFileRefId(docId, sampleApprovalDocument.getAttachments(), docId);
        sampleApprovalDocument.setDocId(docId);
        knoxApprovalSampleService.deleteSampleApprovalDocument(sampleApprovalDocument);
        fileManagerService.updateFileRefId(docId, null, docId);
    }

    @Operation(summary = "결재 문서 상신")
    @PostMapping("/submit/sample-document")
    public void submit(@RequestBody KnoxApprovalSubmitDto knoxApprovalSubmitDto) {

        if (StringUtils.isEmpty(knoxApprovalSubmitDto.getDocId())) throw new KnoxApprovalException("문서 ID는 필수 입니다.");
        if (ObjectUtils.isEmpty(knoxApprovalSubmitDto.getApprovalStepList()))
            throw new KnoxApprovalException("결재 패스는 필수 입니다.");

        //결재 문서 조회
        KnoxApprovalSampleDocument knoxApprovalSampleDocument = knoxApprovalSampleService.getSampleApprovalDocument(knoxApprovalSubmitDto.getDocId());

        ApprovalDocument approvalDocument = KnoxApprovalSampleDocument.class.getAnnotation(ApprovalDocument.class);
        String docType = approvalDocument.docType();
        User requester = Account.currentUser();
        String docId = knoxApprovalSampleDocument.getDocId();
        approvalService.submit(docType, knoxApprovalSampleDocument.getDocId(), knoxApprovalSampleDocument.getTitle(), approvalDocument, null, knoxApprovalSubmitDto.getComment(), requester, knoxApprovalSubmitDto.getApprovalStepList(), TemplateConstants.DOC_NAME, knoxApprovalSampleDocument, "attachments", fileManagerService.getAttachFileList(docId, docId), "messages", messageSourceAccessor, "internalApproval", approvalDocument.isInternalApproval());

    }

}
