package com.madeu.crm.kiosk.ctrl;

import java.util.HashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
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 org.springframework.web.servlet.ModelAndView;

import com.madeu.constants.Constants;
import com.madeu.crm.kiosk.dto.ConsentFormDTO;
import com.madeu.crm.kiosk.dto.UserDTO;
import com.madeu.crm.kiosk.service.KioskService;
import com.madeu.init.ManagerDraftAction;
import com.madeu.service.web.webloghistory.WebLogHistoryService;
import com.madeu.util.HttpUtil;
import com.madeu.util.RequestLogUtil;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
public class KioskController extends ManagerDraftAction {

    @Autowired
    private KioskService kioskService;

    @Autowired
    private WebLogHistoryService webLogHistoryService;

    // ==================== 뷰 반환 메서드 (ModelAndView) ====================

    /**
     * 키오스크 메인화면 화면으로 이동.
     */
    @RequestMapping("/kiosk")
    public ModelAndView selectMainIntro(HttpServletRequest request, HttpServletResponse response) {
        log.debug("KioskController selectMainIntro START");
        log.debug("KioskController selectMainIntro END");
        return new ModelAndView("/kiosk/consultation");
    }
    @PostMapping("/kiosk/getConsentForm.do")
    public ConsentFormDTO getConsentForm(@RequestBody ConsentFormDTO dto) {
    	log.debug("KioskController selectMainIntro START");
    	
    	dto = kioskService.getConsentForm(dto);
    	
        log.debug("KioskController selectMainIntro END");
        return dto;
    }

    /**
     * 키오스크 신규 환자 화면으로 이동.
     */
    @GetMapping("/kiosk/NewPatientIntro.do")
    public ModelAndView NewPatientIntro(HttpServletRequest request, HttpServletResponse response) {
        log.debug("KioskController NewPatientIntro START");
        log.debug("KioskController NewPatientIntro END");
        return new ModelAndView("/kiosk/new-patient");
    }

    /**
     * 키오스크 기존 환자 화면으로 이동.
     */
    @GetMapping("/kiosk/ExistPatientIntro.do")
    public ModelAndView ExistPatientIntro(HttpServletRequest request, HttpServletResponse response) {
        log.debug("KioskController ExistPatientIntro START");
        log.debug("KioskController ExistPatientIntro END");
        return new ModelAndView("/kiosk/existing-patient");
    }

    /**
     * 키오스크 동의서 화면으로 이동.
     */
    @GetMapping("/kiosk/agreement.do")
    public ModelAndView agreementPage(HttpServletRequest request, HttpServletResponse response) {
        log.debug("KioskController agreementPage START");
        log.debug("KioskController agreementPage END");
        return new ModelAndView("/kiosk/agreement");
    }

    // ==================== API 메서드 (JSON 반환) ====================

    /**
     * 진료 정보 리스트 조회 (option)
     */
    @PostMapping("/kiosk/getTreatmentOptionList.do")
    public HashMap<String, Object> getTreatmentOptionList(HttpServletRequest request, HttpServletResponse response) {
        log.debug("KioskController getTreatmentOptionList START");

        HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
        HashMap<String, Object> map = new HashMap<String, Object>();

        try {
            map = kioskService.getTreatmentOptionList(paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msgCode", Constants.FAIL);
            map.put("msgDesc", "서버 오류가 발생했습니다.");
        } finally {
            if (Constants.OK != map.get("msgCode")) {
                map.put("msgCode", Constants.FAIL);
                map.put("success", false);
                if (null == map.get("msgDesc") || ("").equals(map.get("msgDesc"))) {
                    map.put("msgDesc", "정상적으로 수행되지 않았습니다. 관리자에게 문의하시기 바랍니다.");
                }
            }
        }
        log.debug("KioskController getTreatmentOptionList END");
        return map;
    }

    /**
     * 병원 기타정보 카테고리 타입 조회
     */
    @PostMapping("/kiosk/getCategoryList.do")
    public HashMap<String, Object> getCategoryList(HttpServletRequest request, HttpServletResponse response) {
        log.debug("KioskController getCategoryList START");

        HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
        HashMap<String, Object> map = new HashMap<String, Object>();

        try {
            map = kioskService.getCategoryList(paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msgCode", Constants.FAIL);
            map.put("msgDesc", "서버 오류가 발생했습니다.");
        } finally {
            if (Constants.OK != map.get("msgCode")) {
                map.put("msgCode", Constants.FAIL);
                map.put("success", false);
                if (null == map.get("msgDesc") || ("").equals(map.get("msgDesc"))) {
                    map.put("msgDesc", "정상적으로 수행되지 않았습니다. 관리자에게 문의하시기 바랍니다.");
                }
            }
        }
        log.debug("KioskController getCategoryList END");
        return map;
    }

    /**
     * 병원 기타정보 카테고리 아이템 조회
     */
    @PostMapping("/kiosk/getCategoryItem.do")
    public HashMap<String, Object> getCategoryItem(HttpServletRequest request, HttpServletResponse response) {
        log.debug("KioskController getCategoryItem START");

        HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
        HashMap<String, Object> map = new HashMap<String, Object>();

        try {
            map = kioskService.getCategoryItem(paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msgCode", Constants.FAIL);
            map.put("msgDesc", "서버 오류가 발생했습니다.");
        } finally {
            if (Constants.OK != map.get("msgCode")) {
                map.put("msgCode", Constants.FAIL);
                map.put("success", false);
                if (null == map.get("msgDesc") || ("").equals(map.get("msgDesc"))) {
                    map.put("msgDesc", "정상적으로 수행되지 않았습니다. 관리자에게 문의하시기 바랍니다.");
                }
            }
        }
        log.debug("KioskController getCategoryItem END");
        return map;
    }

    /**
     * 고객 정보 리스트 조회 (option)
     */
    @PostMapping("/kiosk/getUserOptionList.do")
    public HashMap<String, Object> getUserOptionList(HttpServletRequest request, HttpServletResponse response) {
        log.debug("KioskController getUserOptionList START");

        HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
        HashMap<String, Object> map = new HashMap<String, Object>();

        try {
            map = kioskService.getUserOptionList(paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msgCode", Constants.FAIL);
            map.put("msgDesc", "서버 오류가 발생했습니다.");
        } finally {
            if (Constants.OK != map.get("msgCode")) {
                map.put("msgCode", Constants.FAIL);
                map.put("success", false);
                if (null == map.get("msgDesc") || ("").equals(map.get("msgDesc"))) {
                    map.put("msgDesc", "정상적으로 수행되지 않았습니다. 관리자에게 문의하시기 바랍니다.");
                }
            }
        }
        log.debug("KioskController getUserOptionList END");
        return map;
    }

    /**
     * 고객 등록
     */
    @PostMapping("/kiosk/putUser.do")
    public HashMap<String, Object> putUser(@RequestBody UserDTO dto, HttpServletRequest request) {
        log.debug("KioskController putUser START");
        
        HashMap<String, Object> resultMap = new HashMap<>();
        StringBuffer errorMsg = new StringBuffer();

        try {
            // DTO에 직접 필요한 공통 정보 세팅
            dto.setRegId("customer");
            dto.setModId("customer");
            dto.setMuUserId("U");
            
            // DTO를 직접 서비스로 전달 (Service 인터페이스도 UserDTO를 받도록 수정 필요)
            resultMap = kioskService.putUser(dto); 
            
        } catch (Exception e) {
            log.error("Error inserting user", e);
            resultMap.put("msgCode", Constants.FAIL);
            resultMap.put("msgDesc", "서버 오류가 발생했습니다.");
            errorMsg.append(e.getMessage());
        } finally {
            // 결과 처리 및 로그 기록 (기존과 동일)
            processFinalResult(resultMap, dto, errorMsg, request);
        }
        
        return resultMap;
    }

    /**
     * 고객 정보 조회
     */
    @PostMapping("/kiosk/getUser.do")
    public HashMap<String, Object> getUser(HttpServletRequest request, HttpServletResponse response) {
        log.debug("KioskController getUser START");

        HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
        HashMap<String, Object> map = new HashMap<String, Object>();

        try {
            map = kioskService.getUser(paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msgCode", Constants.FAIL);
            map.put("msgDesc", "서버 오류가 발생했습니다.");
        } finally {
            if (Constants.OK != map.get("msgCode")) {
                map.put("msgCode", Constants.FAIL);
                map.put("success", false);
                if (null == map.get("msgDesc") || ("").equals(map.get("msgDesc"))) {
                    map.put("msgDesc", "정상적으로 수행되지 않았습니다. 관리자에게 문의하시기 바랍니다.");
                }
            }
        }
        log.debug("KioskController getUser END");
        return map;
    }

    /**
     * 근무 시간 조회
     */
    @PostMapping("/kiosk/getWorkTime.do")
    public HashMap<String, Object> getWorkTime(HttpServletRequest request, HttpServletResponse response) {
        log.debug("KioskController getWorkTime START");

        HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
        HashMap<String, Object> map = new HashMap<String, Object>();

        try {
            map = kioskService.getWorkTime(paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msgCode", Constants.FAIL);
            map.put("msgDesc", "서버 오류가 발생했습니다.");
        } finally {
            if (Constants.OK != map.get("msgCode")) {
                map.put("msgCode", Constants.FAIL);
                map.put("success", false);
                if (null == map.get("msgDesc") || ("").equals(map.get("msgDesc"))) {
                    map.put("msgDesc", "정상적으로 수행되지 않았습니다. 관리자에게 문의하시기 바랍니다.");
                }
            }
        }
        log.debug("KioskController getWorkTime END");
        return map;
    }

    /**
     * 진료 시술 조회
     */
    @PostMapping("/kiosk/getTreatmentProcedureOptionList.do")
    public HashMap<String, Object> getTreatmentProcedureOptionList(HttpServletRequest request,
            HttpServletResponse response) {
        log.debug("KioskController getTreatmentProcedureOptionList START");

        HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
        HashMap<String, Object> map = new HashMap<String, Object>();

        try {
            map = kioskService.getTreatmentProcedureOptionList(paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msgCode", Constants.FAIL);
            map.put("msgDesc", "서버 오류가 발생했습니다.");
        } finally {
            if (Constants.OK != map.get("msgCode")) {
                map.put("msgCode", Constants.FAIL);
                map.put("success", false);
                if (null == map.get("msgDesc") || ("").equals(map.get("msgDesc"))) {
                    map.put("msgDesc", "정상적으로 수행되지 않았습니다. 관리자에게 문의하시기 바랍니다.");
                }
            }
        }
        log.debug("KioskController getTreatmentProcedureOptionList END");
        return map;
    }

    /**
     * 해당 시술 닥터 및 해당과 상담자 조회
     */
    @PostMapping("/kiosk/getMemberDoctorConsultingOptionList.do")
    public HashMap<String, Object> getMemberDoctorConsultingOptionList(HttpServletRequest request,
            HttpServletResponse response) {
        log.debug("KioskController getMemberDoctorConsultingOptionList START");

        HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
        HashMap<String, Object> map = new HashMap<String, Object>();

        try {
            map = kioskService.getMemberDoctorConsultingOptionList(paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msgCode", Constants.FAIL);
            map.put("msgDesc", "서버 오류가 발생했습니다.");
        } finally {
            if (Constants.OK != map.get("msgCode")) {
                map.put("msgCode", Constants.FAIL);
                map.put("success", false);
                if (null == map.get("msgDesc") || ("").equals(map.get("msgDesc"))) {
                    map.put("msgDesc", "정상적으로 수행되지 않았습니다. 관리자에게 문의하시기 바랍니다.");
                }
            }
        }
        log.debug("KioskController getMemberDoctorConsultingOptionList END");
        return map;
    }

    /**
     * 직원 정보 리스트 조회
     */
    @PostMapping("/kiosk/getMemberList.do")
    public HashMap<String, Object> getMemberList(HttpServletRequest request, HttpServletResponse response) {
        log.debug("KioskController getMemberList START");

        HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
        HashMap<String, Object> map = new HashMap<String, Object>();

        try {
            map = kioskService.getMemberList(paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msgCode", Constants.FAIL);
            map.put("msgDesc", "서버 오류가 발생했습니다.");
        } finally {
            if (Constants.OK != map.get("msgCode")) {
                map.put("msgCode", Constants.FAIL);
                map.put("success", false);
                if (null == map.get("msgDesc") || ("").equals(map.get("msgDesc"))) {
                    map.put("msgDesc", "정상적으로 수행되지 않았습니다. 관리자에게 문의하시기 바랍니다.");
                }
            }
        }
        log.debug("KioskController getMemberList END");
        return map;
    }

    /**
     * 고객 - 1년간 진료내역 조회 (수납완료건)
     */
    @PostMapping("/kiosk/getReserveUserOptionList.do")
    public HashMap<String, Object> getReserveUserOptionList(HttpServletRequest request, HttpServletResponse response) {
        log.debug("KioskController getReserveUserOptionList START");

        HashMap<String, Object> paramMap = HttpUtil.getParameterMap(request);
        HashMap<String, Object> map = new HashMap<String, Object>();

        try {
            map = kioskService.getReserveUserOptionList(paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msgCode", Constants.FAIL);
            map.put("msgDesc", "서버 오류가 발생했습니다.");
        } finally {
            if (Constants.OK != map.get("msgCode")) {
                map.put("msgCode", Constants.FAIL);
                map.put("success", false);
                if (null == map.get("msgDesc") || ("").equals(map.get("msgDesc"))) {
                    map.put("msgDesc", "정상적으로 수행되지 않았습니다. 관리자에게 문의하시기 바랍니다.");
                }
            }
        }
        log.debug("KioskController getReserveUserOptionList END");
        return map;
    }
    /**
     * 결과 처리 및 공통 응답 포맷 정리, 로그 기록 준비 메서드
     */
    private void processFinalResult(HashMap<String, Object> resultMap, UserDTO dto, StringBuffer errorMsg, HttpServletRequest request) {
        
        // 1. 결과 코드에 따른 성공 여부 및 기본 메시지 설정
        if (!Constants.OK.equals(resultMap.get("msgCode"))) {
            resultMap.put("msgCode", Constants.FAIL);
            resultMap.put("success", false);
            if (null == resultMap.get("msgDesc") || "".equals(resultMap.get("msgDesc"))) {
                resultMap.put("msgDesc", "정상적으로 수행되지 않았습니다. 관리자에게 문의하시기 바랍니다.");
            }
        } else {
            resultMap.put("success", true);
            if (null == resultMap.get("msgDesc") || "".equals(resultMap.get("msgDesc"))) {
                resultMap.put("msgDesc", "성공적으로 등록되었습니다.");
            }
        }

        // 2. 웹 로그 기록 (비동기 또는 서비스 호출)
        try {
            HashMap<String, Object> visitLogParamMap = RequestLogUtil.getVisitLogParameterMap(request);
            HashMap<String, Object> insertMap = new HashMap<String, Object>();

            insertMap.put("url", "/kiosk/putUser.do");
            insertMap.put("func", "putUser");
            insertMap.put("funcName", "고객 등록");
            insertMap.put("service", "kioskService");
            insertMap.put("serviceName", "고객 등록");
            
            // DTO의 toString()을 사용하여 요청 파라미터 기록
            insertMap.put("requestValue", dto != null ? dto.toString() : "NULL");
            insertMap.put("responseValue", String.valueOf(resultMap));
            insertMap.put("tId", resultMap.get("tId"));
            
            if (errorMsg.length() == 0) {
                insertMap.put("resultCode", "SUCCESS");
            } else {
                insertMap.put("resultCode", "ERROR");
            }
            insertMap.put("resultMsg", errorMsg.toString());
            insertMap.put("muMemberId", "customer");

            // 로그 서비스 호출
            webLogHistoryService.insertLogHistory(insertMap, visitLogParamMap);
            
        } catch (Exception e) {
            log.error("Log History Insertion Error: ", e);
            // 로그 기록 실패가 비즈니스 로직에 영향을 주지 않도록 내부에서 예외 처리
        }
    }
}