package com.eactive.eai.rms.onl.apim.portalInquiry;

import com.eactive.apim.portal.file.entity.FileInfo;
import com.eactive.apim.portal.file.service.FileService;
import com.eactive.apim.portal.portaluser.entity.PortalUser;
import com.eactive.apim.portal.portaluser.entity.PortalUserEnums;
import com.eactive.apim.portal.portaluser.repository.PortalUserRepository;
import com.eactive.apim.portal.qna.entity.Inquiry;
import com.eactive.apim.portal.qna.entity.InquiryComment;
import com.eactive.apim.portal.qna.entity.VisibilityScope;
import com.eactive.apim.portal.user.entity.UserInfo;
import com.eactive.eai.rms.common.base.BaseService;
import com.eactive.eai.rms.common.exception.IntegrationException;
import com.eactive.eai.rms.data.entity.man.user.UserInfoService;
import com.eactive.eai.rms.data.entity.onl.apim.portalinquiry.PortalInquiryCommentService;
import com.eactive.eai.rms.data.entity.onl.apim.portalinquiry.PortalInquirySearch;
import com.eactive.eai.rms.data.entity.onl.apim.portalinquiry.PortalInquiryService;
import com.eactive.eai.rms.onl.apim.masking.MaskingUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@Service
@Transactional(transactionManager = "transactionManagerForEMS")
@Slf4j
public class PortalInquiryManService extends BaseService {
	private final PortalInquiryService portalInquiryService;
	private final PortalInquiryCommentService portalInquiryCommentService;
	private final PortalInquiryUIMapper portalInquiryUIMapper;
	private final PortalInquiryCommentUIMapper portalInquiryCommentUIMapper;
	private final UserInfoService userInfoService;
	private final PortalUserRepository portalUserRepository;
	private final FileService fileService;

	public static final String PENDING = "PENDING";
	public static final String REVIEWING = "REVIEWING";
	public static final String RESPONDED = "RESPONDED";
	public static final String CLOSED = "CLOSED";
	public static final String TARGET_COMMENT = "COMMENT";


	public PortalInquiryManService(PortalInquiryService portalInquiryService,
								   PortalInquiryCommentService portalInquiryCommentService,
								   PortalInquiryUIMapper portalInquiryUIMapper,
								   PortalInquiryCommentUIMapper portalInquiryCommentUIMapper,
								   UserInfoService userInfoService,
								   PortalUserRepository portalUserRepository,
								   FileService fileService){
		this.portalInquiryService = portalInquiryService;
		this.portalInquiryCommentService = portalInquiryCommentService;
		this.portalInquiryUIMapper = portalInquiryUIMapper;
		this.portalInquiryCommentUIMapper = portalInquiryCommentUIMapper;
		this.userInfoService = userInfoService;
		this.portalUserRepository = portalUserRepository;
		this.fileService = fileService;
	}

	public Page<PortalInquiryUI> selectList(Pageable pageable, PortalInquirySearch portalInquirySearch) {
		Page<Inquiry> inquiries = portalInquiryService.findAll(pageable, portalInquirySearch);
		return inquiries.map(inquiry -> {
			PortalInquiryUI ui = portalInquiryUIMapper.toVo(inquiry);
			setOrgName(ui, inquiry);
			// 문의자 정보 마스킹처리 _ 이름, 이메일, 로그인id, 핸드폰번호
			if (ui.getInquirer() != null) {
				maskPortalInquiryUI(ui);
			}
			ui.setCommentCount((int) portalInquiryCommentService.countActiveByInquiryId(inquiry.getId()));
			return setInquiryAttachmentStatus(ui);
		});
	}

	private void setOrgName(PortalInquiryUI ui, Inquiry inquiry) {
		if (inquiry.getInquirer() == null) {
			ui.setOrgName("");
			return;
		}
		PortalUser inquirer = inquiry.getInquirer();
		boolean isCorpUser = inquirer.getRoleCode() == PortalUserEnums.RoleCode.ROLE_CORP_USER
				|| inquirer.getRoleCode() == PortalUserEnums.RoleCode.ROLE_CORP_MANAGER;

		if (isCorpUser && inquirer.getPortalOrg() != null) {
			ui.setOrgName(inquirer.getPortalOrg().getOrgName());
		} else {
			ui.setOrgName("");
		}
	}

	private PortalInquiryUI setInquiryAttachmentStatus(PortalInquiryUI ui) {
		String fileId = ui.getAttachFile();
		FileInfo fileInfo = null;

		if(StringUtils.isNotBlank(fileId)){
			try {
				fileInfo = fileService.findById(fileId);
			} catch (Exception e) {
				// 파일 정보가 DB에 없는 경우 무시하고 계속 진행
				log.warn("File not found for fileId: {}", fileId);
			}
		}

		boolean hasAttachment = false;

		if(fileInfo != null && fileInfo.getFileDetails() != null) {
			hasAttachment = !fileInfo.getFileDetails().isEmpty();
		}

		ui.setHasAttachment(hasAttachment);
		return ui;
	}

	public PortalInquiryUI selectDetail(String id) {
		Inquiry inquiry = portalInquiryService.getById(id);

		// 답변 대기중 상태에서 상세 조회 시 검토중 상태로 변경
		if (PENDING.equals(inquiry.getInquiryStatus())) {
			inquiry.setInquiryStatus(REVIEWING);
			portalInquiryService.save(inquiry);
		}

		PortalInquiryUI portalInquiryUI =  portalInquiryUIMapper.toVo(inquiry);

		// 문의자 정보 마스킹처리 _ 이름, 이메일, 로그인id, 핸드폰번호
		//if (portalInquiryUI.getInquirer() != null) {
		//	maskPortalInquiryUI(portalInquiryUI);
		//}

		if (StringUtils.isNotBlank(inquiry.getAttachFile())) {
			try {
				FileInfo fileInfo = fileService.findById(inquiry.getAttachFile());
				if (fileInfo != null && fileInfo.getFileDetails() != null && !fileInfo.getFileDetails().isEmpty()) {
					portalInquiryUI.setFileInfo(fileInfo);
				}
			} catch (Exception e) {
				// 파일 정보가 DB에 없는 경우 무시하고 계속 진행
				log.warn("File not found for fileId: {}", inquiry.getAttachFile());
			}
		}

		return portalInquiryUI;
	}

	private void maskPortalInquiryUI(PortalInquiryUI ui) {
		if (StringUtils.isNotBlank(ui.getInquirer().getUserName())) {
			ui.getInquirer().setUserName(MaskingUtils.maskName(ui.getInquirer().getUserName()));
		}
		if (StringUtils.isNotBlank(ui.getInquirer().getMobileNumber())) {
			ui.getInquirer().setMobileNumber(MaskingUtils.maskPhoneNumber(ui.getInquirer().getMobileNumber()));
		}
		if (StringUtils.isNotBlank(ui.getInquirer().getLoginId())) {
			ui.getInquirer().setLoginId(MaskingUtils.maskEmailId(ui.getInquirer().getLoginId()));
		}
		if (StringUtils.isNotBlank(ui.getInquirer().getEmailAddr())) {
			ui.getInquirer().setEmailAddr(MaskingUtils.maskEmailId(ui.getInquirer().getEmailAddr()));
		}
	}

	public void insertAndUpdate(PortalInquiryUI portalInquiryUI, String userId) {
		UserInfo userinfo = userInfoService.getById(userId);

		Inquiry inquiry = portalInquiryService.getById(portalInquiryUI.getId());
		validateNotClosed(inquiry);
		// 답변 대기중 상태일 경우만 답변완료로 상태 변경
		if(inquiry.getInquiryStatus().equals(PENDING) || inquiry.getInquiryStatus().equals(REVIEWING)) {
			inquiry.setInquiryStatus(RESPONDED);
		}

		inquiry.setResponseDetail(StringEscapeUtils.unescapeHtml(portalInquiryUI.getResponseDetail()));
		inquiry.setResponder(userinfo);
		inquiry.setResponseDate(LocalDateTime.now());

		portalInquiryService.save(inquiry);
	}

	public void deleteBulk(String ids) {
		if (StringUtils.isBlank(ids)) {
			return;
		}

		List<String> idList = Arrays.asList(ids.split(","));
		portalInquiryService.deleteByIds(idList);
	}
	
	public List<PortalInquiryCommentUI> selectCommentList(String inquiryId) {
		List<InquiryComment> comments = portalInquiryCommentService.findByInquiryId(inquiryId);
		List<PortalInquiryCommentUI> result = portalInquiryCommentUIMapper.toVoList(comments);
		result.forEach(ui -> ui.setWriterName(resolveWriterName(ui.getCreatedBy())));
		return result;
	}

	private String resolveWriterName(String userId) {
		if (StringUtils.isBlank(userId)) return "";
		// 직원(내부 사용자) 여부 먼저 확인 → 이름 그대로 반환
		Optional<UserInfo> staff = userInfoService.findById(userId);
		if (staff.isPresent()) {
			return staff.get().getUsername();
		}
		// 포털 회원이면 이름 마스킹 처리 (김수민 → 김수*)
		Optional<PortalUser> portalUser = portalUserRepository.findById(userId);
		if (portalUser.isPresent()) {
			return MaskingUtils.maskName(portalUser.get().getUserName());
		}
		return userId;
	}

	public void insertComment(PortalInquiryCommentUI commentUI, String userId) {
		Inquiry inquiry = portalInquiryService.getById(commentUI.getInquiryId());
		validateNotClosed(inquiry);

		InquiryComment comment = new InquiryComment();
		comment.setInquiry(inquiry);
		comment.setCommentDetail(commentUI.getCommentDetail());
		comment.setDelYn("N");
		comment.setAdminYn("Y");

		portalInquiryCommentService.save(comment);
	}

	public void deleteComment(String commentId) {
		InquiryComment comment = portalInquiryCommentService.getById(commentId);
		validateNotClosed(comment.getInquiry());
		comment.setDelYn("Y");
		portalInquiryCommentService.save(comment);
	}

	private void validateNotClosed(Inquiry inquiry) {
		if (CLOSED.equals(inquiry.getInquiryStatus())) {
			throw new IntegrationException("답변종료되어 수정할 수 없습니다.");
		}
	}

	/** 조회수 증가 (JSP sessionStorage dedup 통과 시 호출). 관리자는 공개범위 무관 전체 접근. */
	public void incrementViewCount(String id) {
		Inquiry inquiry = portalInquiryService.getById(id);
		inquiry.increaseViewCount();
		portalInquiryService.save(inquiry);
	}

	/**
	 * 게시물/댓글 공개범위 변경. 사유(reason) 필수.
	 * 변경 이력은 eapim-admin 공통 감사 로그(AuditLogInterceptor)가 자동 기록한다
	 * (auditpoints.dat 의 PortalInquiryManController_..._VISIBILITY, serviceType=APIGW, auditReason 파라미터).
	 *
	 * @param targetType INQUIRY 또는 COMMENT
	 * @param id         대상 게시물/댓글 ID
	 * @param newVisibility 변경할 공개범위(ALL/ORG/PRIVATE)
	 * @param reason     변경 사유(필수)
	 */
	public void updateVisibility(String targetType, String id, String newVisibility, String reason) {
		if (StringUtils.isBlank(reason)) {
			throw new IntegrationException("공개범위 변경 사유를 입력해주세요.");
		}
		VisibilityScope newScope = VisibilityScope.fromString(newVisibility, null);
		if (newScope == null) {
			throw new IntegrationException("유효하지 않은 공개범위입니다.");
		}

		if (TARGET_COMMENT.equalsIgnoreCase(targetType)) {
			InquiryComment comment = portalInquiryCommentService.getById(id);
			comment.setVisibility(newScope);
			portalInquiryCommentService.save(comment);
		} else {
			Inquiry inquiry = portalInquiryService.getById(id);
			inquiry.setVisibility(newScope);
			portalInquiryService.save(inquiry);
		}
	}

}
