package sgc.portal.mobile.web;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import sgc.portal.base.exception.BusinessException;
import sgc.portal.base.util.EasyHashMap;
import sgc.portal.com.sym.user.model.Login;
import sgc.portal.com.sym.user.model.LoginAs;
import sgc.portal.com.sym.user.model.UserDetails;
import sgc.portal.com.sym.user.service.LoginService;
import sgc.portal.mobile.dto.RoomSearchVo;
import sgc.portal.mobile.dto.TcsSearchCodeVo;
import sgc.portal.mobile.dto.TcsSearchDeftCustsignVo;
import sgc.portal.mobile.dto.TcsSearchDeftElpsVo;
import sgc.portal.mobile.dto.TcsSearchDeftVo;
import sgc.portal.mobile.dto.TcsSearchVo;
import sgc.portal.mobile.model.CodeVo;
import sgc.portal.mobile.model.MoPushhistVo;
import sgc.portal.mobile.model.SmComCovendVo;
import sgc.portal.mobile.model.TcsCodeCovendChrgrVo;
import sgc.portal.mobile.model.TcsCodeVo;
import sgc.portal.mobile.model.TcsDeftCustsignVo;
import sgc.portal.mobile.model.TcsDeftElpsVo;
import sgc.portal.mobile.model.TcsDeftStatusVo;
import sgc.portal.mobile.model.TcsDeftVo;
import sgc.portal.mobile.model.ZehrRomDisplVo;
import sgc.portal.mobile.model.ZehrRomInfoVo;
import sgc.portal.mobile.model.ZehrRomLoctnVo;
import sgc.portal.mobile.model.ZehrRomResrvtnVo;
import sgc.portal.mobile.model.ZehrSiteAddressVo;
import sgc.portal.mobile.service.AsService;
import sgc.portal.mobile.service.RoomService;
import sgc.portal.security.annotation.Secured;
import sgc.portal.security.annotation.SecurityPolicy;

/**
 * @author 5364
 *
 */
@RestController
@RequestMapping("/mobile/api")
public class MobileApiController {

	@Autowired
	private LoginService loginService;

	@Autowired
	private RoomService roomService;

	/**
	 * 협력업체 하자 확인 및 처리 관련 서비스
	 */
	@Autowired
	private AsService asService;

	/**
	 * @param mv
	 * @param request
	 * @return
	 */
	@PostMapping(value = "/login")
	@Secured(policy = SecurityPolicy.NONE)
	public UserDetails login(@RequestBody Login login, HttpServletRequest request) {
		return loginService.login(login, request);
	}

	/**
	 * 협력업체 로그인
	 * 
	 * @param login
	 * @param request
	 * @return
	 */
	@PostMapping(value = "/aslogin")
	@Secured(policy = SecurityPolicy.NONE)
	public UserDetails asLogin(@RequestBody LoginAs login, HttpServletRequest request) {
		return loginService.asLogin(login, request);
	}

	/**
	 * 협력업체 아이디 찾기 Exec As Id Find.
	 *
	 * @param login
	 *            the login
	 */
	@PostMapping(value = "/execAsIdFind")
	@Secured(policy = SecurityPolicy.NONE)
	public LoginAs execAsIdFind(@RequestBody LoginAs login) {
		return loginService.execAsIdFind(login);
	}

	/**
	 * AS Password 초기화
	 * 
	 * @param login
	 * @return
	 */
	@PostMapping(value = "/execAsPasswordInit")
	@Secured(policy = SecurityPolicy.NONE)
	public LoginAs execAsPasswordInit(@RequestBody LoginAs login) {
		return loginService.execAsPasswordInit(login);
	}

	/**
	 * AS Password 초기화
	 * 
	 * @param login
	 * @return
	 */
	@PostMapping(value = "/execAsPasswordChange")
	public LoginAs execAsPasswordChange(@RequestBody LoginAs login, UserDetails userDetail) {
	    login.setCmpnCd(userDetail.getCmpnCd());
        login.setLginId(userDetail.getLginId());
	    login.setUserName(userDetail.getUserNm());
	    login.setHpNo(userDetail.getHpNo());
		return loginService.execAsPasswordChange(login);
	}

    /**
     * 암호 규칙 가져오기
     * 
     * @return
     */
    @GetMapping(value = "/passwordRule")
    @Secured(policy = SecurityPolicy.NONE)
    public EasyHashMap<String, Object> selectComPasswordPolicyView() {
        return loginService.selectComPasswordPolicyView();
    }
	
	
	/**
	 * 로그인 정보
	 *
	 * @param session
	 *            the session
	 */
	@GetMapping(value = "/info")
    @Secured(policy = SecurityPolicy.NONE)
	public UserDetails logininfo(UserDetails userDetail) {
		return asService.getUserDetails(userDetail);
	}

	/**
	 * 로그인 정보
	 *
	 * @param session
	 *            the session
	 */
	@PostMapping(value = "/info")
	public UserDetails updateLogininfo(UserDetails userDetail, @RequestBody UserDetails vo) {
		userDetail.setConnSiteCd(vo.getConnSiteCd());
		userDetail.setPushUseYn(vo.getPushUseYn());
		userDetail.setPushKey(vo.getPushKey());
		userDetail.setDomainId(vo.getDomainId());
      	return asService.setUserDetails(userDetail);
	}

	/**
	 * Logout.
	 *
	 * @param session
	 *            the session
	 */
	@GetMapping(value = "/logout")
	@Secured(policy = SecurityPolicy.NONE)
	public void logout(HttpSession session) {
		loginService.logOut(session);
	}

	/**
	 * 권한 정보 확인
	 * 
	 * @param userDetails
	 * @param search
	 * @param fillType
	 * @return
	 */
	private TcsSearchVo setFillSearch(UserDetails userDetails, TcsSearchVo search, String fillType) {
		String covendId = "";
		if (userDetails != null) {
			search.setCmpnCd(userDetails.getCmpnCd());
			covendId = userDetails.getCovendId();
		} else {
			search.setCmpnCd("S0001");
		}
		switch (fillType) {
		case "as":
			if (covendId == null || "".equals(covendId)) {
				throw new BusinessException("협력업체만 접근 가능합니다.");
			} else if (userDetails != null){
				search.setLginId(userDetails.getLginId());
				search.setCovendId(covendId);
			}
			break;
		case "po":
			if (userDetails == null) {
				throw new BusinessException("임직원만 접근 가능합니다.");
			} else {
				search.setLginId(userDetails.getEmpNo());
			}
			break;
		case "auto":
			if (userDetails != null) {
				if (covendId != null || !"".equals(covendId)) {
					search.setLginId(userDetails.getLginId());
					search.setCovendId(covendId);
				} else {
					search.setLginId(userDetails.getEmpNo());
				}
			}
			break;
		}
		return search;
	}

	/**
	 * 하자) 하자접수처리 리스트
	 * 
	 * @param userDetails
	 * @param vo
	 * @return
	 */
	@GetMapping("/selectTcsDeftList")
	public List<TcsDeftVo> selectTcsDeftList(UserDetails userDetails, TcsSearchDeftVo vo) {
		setFillSearch(userDetails, vo, "auto");
		return asService.selectTcsDeftList(vo);
	}

	/**
	 * 하자) 하자접수처리 보기
	 * 
	 * @param userDetails
	 * @param vo
	 * @param deftNo
	 * @return
	 */
	@GetMapping("/selectTcsDeftView/{deftNo}")
	public TcsDeftVo selectTcsDeftView(UserDetails userDetails, TcsSearchDeftVo vo, @PathVariable String deftNo) {
		vo.setDeftNo(deftNo);
		setFillSearch(userDetails, vo, "auto");
		return asService.selectTcsDeftView(vo);
	}

	/**
	 * 하자) 하자처리경과 리스트
	 * 
	 * @param userDetails
	 * @param vo
	 * @param deftNo
	 * @return
	 */
	@GetMapping("selectTcsDeftElpsList/{deftNo}")
	public List<TcsDeftElpsVo> selectTcsDeftElpsList(UserDetails userDetails, TcsSearchDeftElpsVo vo,
			@PathVariable String deftNo) {
		setFillSearch(userDetails, vo, "auto");
		vo.setDeftNo(deftNo);
		return asService.selectTcsDeftElpsList(vo);
	}

	/**
	 * 하자) 하자처리경과 보기
	 * 
	 * @param userDetails
	 * @param vo
	 * @param deftNo
	 * @param prcgElpsSeq
	 * @return
	 */
	@GetMapping("selectTcsDeftElpsView/{deftNo}/{prcgElpsSeq}")
	public TcsDeftElpsVo selectTcsDeftElpsView(UserDetails userDetails, TcsSearchDeftElpsVo vo,
			@PathVariable String deftNo, @PathVariable String prcgElpsSeq) {
		setFillSearch(userDetails, vo, "auto");
		vo.setDeftNo(deftNo);
		vo.setPrcgElpsSeq(prcgElpsSeq);
		return asService.selectTcsDeftElpsView(vo);
	}

	/**
	 * 하자) 하자접수처리 통계 보기
	 * 
	 * @param vo
	 * @return
	 */
	@GetMapping("selectTcsDeftStatus")
	public TcsDeftStatusVo selectTcsDeftStatus(UserDetails userDetails, TcsSearchDeftVo vo) {
		setFillSearch(userDetails, vo, "auto");
		return asService.selectTcsDeftStatus(vo);
	}

	/**
	 * 
	 * 공통 - 코드 정보 리스트
	 * 
	 * @param userDetails
	 * @param id
	 * @return
	 */
	@GetMapping("/codes/{id}")
	@Secured(policy = SecurityPolicy.NONE)
	public List<TcsCodeVo> getCode(UserDetails userDetails, @PathVariable String id) {
		switch (id) {
		case "COMPANIES":
		case "companies":
			return asService.selectCodeCmpnList();
		case "SITECD":
		case "siteCd":
			return asService.selectCodeSiteList(setFillSearch(userDetails, new TcsSearchVo(), "auto"));
		case "ROOMCD":
		case "roomCd":
			RoomSearchVo roomSearch = new RoomSearchVo();
			List<CodeVo> orgRoomList = roomService.selectCodeRoomList(roomSearch);
			List<TcsCodeVo> roomList = new ArrayList<>();
			for(CodeVo item : orgRoomList) {
				TcsCodeVo tcsItem = new TcsCodeVo();
				tcsItem.setLabel(item.getLabel());
				tcsItem.setValue(item.getValue());
				roomList.add(tcsItem);
			}
			return roomList;
		case "RE002_APP":
			TcsSearchCodeVo searchRe002CodeVo = new TcsSearchCodeVo();
			setFillSearch(userDetails, searchRe002CodeVo, "auto");
			searchRe002CodeVo.setCommCd("RE002");
			List<TcsCodeVo> codeRe002List = asService.selectCodeList(searchRe002CodeVo);
			List<TcsCodeVo> codeRe002ResultList = new ArrayList<>();
			for (TcsCodeVo item : codeRe002List) {
				switch (item.getValue()) {
				case "20":
				case "30":
				case "40":
					codeRe002ResultList.add(item);
					break;
				default:
					break;
				}
			}
			return codeRe002ResultList;
		default:
			if (id.startsWith("DONG")) {
				String[] codeValues = id.split("_");
				switch (codeValues.length) {
				case 3:
					return asService.getSiteDongHsno(setFillSearch(userDetails, new TcsSearchVo(), "auto"),
							codeValues[1], codeValues[2]);
				case 2:
					return asService.getSiteDongHsno(setFillSearch(userDetails, new TcsSearchVo(), "auto"),
							codeValues[1], "");
				default:
					break;
				}
			} else if (id.startsWith("VENDRLBPR_")) {
				String[] codeValues = id.split("_");
				List<TcsCodeCovendChrgrVo> covendLbprCodeList = asService
						.getCovendLbprCodeList(setFillSearch(userDetails, new TcsSearchVo(), "auto"), codeValues[1]);
				List<TcsCodeVo> newCovendLbprCodeList = new ArrayList<>();
				for (TcsCodeVo item : covendLbprCodeList) {
					newCovendLbprCodeList.add(item);
				}
				return newCovendLbprCodeList;
			} else {
				TcsSearchCodeVo searchCodeVo = new TcsSearchCodeVo();
				setFillSearch(userDetails, searchCodeVo, "auto");
				switch (id) {
				case "CS013_JOBEND":
					searchCodeVo.setCommCd("CS013");
					searchCodeVo.setQuery("JOBEND");
					searchCodeVo.setSo("ESBS_CD3");
					break;
				case "CS013_G":
					searchCodeVo.setCommCd("CS013");
					searchCodeVo.setQuery("G");
					searchCodeVo.setSo("ESBS_CD2");
					break;
				case "CS013_LAST":
					searchCodeVo.setCommCd("CS013");
					searchCodeVo.setQuery("LAST");
					searchCodeVo.setSo("ESBS_CD3");
					break;
				default:
					searchCodeVo.setCommCd(id);
					break;
				}
				return asService.selectCodeList(searchCodeVo);
			}
			return new ArrayList<>();
		}
	}

	/**
	 * 하자) 하자접수처리 수정/등록
	 * 
	 * @param vo
	 * @return
	 */
	@PostMapping("/updateTcsDeftElps")
	public TcsDeftElpsVo updateTcsDeftElps(UserDetails userDetails, @RequestBody TcsSearchDeftElpsVo vo) {
		setFillSearch(userDetails, vo, "auto");
		return asService.updateTcsDeftElps(vo);
	}

	/**
	 * 하자) 임직원 - 임직원 하자접수처리 수정
	 * 
	 * @param vo
	 * @return
	 */
	@PostMapping("/updateTcsDeft")
	public TcsDeftVo updateTcsDeft(UserDetails userDetails, @RequestBody TcsSearchDeftVo vo) {
		setFillSearch(userDetails, vo, "po");
		return asService.updateTcsDeft(vo);
	}

	/**
	 * 하자) 임직원 - 하자작업지시 SMS/PUSH 전송
	 * 
	 * @param vo
	 * @return
	 */
	@PostMapping("/sendTcsDeftSms")
	public TcsDeftVo sendTcsDeftSms(UserDetails userDetails, @RequestBody TcsSearchDeftVo vo) {
		setFillSearch(userDetails, vo, "po");
		vo.setPgprNm(userDetails.getUserNm());
		return asService.sendTcsDeftSmsPush(vo);
	}

	/**
	 * 하자) 현장 담당 업제 정보
	 * 
	 * @param vo
	 * @return
	 */
	@GetMapping("/selectVenList")
	public List<SmComCovendVo> selectVenList(UserDetails userDetails, TcsSearchVo vo) {
		setFillSearch(userDetails, vo, "auto");
		return asService.selectVenList(vo);
	}

	/**
	 * 하자) 하자접수처리 첨부파일 저장
	 * 
	 * @param vo
	 * @return
	 */
	@PostMapping("/updateTcsDeftAttach")
	public TcsDeftVo updateTcsDeftAtach(UserDetails userDetails, @RequestBody TcsSearchDeftVo vo) {
		setFillSearch(userDetails, vo, "auto");
		return asService.updateTcsDeftAttach(vo);
	}

	/**
	 * 하자) 고객서명 보기
	 * 
	 * @param vo
	 * @return
	 */
	@GetMapping("/selectTcsDeftCustsignView/{deftNo}")
	public TcsDeftCustsignVo selectTcsDeftCustsignView(UserDetails userDetails, TcsSearchDeftCustsignVo vo,
			@PathVariable String deftNo) {
		setFillSearch(userDetails, vo, "auto");
		vo.setDeftNo(deftNo);
		return asService.selectTcsDeftCustsignView(vo);
	}

	/**
	 * 하자) 고객서명 업데이트
	 * 
	 * @param vo
	 * @return
	 */
	@PostMapping("/updateTcsDeftCustsign/{deftNo}")
	public TcsDeftCustsignVo updateTcsDeftCustsign(UserDetails userDetails, @RequestBody TcsSearchDeftCustsignVo vo,
			@PathVariable String deftNo) {
		setFillSearch(userDetails, vo, "auto");
		vo.setDeftNo(deftNo);
		return asService.updateTcsDeftCustsign(vo);
	}

	/**
	 * 현장 주소록 리스트
	 * 
	 * @param vo
	 * @return
	 */
	@GetMapping("/siteAddressList")
	public List<ZehrSiteAddressVo> selectSiteAddressList(UserDetails userDetails, TcsSearchVo vo) {
		setFillSearch(userDetails, vo, "auto");
		return asService.selectSiteAddressList(vo);
	}

	/**
	 * 회의실 정보
	 * 
	 * @param search
	 * @param userDetails
	 * @return
	 */
	@GetMapping("/room/romInfo")
	public List<ZehrRomInfoVo> selectRomInfoList(RoomSearchVo search, UserDetails userDetails) {
		setFillSearch(userDetails, search, "po");
		return roomService.selectRomInfoList(search);
	}

	/**
	 * 회의실 - 회의실 일자별 예약 내역
	 * 
	 * @param search
	 * @return
	 */
	@GetMapping("/room/listDay")
	public List<ZehrRomDisplVo> selectRomDayList(RoomSearchVo search, UserDetails userDetails) {
		setFillSearch(userDetails, search, "po");
		return roomService.selectRomDayList(search);
	}

	/**
	 * 회의실 - 회의실 예약 리스트
	 * 
	 * @param search
	 * @param userDetails
	 * @param searchVo
	 * @return
	 */
	@GetMapping("/room/listRem")
	public List<ZehrRomResrvtnVo> selectRomResrvList(RoomSearchVo search, UserDetails userDetails,
			TcsSearchVo searchVo) {
		setFillSearch(userDetails, searchVo, "po");
		return roomService.selectRomResrvList(search);
	}

	/**
	 * 회의실 - 회의실 예약 상세
	 * 
	 * @param search
	 * @param reservationId
	 * @return
	 */
	@GetMapping("/room/viewRem/{reservationId}")
	public ZehrRomResrvtnVo selectRomResrvView(RoomSearchVo search, @PathVariable String reservationId) {
		search.setReservationId(reservationId);
		return roomService.selectRomResrvView(search);
	}

	/**
	 * 회의실 - 회의실 위치 목록
	 * 
	 * @param search
	 * @return
	 */
	@GetMapping("/room/selectLoc")
	public List<ZehrRomLoctnVo> selectLocationList(RoomSearchVo search) {
		return roomService.selectLocationList(search);
	}

	/**
	 * 회의실 - 일반예약
	 * 
	 * @param userDetails
	 * @param vo
	 * @return
	 */
	@PostMapping("/room/revSave")
	public ZehrRomResrvtnVo insertRomResrvtnNormal(UserDetails userDetails, @RequestBody RoomSearchVo vo) {
		setFillSearch(userDetails, vo, "po");
		vo.setSubscCmpnCd(vo.getCmpnCd());
		vo.setSubscSabun(vo.getLginId());
		return roomService.insertRomResrvtn(vo, "normal");
	}

	/**
	 * 회의실 - 반복예약
	 * 
	 * @param userDetails
	 * @param vo
	 * @return
	 */
	@PostMapping("/room/repSave")
	public ZehrRomResrvtnVo insertRomResrvtnRepeat(UserDetails userDetails, @RequestBody RoomSearchVo vo) {
		setFillSearch(userDetails, vo, "po");
		vo.setSubscCmpnCd(vo.getCmpnCd());
		vo.setSubscSabun(vo.getLginId());
		return roomService.insertRomResrvtn(vo, "repeat");
	}

	/**
	 * 회의실 - 기간 예약
	 * 
	 * @param userDetails
	 * @param vo
	 * @return
	 */
	@PostMapping("/room/rangeSave")
	public ZehrRomResrvtnVo insertRomResrvtnRange(UserDetails userDetails, @RequestBody RoomSearchVo vo) {
		setFillSearch(userDetails, vo, "po");
		vo.setSubscCmpnCd(vo.getCmpnCd());
		vo.setSubscSabun(vo.getLginId());
		return roomService.insertRomResrvtn(vo, "range");
	}

	/**
	 * 회의실 - 예약 Update
	 * 
	 * @param userDetails
	 * @param vo
	 * @return
	 */
	@PostMapping("/room/revUpdate")
	@Secured(policy = SecurityPolicy.NONE)
	public ZehrRomResrvtnVo updateRomResrvtn(UserDetails userDetails, @RequestBody RoomSearchVo vo) {
		setFillSearch(userDetails, vo, "po");
		return roomService.updateRomResrvtn(vo, "NORMAL");
	}

	/**
	 * 회의실 - 승인 대기 목록
	 * 
	 * @param search
	 * @param userDetails
	 * @param searchVo
	 * @return
	 */
	@GetMapping("/room/selectZehrRomResrvtnStatusList")
	public List<ZehrRomResrvtnVo> selectZehrRomResrvtnStatusList(RoomSearchVo search, UserDetails userDetails,
			TcsSearchVo searchVo) {
		setFillSearch(userDetails, searchVo, "po");
		search.setShowType("APP");
		return roomService.selectRomResrvList(search);
	}

	/**
	 * 회의실 - 예약 승인
	 * 
	 * @param userDetails
	 * @param vo
	 * @return
	 */
	@PostMapping("/room/appSave")
	public ZehrRomResrvtnVo updateRomResrvtnApp(UserDetails userDetails, @RequestBody RoomSearchVo vo) {
		setFillSearch(userDetails, vo, "po");
		return roomService.updateRomResrvtn(vo, "APPROVAL");
	}

	/**
	 * 회의실 - 회의실 예약 반려
	 * 
	 * @param userDetails
	 * @param vo
	 * @return
	 */
	@PostMapping("/room/rejectSave")
	public ZehrRomResrvtnVo updateRomResrvtnReject(UserDetails userDetails, @RequestBody RoomSearchVo vo) {
		setFillSearch(userDetails, vo, "po");
		return roomService.updateRomResrvtn(vo, "REJECT");
	}

	/**
	 * 회의실 - 회의실 예약 종료
	 * 
	 * @param userDetails
	 * @param vo
	 * @return
	 */
	@PostMapping("/room/closeMeetSave")
	public ZehrRomResrvtnVo updateRomResrvtnClose(UserDetails userDetails, @RequestBody RoomSearchVo vo) {
		setFillSearch(userDetails, vo, "po");
		return roomService.updateRomResrvtn(vo, "CLOSE");
	}

	/**
	 * 회의실 - 회의실 예약 취소
	 * 
	 * @param userDetails
	 * @param vo
	 * @return
	 */
	@PostMapping("/room/cancelMeetSave")
	public ZehrRomResrvtnVo updateRomResrvtnCancel(UserDetails userDetails, @RequestBody RoomSearchVo vo) {
		setFillSearch(userDetails, vo, "po");
		return roomService.updateRomResrvtn(vo, "CANCEL");
	}

	/**
	 * 하자) 푸시 전송 테스트
	 * 실 서버에서 전송 사용되지 않도록 할 것 
	 * 
	 * @param vo
	 * @return
	 */
	@PostMapping("/sendpushtest")
	public MoPushhistVo getSendPush(@RequestBody MoPushhistVo vo) {
		return asService.sendTcsDeftPush(vo);
	}

	/**
	 * 하자) SMS/푸시 전송 테스트
	 * 실 서버에서 전송 사용되지 않도록 할 것 
	 * 
	 * @param vo
	 * @return
	 */
	@PostMapping("/sendsmspushtest")
	@Secured(policy = SecurityPolicy.NONE)
	public TcsDeftVo sendTcsDeftSmsPush(@RequestBody TcsSearchDeftVo vo) {
		return asService.sendTcsDeftSmsPush(vo);
	}
	
    /**
     * 데이타 베이스 스트레스 테스트
     * 
     * @return
     */
    @GetMapping("/insertStressTestFail")
    @Secured(policy = SecurityPolicy.NONE)
    public TcsSearchDeftCustsignVo insertStressTestFail() {
        return asService.insertStressTest(1500);
    }

    /**
     * 데이타 베이스 스트레스 테스트
     * 
     * @return
     */
    @GetMapping("/insertStressTestOk")
    @Secured(policy = SecurityPolicy.NONE)
    public TcsSearchDeftCustsignVo insertStressTestOk() {
        return asService.insertStressTest(3000);
    }
    
	
}
