package com.bcxin.tenant.domain.entities;

import com.bcxin.Infrastructures.SystemConstant;
import com.bcxin.Infrastructures.entities.EntityAbstract;
import com.bcxin.Infrastructures.enums.*;
import com.bcxin.Infrastructures.utils.StringUtils;
import com.bcxin.tenant.domain.services.commands.organizations.CreateMyOrganizationCommand;
import com.bcxin.tenant.domain.services.commands.organizations.RegisterCompanyCommand;
import com.bcxin.tenant.domain.services.commands.organizations.UpdateCompanyCommand;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;

import javax.persistence.*;
import java.util.Date;
import java.util.List;

@Getter
@Setter(AccessLevel.PROTECTED)
@Table(name = "tenant_companies")
@Entity
public class CompanyEntity extends EntityAbstract {

    @Id
    private String id;

    @Column(name = "unify_social_credit_code", nullable = false)
    private String unifySocialCreditCode;

    @Column(name = "unify_social_credit_code_file", nullable = false)
    private String unifySocialCreditCodeFile;

    /**
     * 总公司名称
     */
    @Column(name = "parent_name")
    private String parentName;

    /**
     * 总公司证件类型
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "parent_certificate_type")
    private CompanyCertificateType parentCertificateType;

    /**
     * 总公司证件号码
     */
    @Column(name = "parent_certificate_number")
    private String parentCertificateNumber;

    /**
     * 总公司法人姓名
     */
    @Column(name = "parent_legal_person_name")
    private String parentLegalPersonName;

    /**
     * 总公司联系电话
     */
    @Column(name = "parent_legal_person_telephone")
    private String parentLegalPersonTelephone;

    /**
     * 经济类型，1-国有经济，2-集体经济，3-私营经济，4-个体经济，5-联营经济，6-股份制，7-外商投资，8-港澳台投资与其他经济，9-其他经济
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "economic_type")
    private EconomicType economicType;

    /**
     * 公司类型，1-国有资本，2-民营，3-外资（包括港澳台投资），4-其它
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "nature")
    private CompanyNature nature;

    /**
     * 服务范围，使用2的n次方位移方式，可以保存一对多的格式
     */
    @Column(name = "service_scope")
    private Integer serviceScope;

    /**
     * 服务范围描述
     */
    @Column(name = "service_scope_description")
    private String serviceScopeDescription;

    /**
     * 注册资本
     */
    @Column(name = "registered_capital")
    private String registeredCapital;

    /**
     * 固定资本
     */
    @Column(name = "fixed_capital")
    private String fixedCapital;

    /**
     * 年利税
     */
    @Column(name = "annual_profit_tax")
    private String annualProfitTax;

    /**
     * 年营业额
     */
    @Column(name = "annual_sales_volume")
    private String annualSalesVolume;

    /**
     * 证件类型
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "certificate_type")
    private CompanyCertificateType certificateType;

    /**
     * 保安服务许可/保安培训备案证号
     */
    @Column(name = "service_permit_number")
    private String servicePermitNumber;

    /**
     * 批准文号
     */
    @Column(name = "security_approval_number")
    private String securityApprovalNumber;

    /**
     * 发证机关
     */
    @Column(name = "name_of_issuing_authority")
    private String nameOfIssuingAuthority;

    /**
     * 保安服务许可证首次发证日期或者培训单位的发证日期
     */
    @Column(name = "first_issue_service_permit")
    private Date firstIssueServicePermit;

    /**
     * 保安服务许可证扫描件或者保安培训许可（备案）证扫描件
     */
    @Column(name = "service_permit_attachment")
    private String servicePermitAttachment;

    /**
     * 培训单位的培训内容
     */
    @Column(name = "train_content")
    private String trainContent;

    /**
     * 人力防范评定等级，0-无，1-一级，2-二级，3-三级，4-准三级
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "security_preparedness_rating")
    private SecurityPreparednessRating securityPreparednessRating;

    /**
     * 武装守护押运评定等级，0-无，1-一级，2-二级
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "security_armed_rating")
    private SecurityArmedRating securityArmedRating;

    /**
     * 安全技术防范评定等级，0-无，1-一级，2-二级，3-三级
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "security_safety_defense_rating")
    private SecuritySafetyDefenseRating securitySafetyDefenseRating;

    /**
     * 是否有风险评估资质，0-否，1-是
     */
    @Column(name = "is_risk_assessment")
    private Boolean isRiskAssessment;

    /**
     * 自行招用保安员单位.拟自招保安员数
     */
    @Column(name = "number_of_security_guards")
    private Integer numberOfSecurityGuards;

    /**
     * 自行招用保安员单位.是否治安保卫重点单位，0-否，1-是
     */
    @Column(name = "is_public_security_security")
    private Boolean isPublicSecuritySecurity;

    /**
     * 自行招用保安员单位.是否物业企业，0-否，1-是
     */
    @Column(name = "is_property_enterprise")
    private Boolean isPropertyEnterprise;

    /**
     * 自行招用保安员单位.自招保安单位性质
     */
    @Column(name = "nature_of_self_recruited_units")
    private String natureOfSelfRecruitedUnits;

    /**
     * 法人姓名
     */
    @Column(name = "legal_person_name")
    private String legalPersonName;

    /**
     * 法人手机号码
     */
    @Column(name = "legal_person_telephone")
    private String legalPersonTelephone;

    /**
     * 法人证件类型
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "legal_person_credential_type")
    private CredentialType legalPersonCredentialType;

    /**
     * 法人证件号码
     */
    @Column(name = "legal_person_credential_number")
    private String legalPersonCredentialNumber;

    /**
     * 法人国籍
     */
    @Column(name = "legal_person_nationality")
    private String legalPersonNationality;

    /**
     * 保安负责人姓名
     */
    @Column(name = "security_person_name")
    private String securityPersonName;

    /**
     * 保安负责人手机号码
     */
    @Column(name = "security_person_telephone")
    private String securityPersonTelephone;

    /**
     * 保安负责人证件类型
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "security_person_credential_type")
    private CredentialType securityPersonCredentialType;

    /**
     * 保安负责人证件号码
     */
    @Column(name = "security_person_credential_number")
    private String securityPersonCredentialNumber;

    /**
     * 创建睡时间
     */
    @Column(name = "create_time")
    private Date createTime;

    /**
     * 更新时间
     */
    @Column(name = "last_updated_time")
    private Date lastUpdatedTime;


    public CompanyEntity() {
        super();
    }

    public CompanyEntity(OrganizationEntity organization) {
        this.setId(organization.getId());
    }

    public CompanyEntity(OrganizationEntity organization, String unifySocialCreditCode, String unifySocialCreditCodeFile, String parentName,
                         CompanyCertificateType parentCertificateType, String parentCertificateNumber, String parentLegalPersonName,
                         String parentLegalPersonTelephone, EconomicType economicType, CompanyNature nature,
                         Integer serviceScope, String serviceScopeDescription, String registeredCapital,
                         String fixedCapital, String annualProfitTax, String annualSalesVolume, CompanyCertificateType certificateType,String servicePermitNumber,
                         String securityApprovalNumber, String nameOfIssuingAuthority, Date firstIssueServicePermit,
                         String servicePermitAttachment, String trainContent, SecurityPreparednessRating securityPreparednessRating,
                         SecurityArmedRating securityArmedRating, SecuritySafetyDefenseRating securitySafetyDefenseRating,
                         Boolean isRiskAssessment, Integer numberOfSecurityGuards, Boolean isPublicSecuritySecurity,
                         Boolean isPropertyEnterprise, String natureOfSelfRecruitedUnits,
                         String legalPersonName, String legalPersonTelephone, CredentialType legalPersonCredentialType,
                         String legalPersonCredentialNumber, String legalPersonNationality, String securityPersonName, String securityPersonTelephone,
                         CredentialType securityPersonCredentialType, String securityPersonCredentialNumber) {
        this.setId(organization.getId());
        this.unifySocialCreditCode = unifySocialCreditCode;
        this.unifySocialCreditCodeFile = unifySocialCreditCodeFile;
        this.parentName = parentName;
        this.parentCertificateType = parentCertificateType;
        this.parentCertificateNumber = parentCertificateNumber;
        this.parentLegalPersonName = parentLegalPersonName;
        this.parentLegalPersonTelephone = parentLegalPersonTelephone;
        this.economicType = economicType == null ? EconomicType.None : economicType;
        this.nature = nature;
        this.serviceScope = serviceScope;
        this.serviceScopeDescription = serviceScopeDescription;
        this.registeredCapital = registeredCapital == null ? "" : registeredCapital;
        this.fixedCapital = fixedCapital;
        this.annualProfitTax = annualProfitTax;
        this.annualSalesVolume = annualSalesVolume;
        this.certificateType = certificateType;
        this.servicePermitNumber = servicePermitNumber;
        this.securityApprovalNumber = securityApprovalNumber;
        this.nameOfIssuingAuthority = nameOfIssuingAuthority;
        this.firstIssueServicePermit = firstIssueServicePermit;
        this.servicePermitAttachment = servicePermitAttachment;
        this.trainContent = trainContent;
        this.securityPreparednessRating = securityPreparednessRating;
        this.securityArmedRating = securityArmedRating;
        this.securitySafetyDefenseRating = securitySafetyDefenseRating;
        this.isRiskAssessment = isRiskAssessment;
        this.numberOfSecurityGuards = numberOfSecurityGuards;
        this.isPublicSecuritySecurity = isPublicSecuritySecurity;
        this.isPropertyEnterprise = isPropertyEnterprise;
        this.natureOfSelfRecruitedUnits = natureOfSelfRecruitedUnits;
        this.legalPersonName = legalPersonName == null ? "" : legalPersonName;
        this.legalPersonTelephone = legalPersonTelephone == null ? "" : legalPersonTelephone;
        this.legalPersonCredentialType = legalPersonCredentialType == null ? CredentialType.IdCard : legalPersonCredentialType;
        this.legalPersonCredentialNumber = legalPersonCredentialNumber == null ? "" : legalPersonCredentialNumber;
        this.legalPersonNationality = legalPersonNationality == null ? "" : legalPersonNationality;
        this.securityPersonName = securityPersonName;
        this.securityPersonTelephone = securityPersonTelephone;
        this.securityPersonCredentialType = securityPersonCredentialType;
        this.securityPersonCredentialNumber = securityPersonCredentialNumber;
        this.createTime = new Date();
    }

    public void change(String unifySocialCreditCode, String unifySocialCreditCodeFile, String parentName,
                       CompanyCertificateType parentCertificateType, String parentCertificateNumber, String parentLegalPersonName,
                       String parentLegalPersonTelephone, EconomicType economicType, CompanyNature nature,
                       List<String> serviceScopeList, String registeredCapital,
                       String fixedCapital, String annualProfitTax, String annualSalesVolume, CompanyCertificateType certificateType, String servicePermitNumber,
                       String securityApprovalNumber, String nameOfIssuingAuthority, Date firstIssueServicePermit,
                       String servicePermitAttachment, String trainContent, SecurityPreparednessRating securityPreparednessRating,
                       SecurityArmedRating securityArmedRating, SecuritySafetyDefenseRating securitySafetyDefenseRating,
                       Boolean isRiskAssessment, Integer numberOfSecurityGuards, Boolean isPublicSecuritySecurity,
                       Boolean isPropertyEnterprise, String natureOfSelfRecruitedUnits,
                       String legalPersonName, String legalPersonTelephone, CredentialType legalPersonCredentialType,
                       String legalPersonCredentialNumber, String legalPersonNationality, String securityPersonName, String securityPersonTelephone,
                       CredentialType securityPersonCredentialType, String securityPersonCredentialNumber) {
        //处理服务范围
        Integer serviceScope = null;
        String serviceScopeDescription = null;
        StringBuffer serviceScopeDescriptionSb = new StringBuffer();

        if (CollectionUtils.isNotEmpty(serviceScopeList)) {
            int serviceScopeInt = 0;
            for (String scope : serviceScopeList) {
                int s = Integer.parseInt(scope);
                serviceScopeDescriptionSb.append(scope).append(";");
                //服务范围可以多选，采用2的n次方累加存储
                serviceScopeInt += Math.pow(2, s-1);
            }
            serviceScope = serviceScopeInt;
            serviceScopeDescription = serviceScopeDescriptionSb.substring(0, serviceScopeDescriptionSb.length()-1);
        }

        if (economicType != null) {
            this.setEconomicType(economicType);
        }
        if (nature != null) {
            this.setNature(nature);
        }

        if (parentName != null) {
            this.setParentName(parentName);
        }
        if (parentCertificateType != null) {
            this.setParentCertificateType(parentCertificateType);
        }
        if (parentCertificateNumber != null) {
            this.setParentCertificateNumber(parentCertificateNumber);
        }
        if (parentLegalPersonName != null) {
            this.setParentLegalPersonName(parentLegalPersonName);
        }
        if (parentLegalPersonTelephone != null) {
            this.setParentLegalPersonTelephone(parentLegalPersonTelephone);
        }
        if (registeredCapital != null) {
            this.setRegisteredCapital(registeredCapital);
        }
        if (fixedCapital != null) {
            this.setFixedCapital(fixedCapital);
        }
        if (annualSalesVolume != null) {
            this.setAnnualSalesVolume(annualSalesVolume);
        }
        if (annualProfitTax != null) {
            this.setAnnualProfitTax(annualProfitTax);
        }
        if (certificateType != null) {
            this.setCertificateType(certificateType);
        }
        if (unifySocialCreditCode != null) {
            this.setUnifySocialCreditCode(unifySocialCreditCode);
        }
        if (unifySocialCreditCodeFile != null) {
            this.setUnifySocialCreditCodeFile(unifySocialCreditCodeFile);
        }
        if (servicePermitNumber != null) {
            this.setServicePermitNumber(servicePermitNumber);
        }
        if (nameOfIssuingAuthority != null) {
            this.setNameOfIssuingAuthority(nameOfIssuingAuthority);
        }
        if (firstIssueServicePermit != null) {
            this.setFirstIssueServicePermit(firstIssueServicePermit);
        }
        if (servicePermitAttachment != null) {
            this.setServicePermitAttachment(servicePermitAttachment);
        }
        if (securityApprovalNumber != null) {
            this.setSecurityApprovalNumber(securityApprovalNumber);
        }
        if (CollectionUtils.isNotEmpty(serviceScopeList)) {
            this.setServiceScope(serviceScope);
            this.setServiceScopeDescription(serviceScopeDescription);
        }
        if (securityPreparednessRating != null) {
            this.setSecurityPreparednessRating(securityPreparednessRating);
        }
        if (securityArmedRating != null) {
            this.setSecurityArmedRating(securityArmedRating);
        }
        if (securitySafetyDefenseRating != null) {
            this.setSecuritySafetyDefenseRating(securitySafetyDefenseRating);
        }
        if (isRiskAssessment != null) {
            this.setIsRiskAssessment(isRiskAssessment);
        }
        if (trainContent != null) {
            this.setTrainContent(trainContent);
        }
        if (numberOfSecurityGuards != null) {
            this.setNumberOfSecurityGuards(numberOfSecurityGuards);
        }
        if (isPublicSecuritySecurity != null) {
            this.setIsPublicSecuritySecurity(isPublicSecuritySecurity);
        }
        if (isPropertyEnterprise != null) {
            this.setIsPropertyEnterprise(isPropertyEnterprise);
        }
        if (natureOfSelfRecruitedUnits != null) {
            this.setNatureOfSelfRecruitedUnits(natureOfSelfRecruitedUnits);
        }
        if (legalPersonName != null) {
            this.setLegalPersonName(legalPersonName);
        }
        if (legalPersonTelephone != null) {
            this.setLegalPersonTelephone(legalPersonTelephone);
        }
        if (legalPersonCredentialType != null) {
            this.setLegalPersonCredentialType(legalPersonCredentialType);
        }
        if (legalPersonCredentialNumber != null) {
            this.setLegalPersonCredentialNumber(legalPersonCredentialNumber);
        }
        if (legalPersonNationality != null) {
            this.setLegalPersonNationality(legalPersonNationality);
        }
        if (securityPersonName != null) {
            this.setSecurityPersonName(securityPersonName);
        }
        if (securityPersonTelephone != null) {
            this.setSecurityPersonTelephone(securityPersonTelephone);
        }
        if (securityPersonCredentialType != null) {
            this.setSecurityPersonCredentialType(securityPersonCredentialType);
        }
        if (securityPersonCredentialNumber != null) {
            this.setSecurityPersonCredentialNumber(securityPersonCredentialNumber);
        }
    }

    public static CompanyEntity create(OrganizationEntity organization) {
        CompanyEntity company = new CompanyEntity(organization);

        return company;
    }


    public static CompanyEntity create(OrganizationEntity organization, RegisterCompanyCommand command) {
        //处理服务范围
        Integer serviceScope = null;
        String serviceScopeDescription = null;
        StringBuffer serviceScopeDescriptionSb = new StringBuffer();

        if (CollectionUtils.isNotEmpty(command.getServiceScopeList())) {
            int serviceScopeInt = 0;
            for (String scope : command.getServiceScopeList()) {
                int s = Integer.parseInt(scope);
                serviceScopeDescriptionSb.append(scope).append(";");
                //服务范围可以多选，采用2的n次方累加存储
                serviceScopeInt += Math.pow(2, s-1);
            }
            serviceScope = serviceScopeInt;
            serviceScopeDescription = serviceScopeDescriptionSb.substring(0, serviceScopeDescriptionSb.length()-1);
        }

        CompanyEntity company = new CompanyEntity(organization, command.getUnifySocialCreditCode(), command.getUnifySocialCreditCodeFile(),
                command.getParentName(), command.getParentCertificateType(), command.getParentCertificateNumber(), command.getParentLegalPersonName(),
                command.getParentLegalPersonTelephone(), command.getEconomicType(), command.getNature(),
                serviceScope, serviceScopeDescription, command.getRegisteredCapital(),
                command.getFixedCapital(), command.getAnnualProfitTax(), command.getAnnualSalesVolume(), command.getCertificateType(),command.getServicePermitNumber(),
                command.getSecurityApprovalNumber(), command.getNameOfIssuingAuthority(), command.getFirstIssueServicePermit(),
                command.getServicePermitAttachment(), command.getTrainContent(), command.getSecurityPreparednessRating(),
                command.getSecurityArmedRating(), command.getSecuritySafetyDefenseRating(),
                command.getIsRiskAssessment(), command.getNumberOfSecurityGuards(), command.getIsPublicSecuritySecurity(),
                command.getIsPropertyEnterprise(), command.getNatureOfSelfRecruitedUnits(),
                command.getLegalPersonName(), command.getLegalPersonTelephone(), command.getLegalPersonCredentialType(),
                command.getLegalPersonCredentialNumber(), command.getLegalPersonNationality(), command.getSecurityPersonName(),
                command.getSecurityPersonTelephone(), command.getSecurityPersonCredentialType(), command.getSecurityPersonCredentialNumber());

        return company;
    }

    public static CompanyEntity create(OrganizationEntity organization, CreateMyOrganizationCommand command) {
        //处理服务范围
        Integer serviceScope = 0;
        String unifySocialCreditCode =command.getUnifySocialCreditCode();
        if(StringUtils.isEmpty(unifySocialCreditCode))
        {
            /**
             * 默认情况下; 该值来自于读取营业执照；先忽略前端无法正常识别的情况
             */
            unifySocialCreditCode = SystemConstant.EmptyValue;
        }
        CompanyEntity company = new CompanyEntity(organization,
                unifySocialCreditCode, command.getUnifySocialCreditCodeFile(),
                null,CompanyCertificateType.UniformCreditCode,SystemConstant.EmptyValue,SystemConstant.EmptyValue,
                SystemConstant.EmptyValue, EconomicType.Collective,
                CompanyNature.None,serviceScope,SystemConstant.EmptyValue,null,null,null,null,
                CompanyCertificateType.UniformCreditCode,
                null,null,null,null,//servicePermitAttachment
                null,null,SecurityPreparednessRating.None,SecurityArmedRating.None,
                SecuritySafetyDefenseRating.None,false,0,false,
                false,SystemConstant.EmptyValue,SystemConstant.EmptyValue,SystemConstant.EmptyValue,CredentialType.IdCard,
                SystemConstant.EmptyValue,SystemConstant.EmptyValue,SystemConstant.EmptyValue,SystemConstant.EmptyValue,
                CredentialType.IdCard,SystemConstant.EmptyValue);

        return company;
    }
}
