package com.madeu.crm.callLog.ctrl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.madeu.crm.callLog.dto.CallLogDTO;
import com.madeu.crm.callLog.service.CallLogService;

import lombok.extern.slf4j.Slf4j;

/**
 * GoodARS Webhook 수신 Controller
 *
 * ARS 서버에서 통화 단계별로 이 엔드포인트를 호출하여 통화 로그를 저장합니다.
 * 인증 없이(public) 접근 가능해야 합니다.
 *
 * 통화 흐름:
 * step01 (수신) → step02 (ARS 메뉴 선택) → step03 (통화 연결)
 * → step04 (통화 종료) → step05 (기타 종료)
 * callback (콜백 요청)
 */
@Slf4j
@RestController
@RequestMapping("/api/cti/webhook")
public class CtiWebhookController {

    @Autowired
    private CallLogService callLogService;

    /**
     * Step 01 - 전화 수신 (통화 시작)
     */
    @PostMapping("/step01")
    public String step01(
            @RequestParam(value = "FULLDNIS", required = false, defaultValue = "") String fulldnis,
            @RequestParam(value = "CID", required = false, defaultValue = "") String cid,
            @RequestParam(value = "MENU_NO", required = false, defaultValue = "") String menuNo,
            @RequestParam(value = "LOGINCID", required = false, defaultValue = "") String logincid,
            @RequestParam(value = "RECORD_NO", required = false, defaultValue = "") String recordNo,
            @RequestParam(value = "BOUND", required = false, defaultValue = "") String bound,
            @RequestParam(value = "STATE_TYPE", required = false, defaultValue = "") String stateType) {

        log.debug("CtiWebhook step01 - RECORD_NO:{}, CID:{}, FULLDNIS:{}", recordNo, cid, fulldnis);

        try {
            CallLogDTO logDTO = buildLogDTO(fulldnis, cid, menuNo, logincid, recordNo, bound, stateType, "1");
            callLogService.putCtiLog(logDTO);
            return "success";
        } catch (Exception e) {
            log.error("CtiWebhook step01 error", e);
            return "fail";
        }
    }

    /**
     * Step 02 - ARS 메뉴 선택 (Ring)
     */
    @PostMapping("/step02")
    public String step02(
            @RequestParam(value = "FULLDNIS", required = false, defaultValue = "") String fulldnis,
            @RequestParam(value = "CID", required = false, defaultValue = "") String cid,
            @RequestParam(value = "MENU_NO", required = false, defaultValue = "") String menuNo,
            @RequestParam(value = "LOGINCID", required = false, defaultValue = "") String logincid,
            @RequestParam(value = "RECORD_NO", required = false, defaultValue = "") String recordNo,
            @RequestParam(value = "BOUND", required = false, defaultValue = "") String bound,
            @RequestParam(value = "STATE_TYPE", required = false, defaultValue = "") String stateType) {

        log.debug("CtiWebhook step02 - RECORD_NO:{}, MENU_NO:{}", recordNo, menuNo);

        try {
            CallLogDTO logDTO = buildLogDTO(fulldnis, cid, menuNo, logincid, recordNo, bound, stateType, "2");
            callLogService.putCtiLog(logDTO);
            return "success";
        } catch (Exception e) {
            log.error("CtiWebhook step02 error", e);
            return "fail";
        }
    }

    /**
     * Step 03 - 통화 연결 (Link)
     */
    @PostMapping("/step03")
    public String step03(
            @RequestParam(value = "FULLDNIS", required = false, defaultValue = "") String fulldnis,
            @RequestParam(value = "CID", required = false, defaultValue = "") String cid,
            @RequestParam(value = "MENU_NO", required = false, defaultValue = "") String menuNo,
            @RequestParam(value = "LOGINCID", required = false, defaultValue = "") String logincid,
            @RequestParam(value = "RECORD_NO", required = false, defaultValue = "") String recordNo,
            @RequestParam(value = "BOUND", required = false, defaultValue = "") String bound,
            @RequestParam(value = "STATE_TYPE", required = false, defaultValue = "") String stateType) {

        log.debug("CtiWebhook step03 - RECORD_NO:{}, LOGINCID:{}", recordNo, logincid);

        try {
            CallLogDTO logDTO = buildLogDTO(fulldnis, cid, menuNo, logincid, recordNo, bound, stateType, "3");
            callLogService.putCtiLog(logDTO);
            return "success";
        } catch (Exception e) {
            log.error("CtiWebhook step03 error", e);
            return "fail";
        }
    }

    /**
     * Step 04 - 통화 종료 (Link End)
     */
    @PostMapping("/step04")
    public String step04(
            @RequestParam(value = "FULLDNIS", required = false, defaultValue = "") String fulldnis,
            @RequestParam(value = "CID", required = false, defaultValue = "") String cid,
            @RequestParam(value = "MENU_NO", required = false, defaultValue = "") String menuNo,
            @RequestParam(value = "LOGINCID", required = false, defaultValue = "") String logincid,
            @RequestParam(value = "RECORD_NO", required = false, defaultValue = "") String recordNo,
            @RequestParam(value = "BOUND", required = false, defaultValue = "") String bound,
            @RequestParam(value = "STATE_TYPE", required = false, defaultValue = "") String stateType) {

        log.debug("CtiWebhook step04 - RECORD_NO:{}", recordNo);

        try {
            CallLogDTO logDTO = buildLogDTO(fulldnis, cid, menuNo, logincid, recordNo, bound, stateType, "4");
            callLogService.putCtiLog(logDTO);
            return "success";
        } catch (Exception e) {
            log.error("CtiWebhook step04 error", e);
            return "fail";
        }
    }

    /**
     * Step 05 - 기타 종료 (Bend)
     */
    @PostMapping("/step05")
    public String step05(
            @RequestParam(value = "FULLDNIS", required = false, defaultValue = "") String fulldnis,
            @RequestParam(value = "CID", required = false, defaultValue = "") String cid,
            @RequestParam(value = "MENU_NO", required = false, defaultValue = "") String menuNo,
            @RequestParam(value = "LOGINCID", required = false, defaultValue = "") String logincid,
            @RequestParam(value = "RECORD_NO", required = false, defaultValue = "") String recordNo,
            @RequestParam(value = "BOUND", required = false, defaultValue = "") String bound,
            @RequestParam(value = "STATE_TYPE", required = false, defaultValue = "") String stateType) {

        log.debug("CtiWebhook step05 - RECORD_NO:{}", recordNo);

        try {
            CallLogDTO logDTO = buildLogDTO(fulldnis, cid, menuNo, logincid, recordNo, bound, stateType, "5");
            callLogService.putCtiLog(logDTO);
            return "success";
        } catch (Exception e) {
            log.error("CtiWebhook step05 error", e);
            return "fail";
        }
    }

    /**
     * Callback - 콜백 요청
     */
    @PostMapping("/callback")
    public String callback(
            @RequestParam(value = "FULLDNIS", required = false, defaultValue = "") String fulldnis,
            @RequestParam(value = "CID", required = false, defaultValue = "") String cid,
            @RequestParam(value = "MENU_NO", required = false, defaultValue = "") String menuNo,
            @RequestParam(value = "LOGINCID", required = false, defaultValue = "") String logincid,
            @RequestParam(value = "RECORD_NO", required = false, defaultValue = "") String recordNo,
            @RequestParam(value = "BOUND", required = false, defaultValue = "") String bound,
            @RequestParam(value = "STATE_TYPE", required = false, defaultValue = "") String stateType) {

        log.debug("CtiWebhook callback - RECORD_NO:{}, CID:{}", recordNo, cid);

        try {
            CallLogDTO logDTO = buildLogDTO(fulldnis, cid, menuNo, logincid, recordNo, bound, "callback", "98");
            callLogService.putCtiLog(logDTO);
            return "success";
        } catch (Exception e) {
            log.error("CtiWebhook callback error", e);
            return "fail";
        }
    }

    /**
     * 공통 DTO 빌드 메서드
     */
    private CallLogDTO buildLogDTO(String fulldnis, String cid, String menuNo, String logincid,
            String recordNo, String bound, String stateType, String ctiStep) {
        CallLogDTO dto = new CallLogDTO();
        dto.setFulldnis(fulldnis);
        dto.setCid(cid);
        dto.setMenuNo(menuNo);
        dto.setLogincid(logincid);
        dto.setRecordNo(recordNo);
        dto.setBound(bound);
        dto.setStateType(stateType);
        dto.setCtiStep(ctiStep);
        return dto;
    }
}
