package com.dbs.consentServer.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import com.dbs.consentServer.VO.consentVO.ConsentFormListVO;
import com.dbs.consentServer.exception.ItemNotFoundException;
import com.dbs.consentServer.service.ConsentService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@Api(tags = { "1. ConsentService " })
@RestController
@RequestMapping("/ConsentSvc")
public class ConsentSvc {

  private final Logger logger = LoggerFactory.getLogger(this.getClass());

  @Autowired
  private ConsentService consentService;

  @ApiOperation(value = "테스트 URI", notes = "테스트 URI 입니다.")
  @RequestMapping(value = "/test", method = RequestMethod.GET)
  public void test() throws Exception {
    logger.error("test");
  }

  /**
   * 동의서 조회 (미작성, 환자별, 작성자별)
   * 
   * @param patientCode  환자 등록번호
   * @param startDt      조회 시작 일자
   * @param endDt        조회 마지막 일자
   * @param consentState 동의서 상태 인증 : CERTIFY_CMP, 임시 : TEMP, 확인 : ELECTR_CMP, 연동 :
   *                     UNFINISHED, 출력 : PAPER_OUT 받을때 형식
   *                     'CERTIFY_CMP','TEMP','ELECTR_CMP'
   * @param instCd       기관코드
   * @param userId       작성자별 검색시 로그인 사용자 아이디
   * @return
   */
  @RequestMapping(path = "getConsentList", method = RequestMethod.POST)
  public ArrayList<HashMap<String, Object>> getConsentList(String patientCode, String startDt, String endDt,
      String consentState, String instCd, String userId) {
    ArrayList<HashMap<String, Object>> result = new ArrayList<HashMap<String, Object>>();
    HashMap<String, Object> map = new HashMap<String, Object>();
    HashMap<String, Object> params = new HashMap<String, Object>();

    String[] consentStateStrAr = {};
    if (!consentState.isEmpty()) {
      if (!consentState.equals("ALL")) {
        consentStateStrAr = consentState.trim().split(",");
        params.put("consentState", consentStateStrAr);
      } else {
        consentState = "ALL";
        params.put("consentState", consentState);
      }
    } else {
      consentState = "ALL";
      params.put("consentState", consentState);
    }

    params.put("patientCode", patientCode);
    params.put("startDt", startDt);
    params.put("endDt", endDt);

    params.put("instCd", instCd);
    params.put("userId", userId);

    ArrayList<ConsentFormListVO> consentList = consentService.getConsentList(params);

    if (consentList.size() == 0) {
      map.put("code", "01");
    } else {
      map.put("code", "00");
      map.put("data", consentList);
    }

    result.add(map);

    return result;
  }

  /**
   * Map 을 log 로 출력
   * @param map
   */
  private void loggingMap(Map<String, String> map){
    map.forEach((k, v) -> {
      logger.debug(String.format("[KEY] %s, [VALUE] %s", k, v));
    });
  }

  /**
   * 동의서 목록 조회, 현재 URL Mapping 은 getConsentList 로 되어 있음
   * 향후에는 ConsentList 로 변경 예정
   * @param reqQeury
   * @return
   * @throws ResponseStatusException 파라미터가 없는 경우 bad_request, 조회된 결과 없는 경우 no_content 반환
   */
  @GetMapping("getConsentList")   // ConsentList 로 변경 예정
  public List<ConsentFormListVO> getConsentList(@RequestParam final Map<String, Object> reqQeury) throws ResponseStatusException{
    if(reqQeury.isEmpty()){
      throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "request parameters are missing");
    }  

    reqQeury.forEach((k, v) -> {
      Optional.ofNullable(v).ifPresent(o -> {
        // 요청 파라미터가 consentState 일 경우 처리
        if(k.equals("consentState")){
          String tmp = String.valueOf(o);
          // , 구분자가 있는경우 배열로 파라미터를 채워준다
          if(tmp.indexOf(",") > 0){
            reqQeury.put(k, tmp.split(","));
          }
          // 그렇지 않을 경우 그대로 넣어준다
          // 단 빈 값으로 오면 ALL 로 치환하여 준다
          else{
            if(!tmp.equals("") || !tmp.equals("ALL")){
              String value = "'%" + tmp.trim() + "%''";
              reqQeury.put(k, new String[] {value});
            }
            
          }
        }
      });
    });

    return Optional.ofNullable(consentService.getConsentList(reqQeury))
      .filter(p -> p.size() > 0)
      .orElseThrow(() -> new ResponseStatusException(HttpStatus.NO_CONTENT, "no consents has found"));
  }

  /**
   * 즐겨찾기 목록 리스트
   * 
   * @param userId 사용자 아이디
   * @param instCd 기관코드
   * @return
   */
  @RequestMapping(path = "getUserFormSetList", method = RequestMethod.POST)
  public ArrayList<HashMap<String, Object>> getUserFormSetList(String userId, String instCd) {
    ArrayList<HashMap<String, Object>> result = new ArrayList<HashMap<String, Object>>();
    HashMap<String, Object> map = new HashMap<String, Object>();
    List<ConsentFormListVO> formList = new ArrayList<ConsentFormListVO>();
    HashMap<String, String> params = new HashMap<String, String>();

    params.put("userId", userId);
    params.put("instCd", instCd);

    formList = consentService.getUserFormSet(params);

    if (formList.size() == 0) {
      map.put("code", "01");
    } else {
      map.put("code", "00");
      map.put("data", formList);
    }

    result.add(map);

    return result;
  }

  /**
   * 사용자 즐겨찾기 목록 조회
   * 향후에는 URL 이 UserFormSetList 로 변경
   * @param reqQeury 요청 파라미터는 다음의 정보가 Map 으로 전달 된다
   * <pre>
   * userId 사용자 아이디
   * instcd 근무지기관코드
   * </pre>
   * @return
   */
  @GetMapping("getUserFormSetList")
  public List<ConsentFormListVO> getUserFormSetList(@RequestParam Map<String, String> reqQeury){
    Optional.ofNullable(reqQeury)
      .filter(o -> o.size() > 0)
      .orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST));

    return Optional.ofNullable(consentService.getUserFormSet(reqQeury))
      .filter(o -> o.size() > 0)
      .orElseThrow(() -> new ResponseStatusException(HttpStatus.NO_CONTENT, "no user form set found", new ItemNotFoundException("no user data")));
  }

  /**
   * 동의서 찾기
   * 
   * @param categoryId 동의서 카테고리
   * @param keyWord    검색할 동의서 이름
   * @return
   */
  @RequestMapping(path = "getConsentBySearch", method = RequestMethod.POST)
  public ArrayList<HashMap<String, Object>> getConsentBySearch(String categoryId, String keyWord) {
    ArrayList<HashMap<String, Object>> result = new ArrayList<HashMap<String, Object>>();
    HashMap<String, Object> map = new HashMap<String, Object>();
    List<ConsentFormListVO> formList = new ArrayList<ConsentFormListVO>();
    HashMap<String, String> params = new HashMap<String, String>();

    params.put("categoryId", categoryId);
    params.put("keyWord", "%" + keyWord + "%");

    formList = consentService.getConsentBySearch(params);
    if (formList.size() == 0) {
      map.put("code", "01");
    } else {
      map.put("code", "00");
      map.put("data", formList);
    }
    result.add(map);

    return result;
  }

  /**
   * 동의서 검색 GET 메서드
   * ConsentBySearch 로 URL 변경 예정
   * @param reqQeury 파라미터 목록
   * <pre>
   * @param categoryId 카테고리 ID
   * @param keyWord 검색어
   * </pre>
   * @return 검색된 동의서 메서드
   */
  @GetMapping("getConsentBySearch")
  public List<ConsentFormListVO> getConsentBySearch(@RequestParam Map<String, String> reqQeury) throws ItemNotFoundException{
    reqQeury.forEach((k, v) -> {
      if(k.equals("keyWord")){
        reqQeury.put(k, "%" + v + "%");
      }
    });

    return Optional.ofNullable(consentService.getConsentBySearch(reqQeury))
      .filter(o -> o.size() > 0)
      .orElseThrow(() -> new ResponseStatusException(HttpStatus.NO_CONTENT));
  }

  /**
   * 
   * @param reqQuery
   * <pre>
   *{@linkplain 
   *param userId 삭제하려는 사용자 ID
   *param consentMstRid 삭제할 서식 마스터 ID
   *param reasonForUseN 삭제 사유
   *}
   * </pre>
   * @return 삭제 카운트
   */
  @DeleteMapping("saveTempDelete")
  public int saveTempDelete(@RequestParam Map<String, Object> reqQuery){
    Optional.ofNullable(reqQuery)
      .orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST))
    ;

    return consentService.updateConsentMstForDelete(reqQuery);
  }

  /**
   * 임시저장 서식 삭제
   * 
   * @param userId
   * @param consentMstRid
   * @param reasonForUseN
   * @return
   */
  @RequestMapping(path = "saveTempDelete", method = RequestMethod.POST)
  public ArrayList<HashMap<String, Object>> saveTempDelete(String userId, int consentMstRid, String reasonForUseN) {
    ArrayList<HashMap<String, Object>> result = new ArrayList<HashMap<String, Object>>();
    HashMap<String, Object> map = new HashMap<String, Object>();
    HashMap<String, Object> params = new HashMap<String, Object>();

    int rCount = 0;
    // String ocrTag = "";

    params.put("userId", userId);
    params.put("consentMstRid", consentMstRid);
    params.put("reasonForUseN", reasonForUseN);

    rCount = consentService.updateConsentMstForDelete(params);

    if (rCount == 0) {
      map.put("code", 01);
    } else {
      map.put("code", 00);
      map.put("data", rCount);
    }

    // if (rCount == 0) {
    // map.put("code", "01");
    // } else {
    // ocrTag = consentService.getConsentMstForDeleteOcrTag(params);

    // if (!(ocrTag.equals("") || ocrTag.isEmpty())) {
    // params.put("ocrTag", ocrTag);
    // rCount = consentService.updateMrfhOcrPrntStatCd(params);

    // if (rCount == 0) {
    // map.put("code", "02");
    // } else {
    // map.put("code", "00");
    // map.put("data", rCount);
    // }
    // }
    // }
    result.add(map);

    return result;
  }

  @GetMapping("getOcrTag")
  public String getOcrTag(@RequestParam Map<String, String> reqQeury) {
    return Optional.ofNullable(consentService.getOcrTag())
      .filter(o -> !o.isEmpty())
      .orElseThrow(() -> new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "tag creation has been failed"));
  }

  /**
   * 
   * @return 생성된 OCRTAG 반환
   * @throws ItemNotFoundException OCRTAG 생성 오류 시 500 에러 반환
   */
  @RequestMapping(value = "getOcrTag", method = RequestMethod.POST)
  public String getOcrTag() throws ResponseStatusException{
    return Optional.ofNullable(consentService.getOcrTag()).filter(o -> !o.isEmpty())
      .orElseThrow(() -> new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, "ocrtag creation failed"));
  }
}
