package com.bcxin.risk.policy.domain;

import com.bcxin.risk.activity.Activity;
import com.bcxin.risk.base.domain.BaseBean;
import com.bcxin.risk.base.domain.util.CollectionUtil;
import com.bcxin.risk.base.domain.util.DomainDateUtil;
import com.bcxin.risk.policy.enums.*;
import com.bcxin.risk.report.enums.ExpressMode;
import com.bcxin.risk.user.domain.User;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

import javax.persistence.*;
import java.math.BigDecimal;
import java.util.*;

/**
 * 保单
 * @author luopeng
 *
 */
@Entity
@Table(name = "RISK_InsurancePolicy")
@Inheritance(strategy = InheritanceType.JOINED)
@Data
@DynamicInsert(true)
@DynamicUpdate(true)
public class InsurancePolicy extends BaseBean {
	
	private static final long serialVersionUID = 1L;
	
	@ManyToOne(targetEntity = Activity.class, fetch = FetchType.LAZY)
	@JoinColumn(name = "activity_id")
	private Activity activity; //活动报告
	
	private String externalReference;//保单号（重要）

	@Enumerated(EnumType.STRING)
	private PolicyType policyType;//保单类型（投保单，未支付的保单；保单，已支付的保单）
	
	private String policySerialNumber;//投保单号

	@Temporal(TemporalType.DATE)
	private Date inceptionDate;//生效日期

	@Temporal(TemporalType.DATE)
	private Date plannedEndDate;//失效日期
	
	@Temporal(TemporalType.DATE)
	private Date htPlannedEndDate;//华泰保险失效日期（默认在失效日期上多加一天）

	@Temporal(TemporalType.TIMESTAMP)
	private Date signedDate;//投保日期

	private BigDecimal premium = BigDecimal.ZERO;//保费（单份保费，和unitCount挂钩，目前系统均为一份,故此值与grossPremium一般都是相同）

	private BigDecimal discountRate = BigDecimal.ZERO;//折扣

	@Enumerated(EnumType.STRING)
	private PolicyStatus policyStatus;//保单状态

	@Enumerated(EnumType.STRING)
	private BenefitPeriodType benefitPeriodType;//保险期间类型（年，月，日）

	private Integer benefitPeriod;//保险期间

	@Enumerated(EnumType.STRING)
	private PaymentMode paymentMode = PaymentMode.SINGLE;//支付方式，默认为趸交
	
	@Enumerated(EnumType.STRING)
	private SettlementStatus settlementStatus = SettlementStatus.NO_SETTLEMENT;//结算状态，目前默认为未结算

	@Enumerated(EnumType.STRING)
	private BeneficiaryMode beneficiaryMode;//受益人类型。默认为法定
	
	@OneToOne(targetEntity = MailPolicy.class, cascade = CascadeType.ALL)
	@JoinColumn(name = "mailPolicy_id")
	private MailPolicy mailPolicy = new MailPolicy();//邮寄保单相关信息
	
//	@OneToOne(targetEntity = Transaction.class, cascade = CascadeType.ALL)
//	@JoinColumn(name = "transaction_id")
//	private Transaction transaction = new Transaction();//保单交易
	
	@ManyToOne(targetEntity = InsuranceProduct.class, fetch = FetchType.LAZY)
	@JoinColumn(name = "spec_id")
	private InsuranceProduct insuranceProduct; //保单对应产品
	
	@ManyToOne(targetEntity = PlanSpec.class, fetch = FetchType.LAZY)
	@JoinColumn(name = "planSpec_id")
	private PlanSpec planSpec; //保单对应方案
	
	@ManyToOne(targetEntity = RateSpec.class, fetch = FetchType.LAZY)
	@JoinColumn(name = "rateSpec_id")
	private RateSpec rateSpec; //保单对应保费配置
	
	@ManyToOne(targetEntity = User.class, fetch = FetchType.LAZY)
	@JoinColumn(name = "user_id")
	private User user;
	
	@Enumerated(EnumType.STRING)
	private ExpressMode expressMode;// 是否需要发票，增值税发票(保障服务)(还没有加上去)
	
	private String policyURL; //电子保单地址
	
	@Transient
	private Map<String, RoleInPolicy> roleMap = new HashMap<String, RoleInPolicy>();

	@Transient
	private List<RoleInPolicy> roles = new ArrayList<RoleInPolicy>();

	public void addRole(RoleInPolicy r) {
		if ( CollectionUtil.isEmpty(roles) ) {
			roles.add(r);
		} else {
			List<RoleInPolicy> tempList = new ArrayList<RoleInPolicy>();
			tempList.addAll(roles);
			for (RoleInPolicy role : tempList) {
				String kind = role.getRoleKind().getKind();
				if ( !kind.equals(r.getRoleKind().getKind()) ) {
					roles.add(r);
				}
			}
		}
	}
	
	@JsonIgnore
	public Map<String, RoleInPolicy> getRoleMap() {
		for (RoleInPolicy role : roles) {
			String kind = role.getRoleKind().getKind();
			if ( !roleMap.containsKey(kind) ) {
				roleMap.put(kind, role);	
			}
		}
		return roleMap;
	}
	
	public RoleInPolicy getRoleOfKind(RoleKind kind) {
		for (RoleInPolicy role : roles) {
			if ( kind.equals(role.getRoleKind()) ){
				return role;
			}
		}
		return null;
	}

	public Date getHtPlannedEndDate() {
		htPlannedEndDate = DomainDateUtil.addDay(this.plannedEndDate, 1);
		return htPlannedEndDate;
	}

	public void setHtPlannedEndDate(Date htPlannedEndDate) {
		htPlannedEndDate = DomainDateUtil.addDay(this.plannedEndDate, 1);
		this.htPlannedEndDate = htPlannedEndDate;
	}
	
}
