package com.style24.admin.biz.service;

import java.util.Collection;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.style24.admin.biz.dao.TsaSettleDao;
import com.style24.admin.support.env.TsaConstants;
import com.style24.admin.support.security.session.TsaSession;
import com.style24.persistence.domain.AflinkFee;
import com.style24.persistence.domain.DelvFeeSettle;
import com.style24.persistence.domain.GiftcardSettle;
import com.style24.persistence.domain.GoodsSettle;
import com.style24.persistence.domain.SettleConfirm;

import lombok.extern.slf4j.Slf4j;

import com.gagaframework.excel.GagaExcelUtil;
import com.gagaframework.excel.env.GagaExcelConstants;
import com.gagaframework.web.parameter.GagaMap;

/**
 * 정산 Service
 *
 * @author gagamel
 * @since 2021. 1. 20
 */
@Service
@Slf4j
public class TsaSettleService {

	@Autowired
	private TsaSettleDao settleDao;

	@Autowired
	private ObjectMapper mapper;

	/**
	 * 상품정산 목록
	 * @param goodsSettle - 상품정산 정보
	 * @return
	 * @author gagamel
	 * @since 2021. 7. 5
	 */
	public Collection<GoodsSettle> getGoodsSettleList(GoodsSettle goodsSettle) {
		return settleDao.getGoodsSettleList(goodsSettle);
	}

	/**
	 * 정산확정 처리 - 업체별정산데이터 생성
	 * @param settleYm - 정산기준월
	 * @author gagamel
	 * @since 2021. 7. 30
	 */
	@Transactional("shopTxnManager")
	public void saveSettleConfirm(String settleYm) {
		// 정산데이터 삭제
		settleDao.deleteSettleConfirm(settleYm);

		// 정산데이터 생성
		SettleConfirm settleConfirm = new SettleConfirm();
		settleConfirm.setSettleYm(settleYm);
		settleConfirm.setRegNo(TsaSession.getInfo().getUserNo());
		settleDao.createSettleConfirm(settleConfirm);
	}

	/**
	 * 배송비정산 목록
	 * @param delvFeeSettle - 배송비정산 정보
	 * @return
	 * @author gagamel
	 * @since 2021. 7. 6
	 */
	public Collection<DelvFeeSettle> getDeliveryFeeSettleList(DelvFeeSettle delvFeeSettle) {
		return settleDao.getDeliveryFeeSettleList(delvFeeSettle);
	}

	/**
	 * 정산확정 목록
	 * @param settleConfirm - 정산확정 정보
	 * @return
	 * @author gagamel
	 * @since 2021. 7. 26
	 */
	public Collection<SettleConfirm> getSettleConfirmList(SettleConfirm settleConfirm) {
		return settleDao.getSettleConfirmList(settleConfirm);
	}

	/**
	 * 정산확정 기타차감 저장 처리
	 * @param dataMap - 기타차감 정보
	 * @author gagamel
	 * @since 2021. 8. 16
	 */
	@Transactional("shopTxnManager")
	public void saveEtcDeductAmt(GagaMap dataMap) {
		SettleConfirm settleConfirm = mapper.convertValue(dataMap, SettleConfirm.class);
		log.info("settleConfirm: {}", settleConfirm);

		if (StringUtils.isBlank(settleConfirm.getOccurYm())) {
			throw new IllegalStateException("발생연월은 필수입니다.");
		}

		if (StringUtils.isBlank(settleConfirm.getSupplyCompCd())) {
			throw new IllegalStateException("업체번호는 필수입니다.");
		}

		if (settleConfirm.getRewardAmt() <= 0) {
			throw new IllegalStateException("보상액은 0 보다 커야 합니다.");
		}

		settleConfirm.setRegNo(TsaSession.getInfo().getUserNo());
		settleConfirm.setUpdNo(TsaSession.getInfo().getUserNo());
		settleDao.createEtcDeductAmt(settleConfirm);
	}

	/**
	 * 정산확정 미수금 목록 저장 처리
	 * @param settleConfirmList - 정산확정 목록
	 * @author gagamel
	 * @since 2021. 8. 16
	 */
	@Transactional("shopTxnManager")
	public void saveReceivableAmtList(Collection<SettleConfirm> settleConfirmList) {
		for (SettleConfirm settleConfirm : settleConfirmList) {
			settleConfirm.setRegNo(TsaSession.getInfo().getUserNo());
			settleConfirm.setUpdNo(TsaSession.getInfo().getUserNo());
			settleDao.createReceivableAmt(settleConfirm);
		}
	}

	/**
	 * 세금계산서용 정산엑셀파일 생성
	 * @param settleConfirm - 정산확정 정보
	 * @param excelFilenameWithPath - 경로를 포함한 엑셀파일명
	 * @author gagamel
	 * @since 2021. 8. 16
	 */
	public void createTaxBillSettleExcel(SettleConfirm settleConfirm, String excelFilenameWithPath) {
		// 헤더 title 설정
		String[] listTitles = {"작성연월", "품목", "공급가액", "세액", "현금거래액", "사업자번호", "상호", "대표자명", "업태", "업종", "기본주소", "상세주소", "정산담당자", "전화번호", "계산서이메일", "계산서발행금액"};

		// DB 처리 시 사용되는 셀명 설정
		String[] cellNames = {"usacYm", "billType", "supplyAmt", "taxAmt", "tradeAmt", "bizNo", "supplyCompNm", "ownerNm", "bizType", "bizKind", "bizBaseAddr", "bizDtlAddr", "settleChargeNm", "settleChargeTelno", "billEmail", "billAmt"};

		String[] cellTypes = {
			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
			GagaExcelConstants.CellType.CHAR_RIGHT.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name(),
			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
			GagaExcelConstants.CellType.CHAR_LEFT.name(), GagaExcelConstants.CellType.CHAR_LEFT.name(),
			GagaExcelConstants.CellType.CHAR_LEFT.name(), GagaExcelConstants.CellType.CHAR_LEFT.name(),
			GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
			GagaExcelConstants.CellType.CHAR_RIGHT.name()};

		// 세금계산서용 정산 목록
		Collection<SettleConfirm> dataList = settleDao.getTaxBillSettleList(settleConfirm);

		try {
			GagaExcelUtil.createExcel(excelFilenameWithPath, dataList, settleConfirm.getSettleYm() + " 세금계산서", listTitles, cellNames, cellTypes, TsaConstants.EXCEL_FOOTER_TITLE);
		} catch (Exception e) {
			throw new IllegalStateException(e);
		}
	}

	/**
	 * 상품권현황 목록
	 * @param giftcardSettle - 상품권정산 정보
	 * @return
	 * @author gagamel
	 * @since 2021. 8. 16
	 */
	public Collection<GiftcardSettle> getGiftcardStatusList(GiftcardSettle giftcardSettle) {
		return settleDao.getGiftcardStatusList(giftcardSettle);
	}

	/**
	 * 상품권정산 목록
	 * @param giftcardSettle - 상품권정산 정보
	 * @return
	 * @author gagamel
	 * @since 2021. 8. 16
	 */
	public Collection<GiftcardSettle> getGiftcardSettleList(GiftcardSettle giftcardSettle) {
		return settleDao.getGiftcardSettleList(giftcardSettle);
	}

	/**
	 * 제휴채널정산 목록
	 * @param afLinkFee - 제휴채널수수료 정보
	 * @return
	 * @author gagamel
	 * @since 2021. 1. 20
	 */
	public Collection<AflinkFee> getAfLinkFeeList(AflinkFee afLinkFee) {
		return settleDao.getAfLinkFeeList(afLinkFee);
	}

}
