package com.bcxin.tenant.domain.entities;

import cn.hutool.core.date.DateUtil;
import com.bcxin.Infrastructures.SystemConstant;
import com.bcxin.Infrastructures.TenantContext;
import com.bcxin.Infrastructures.components.EventDispatcher;
import com.bcxin.Infrastructures.components.JsonProvider;
import com.bcxin.Infrastructures.entities.EntityAbstract;
import com.bcxin.Infrastructures.entities.IAggregate;
import com.bcxin.Infrastructures.entities.OperatorValueType;
import com.bcxin.Infrastructures.enums.*;
import com.bcxin.Infrastructures.exceptions.BadTenantException;
import com.bcxin.Infrastructures.snapshots.OrgGisLocationSnapshot;
import com.bcxin.Infrastructures.utils.AuthUtil;
import com.bcxin.Infrastructures.utils.UUIDUtil;
import com.bcxin.tenant.domain.DomainConstraint;
import com.bcxin.tenant.domain.entities.valueTypes.ApprovedInformationValueType;
import com.bcxin.tenant.domain.entities.valueTypes.LocationValueType;
import com.bcxin.tenant.domain.events.OrganizationApprovedChangedEvent;
import com.bcxin.tenant.domain.events.OrganizationCreatedEvent;
import com.bcxin.tenant.domain.services.commands.organizations.CreateMyOrganizationCommand;
import com.bcxin.tenant.domain.services.commands.organizations.RegisterCompanyCommand;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;

import javax.persistence.*;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.*;

@Getter
@Setter(AccessLevel.PROTECTED)
@Table(name = "tenant_organizations",
        uniqueConstraints = @UniqueConstraint(name = DomainConstraint.UNIQUE_ORGANIZATION_NAME,columnNames = "name"))
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class OrganizationEntity extends EntityAbstract implements IAggregate {
    @Id
    @Column(length = 50)
    private String id;

    @Column(nullable = false,length = 30)
    private String code;

    /**
     * 组织名称
     */
    @Column(name = "name",nullable = false)
    private String name;

    /**
     * 系统名称
     */
    @Column(name = "sys_name",length = 100)
    private String sysName;

    /**
     * 描述
     */
    @Column(length = 500)
    private String description;

    /**
     * 经度
     */
    @Column
    private Double longitude;

    /**
     * 纬度
     */
    @Column
    private Double latitude;

    /**
     * 经纬度信息
     */
    @Column(nullable = true, name = "lon_lat_json", length = 200)
    private String lonLatJson;

    /**
     * 注册地
     */
    @Embedded
    @AttributeOverrides({
            @AttributeOverride(name="province.code",
                    column=@Column(name="place_Of_register_province_code")),
            @AttributeOverride(name="province.name",
                    column=@Column(name="place_Of_register_province_name")),
            @AttributeOverride(name="city.code",
                    column=@Column(name="place_Of_register_city_code")),
            @AttributeOverride(name="city.name",
                    column=@Column(name="place_Of_register_city_name")),
            @AttributeOverride(name="district.code",
                    column=@Column(name="place_Of_register_district_code")),
            @AttributeOverride(name="district.name",
                    column=@Column(name="place_Of_register_district_name")),
            @AttributeOverride(name="address",
                    column=@Column(name="place_Of_register_address")),
    })
    private LocationValueType placeOfRegister;

    /**
     * 组织图标
     */
    @Column(name = "logo_path", length = 500)
    private String logoPath;

    /**
     * 经营地
     */
    @Embedded
    @AttributeOverrides({
            @AttributeOverride(name="province.code",
                    column=@Column(name="place_Of_business_province_code")),
            @AttributeOverride(name="province.name",
                    column=@Column(name="place_Of_business_province_name")),
            @AttributeOverride(name="city.code",
                    column=@Column(name="place_Of_business_city_code")),
            @AttributeOverride(name="city.name",
                    column=@Column(name="place_Of_business_city_name")),
            @AttributeOverride(name="district.code",
                    column=@Column(name="place_Of_business_district_code")),
            @AttributeOverride(name="district.name",
                    column=@Column(name="place_Of_business_district_name")),
            @AttributeOverride(name="address",
                    column=@Column(name="place_Of_business_address")),
    })
    private LocationValueType placeOfBusiness;

    /**
     * 行业类型
     */
    @Column(name = "industry_code")
    private String industryCode;

    /**
     * 机构类型
     */
    @Column(name = "institutional_code")
    private String institutionalCode;

    /**
     * 审批状态
     */
    @Embedded
    @Column(name = "approved_information")
    @AttributeOverrides({
            @AttributeOverride(name="status",
                    column=@Column(name="approved_information_status")),
            @AttributeOverride(name="lastUpdatedTime",
                    column=@Column(name="approved_information_last_updated_time")),
            @AttributeOverride(name="note",
                    column=@Column(name="approved_information_note")),
    })
    private ApprovedInformationValueType approvedInformationValueType;

    @Column(name = "created_time", nullable = false)
    private Timestamp createdTime;

    @Column(name = "last_updated_time", nullable = true)
    private Timestamp lastUpdatedTime;

    /**
     * 员工信息
     */
    @OneToMany(mappedBy = "organization", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private Collection<EmployeeEntity> employees;

    /**
     * 部门列表
     */
    @OneToMany(mappedBy = "organization",fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private Collection<DepartmentEntity> departments;

    @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    @JoinColumn(name = "id", referencedColumnName = "id",nullable = false)
    private CompanyEntity company;

    @ManyToOne(cascade = CascadeType.DETACH,fetch = FetchType.LAZY)
    @JoinColumn(name = "tenant_user_id",referencedColumnName = "id", nullable = false,
            foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
    private TenantUserEntity tenantUser;

    /**
     * 公司状态，1-正常，2-注销，3-撤销，4-吊销
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "status")
    private OrganizationsStatus status;


    /**
     * 传真
     */
    @Column(name = "fax")
    private String fax;


    /**
     * 联系电话
     */
    @Column(name = "telephone")
    private String telephone;

    /**
     * 总分子公司
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "type")
    private ParentSubsidiary type;

    /**
     * 保安服务公司类型
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "industry_detail_type")
    private IndustryDetailType industryDetailType;

    /**
     * 监管地区
     */
    @Column(name = "supervise_region_code")
    private String superviseRegionCode;

    @ManyToOne(targetEntity = RegionEntity.class, cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
    @JoinColumn(name = "supervise_region_code",referencedColumnName = "id", insertable = false, updatable = false)
    private RegionEntity superviseRegion;

    /**
     * 监管机构
     */
    @Column(name = "supervise_depart_id")
    private String superviseDepartId;

    /**
     * 监管机构名称(冗余)
     */
    @Column(name = "supervise_depart_name")
    private String superviseDepartName;

//    /**
//     * 主管单位所在地区
//     */
//    @Column(name = "competent_unit_region_code")
//    private String competentUnitRegionCode;
//
//    /**
//     * 主管单位编码
//     */
//    @Column(name = "competent_unit_code")
//    private String competentUnitCode;

    /**
     * 分享单位id
     */
    @Column(name = "share_organization_id")
    private String shareOrganizationId;

    /**
     * 分享单位名称(冗余)
     */
    @Column(name = "share_organization_name")
    private String shareOrganizationName;

    /**
     * 分享职员id
     */
    @Column(name = "share_employee_id")
    private String shareEmployeeId;

    /**
     * 分享职员姓名(冗余)
     */
    @Column(name = "share_employee_name")
    private String shareEmployeeName;

    @Column(name = "level")
    private int organizationLevel;

    @Column(name = "level_changed_time")
    private Timestamp levelChangedTime;



    public void change(LocationValueType placeOfRegister, LocationValueType placeOfBusiness) {
        this.setPlaceOfRegister(placeOfRegister);
        this.setPlaceOfBusiness(placeOfBusiness);

        this.setLastUpdatedTime(Timestamp.from(Instant.now()));
    }

    public void change(String sysName,
                       String description,
                       String logoPath,
                       Double longitude,
                       Double latitude,
                       String institutionalCode, IndustryDetailType industryDetailType,
                       String name, ParentSubsidiary type, String telephone, EconomicType economicType,
                       CompanyNature nature, LocationValueType placeOfRegister, LocationValueType placeOfBusiness,
                       String parentName, CompanyCertificateType parentCertificateType, String parentCertificateNumber,
                       String parentLegalPersonName, String parentLegalPersonTelephone,
                       String legalPersonName, String legalPersonTelephone, CredentialType legalPersonCredentialType,
                       String legalPersonCredentialNumber, String legalPersonNationality, String securityPersonName, String securityPersonTelephone,
                       CredentialType securityPersonCredentialType, String securityPersonCredentialNumber,
                       String registeredCapital, String fixedCapital,
                       String annualSalesVolume, String annualProfitTax, CompanyCertificateType certificateType,
                       String unifySocialCreditCode, String unifySocialCreditCodeFile, String servicePermitNumber,
                       String nameOfIssuingAuthority, Date firstIssueServicePermit, String servicePermitAttachment,
                       String securityApprovalNumber, List<String> serviceScopeList, SecurityPreparednessRating securityPreparednessRating,
                       SecurityArmedRating securityArmedRating, SecuritySafetyDefenseRating securitySafetyDefenseRating,
                       Boolean isRiskAssessment, String trainContent, Integer numberOfSecurityGuards,
                       Boolean isPublicSecuritySecurity, Boolean isPropertyEnterprise, String natureOfSelfRecruitedUnits,
                       String placeOfSupervise, String superviseDepartId, String superviseDepartName, String fax, String adminUserName,
                       String adminUserTelephone, JsonProvider jsonProvider,String address) {
        if (sysName != null) {
            this.setSysName(sysName);
        }
        if (description != null) {
            this.setDescription(description);
        }
        if (logoPath != null) {
            this.setLogoPath(logoPath);
        }

        if(longitude != null && latitude != null){
            this.setLongitude(longitude);
            this.setLatitude(latitude);
            OrgGisLocationSnapshot sn = jsonProvider.toObject(OrgGisLocationSnapshot.class,this.getLonLatJson());
            long days = 0;
            if(sn != null) {
                LocalDate localDate = sn.getTime().toLocalDateTime().toLocalDate();
                LocalDate localDate2 = Timestamp.from(Instant.now()).toLocalDateTime().toLocalDate();
                days = ChronoUnit.DAYS.between(localDate, localDate2);
            }
            if(sn == null || days > 30){
                sn = OrgGisLocationSnapshot.create(latitude, longitude,address);
            }else{
                sn.update(latitude,longitude,address);
            }
            String json = jsonProvider.getJson(sn);
            this.setLonLatJson(json);
        }
        if (institutionalCode != null) {
            this.setInstitutionalCode(institutionalCode);
        }
        if (industryDetailType != null) {
            this.setIndustryDetailType(industryDetailType);
        }
        if (name != null) {
            this.setName(name);
        }
        if (type != null) {
            this.setType(type);
        }
        if (telephone != null) {
            this.setTelephone(telephone);
        }
        if (placeOfRegister != null) {
            this.setPlaceOfRegister(placeOfRegister);
        }
        if (placeOfBusiness != null) {
            this.setPlaceOfBusiness(placeOfBusiness);
        }
        if (placeOfSupervise != null) {
            this.setSuperviseRegionCode(placeOfSupervise);
        }
        if (superviseDepartId != null) {
            this.setSuperviseDepartId(superviseDepartId);
        }
        if (superviseDepartName != null) {
            this.setSuperviseDepartName(superviseDepartName);
        }
        if (fax != null) {
            this.setFax(fax);
        }
        this.setLastUpdatedTime(Timestamp.from(Instant.now()));

        CompanyEntity company = this.getCompany();
        if(company==null) {
            company = CompanyEntity.create(this);
        }

        company.change(unifySocialCreditCode, unifySocialCreditCodeFile, parentName,
                parentCertificateType, parentCertificateNumber, parentLegalPersonName,
                parentLegalPersonTelephone, economicType, nature, serviceScopeList, registeredCapital,
                fixedCapital, annualProfitTax, annualSalesVolume, certificateType, servicePermitNumber,
                securityApprovalNumber, nameOfIssuingAuthority, firstIssueServicePermit,
                servicePermitAttachment, trainContent, securityPreparednessRating,
                securityArmedRating, securitySafetyDefenseRating,
                isRiskAssessment, numberOfSecurityGuards, isPublicSecuritySecurity,
                isPropertyEnterprise, natureOfSelfRecruitedUnits,
                legalPersonName, legalPersonTelephone, legalPersonCredentialType,
                legalPersonCredentialNumber, legalPersonNationality, securityPersonName, securityPersonTelephone,
                securityPersonCredentialType, securityPersonCredentialNumber);

        this.setCompany(company);

        if (StringUtils.isNotBlank(adminUserName) || StringUtils.isNotBlank(adminUserTelephone)) {
            TenantUserEntity adminUser = this.getTenantUser();
            if (StringUtils.isNotBlank(adminUserName)) {
                adminUser.changeName(adminUserName);
            }
            if (StringUtils.isNotBlank(adminUserTelephone)) {
                adminUser.changeTelephone(adminUserTelephone);
            }
            this.setTenantUser(adminUser);
        }
    }

    public void changeLogoPath(String logoPath) {
        this.setLogoPath(logoPath);
        this.setLastUpdatedTime(Timestamp.from(Instant.now()));
    }

    /**
     * description：审批不通过，公司作废
     * author：linchunpeng
     * date：2024/11/20
     */
    public void abandon() {
        this.setName(this.getName().concat("-作废-").concat(DateUtil.format(new Date(), "yyyyMMddHHmmss")));
        this.setLastUpdatedTime(Timestamp.from(Instant.now()));
    }

    /**
     *需改审批状态
     * @param status
     * @param note
     */
    public void approve(ApprovedStatus status, String note) {
        if (this.getApprovedInformationValueType()!=null &&
                this.getApprovedInformationValueType().getStatus() == ApprovedStatus.Passed) {
            throw new BadTenantException("企业已经审批通过，无需重复审批");
        }

        ApprovedInformationValueType approvedInformation = ApprovedInformationValueType.create(status, note);
        this.setApprovedInformationValueType(approvedInformation);

        this.recordEvent(OrganizationApprovedChangedEvent.create(
                this.getId(),
                approvedInformation.getStatus(),
                this.getPlaceOfRegister(),
                this.getPlaceOfBusiness(),
                institutionalCode,superviseRegionCode));

        this.setLastUpdatedTime(Timestamp.from(Instant.now()));
    }

    public void setCompanyEntity(RegisterCompanyCommand command) {
        CompanyEntity company = CompanyEntity.create(this, command);
        this.setCompany(company);
    }

    public void setCompanyEntity(CreateMyOrganizationCommand command) {
        CompanyEntity company = CompanyEntity.create(this, command);
        this.setCompany(company);
    }


    /**
     * 只适合用于在新增组织的时候进行操作.
     * @param department
     * @param masterSlaveType
     * @param name
     * @param telephone
     * @param credentialType
     * @param credentialNumber
     * @param ensureExistsUser
     */
    @Deprecated
    public void addEmployee(
            DepartmentEntity department,
            MasterSlaveType masterSlaveType,
            String name, String telephone,
            Date hiredDate,
            CredentialType credentialType,
            String credentialNumber,
            OccupationType occupationType,
            boolean ensureExistsUser) {
        Collection<EmployeeEntity> employees = this.getEmployees();
        if (employees == null) {
            employees = new ArrayList<>();
        }

        EmployeeEntity employee = EmployeeEntity.create(
                TenantContext.getInstance().resolve(EventDispatcher.class),
                this,
                department,
                name, telephone, null, null,
                hiredDate, MasterSlaveType.Normal,
                credentialType, credentialNumber, occupationType, ensureExistsUser,
                AuthUtil.getCurrentOperator()
                );
        employees.add(employee);

        this.setEmployees(employees);
        this.setLastUpdatedTime(Timestamp.from(Instant.now()));
    }


    @Deprecated
    public EmployeeEntity addEmployee(
            DepartmentEntity department, MasterSlaveType masterSlaveType,
            TenantUserEntity tenantUser, String position, boolean isDomainAdmin,
            OperatorValueType operator) {
        Collection<EmployeeEntity> employees = this.getEmployees();
        if (employees == null) {
            employees = new ArrayList<>();
        }

        EmployeeEntity employee = EmployeeEntity.create(
                TenantContext.getInstance().resolve(EventDispatcher.class),
                this,
                department,
                tenantUser, masterSlaveType, position, OccupationType.Normal,
                null, null,isDomainAdmin,operator);

        employees.add(employee);

        this.setEmployees(employees);
        this.setLastUpdatedTime(Timestamp.from(Instant.now()));


        return employee;
    }

    /**
     * 配置组织拥有者
     * @param tenantUser
     */
    public void changeOwner(TenantUserEntity tenantUser) {
        tenantUser.assignOrganization(this);
        this.setTenantUser(tenantUser);
    }

    /**
     * 新增部门
     * @param name
     */
    public DepartmentEntity addDepartment(String name, int displayOrder) {
        Collection<DepartmentEntity> departments = this.getDepartments();
        if (departments == null) {
            departments = new ArrayList<>();
        }

        DepartmentEntity department = DepartmentEntity.createRoot(this, name, displayOrder);
        departments.add(department);
        this.setDepartments(departments);

        return department;
    }

    protected OrganizationEntity() {
        String value = UUIDUtil.getShortUuid();
        this.setId(value);
        this.setCode(value);
        this.setCreatedTime(Timestamp.from(Instant.now()));
        this.setOrganizationLevel(OrganizationLevel.Basic.getValue());
    }

    protected OrganizationEntity(String industryCode, String institutionalCode,
                                 String name,String telephone
                                 ) {
        this();
        this.setName(name);
        this.setIndustryCode(industryCode);
        this.setInstitutionalCode(institutionalCode);
        this.setTelephone(telephone);
        this.setSuperviseRegionCode(SystemConstant.EmptyValue);
        this.setSuperviseDepartId(SystemConstant.EmptyValue);
        this.setSuperviseDepartName(SystemConstant.EmptyValue);
        this.setStatus(OrganizationsStatus.Normal);
        this.setType(ParentSubsidiary.None);
        this.setOrganizationLevel(OrganizationLevel.Basic.getValue());
        this.setApprovedInformationValueType(ApprovedInformationValueType.create(ApprovedStatus.Init, ""));

        this.recordEvent(OrganizationCreatedEvent.create(this, this.getName(), new HashMap<>()));
        /**
         * 默认添加改组织为默认部门
         */
        this.addDepartment(this.getName(), 0);
    }

    protected OrganizationEntity(String industryCode, String institutionalCode, String name,
                                 String telephone, ParentSubsidiary type, IndustryDetailType industryDetailType,
                                 String superviseRegionCode, String superviseDepartId, String superviseDepartName,
                                 String shareOrganizationId,
                                 String shareOrganizationName, String shareEmployeeId, String shareEmployeeName,
                                 Map<String,String> dynamic) {
        this(industryCode,institutionalCode,name,telephone);
        this.setType(type == null ? ParentSubsidiary.None : type);
        this.setIndustryDetailType(industryDetailType);
        this.setSuperviseRegionCode(superviseRegionCode == null ? "#" : superviseRegionCode);
        this.setSuperviseDepartId(superviseDepartId == null ? "#" : superviseDepartId);
        this.setSuperviseDepartName(superviseDepartName == null ? "#" : superviseDepartName);

        this.setShareOrganizationId(shareOrganizationId);
        this.setShareOrganizationName(shareOrganizationName);
        this.setShareEmployeeId(shareEmployeeId);
        this.setShareEmployeeName(shareEmployeeName);

        /**
         * 统一在另外一个构造函数使用
         * OrganizationEntity(String industryCode, String institutionalCode,
         *                                  String name,String telephone
         *                                  )
         */
        //this.recordEvent(OrganizationCreatedEvent.create(this, this.getName(), dynamic));
        /**
         * 默认添加改组织为默认部门
         */
       // this.addDepartment(this.getName(), 0);
    }

    public static OrganizationEntity create(String industryCode, String institutionalCode, String name,
                                            String telephone, ParentSubsidiary type, IndustryDetailType industryDetailType,
                                            String superviseRegionCode, String superviseDepartId, String superviseDepartName,
                                            String shareOrganizationId,
                                            String shareOrganizationName, String shareEmployeeId, String shareEmployeeName,
                                            Map<String,String> dynamic) {
        OrganizationEntity organization = new OrganizationEntity(industryCode, institutionalCode, name, telephone,
                type, industryDetailType, superviseRegionCode, superviseDepartId, superviseDepartName,
                shareOrganizationId, shareOrganizationName, shareEmployeeId, shareEmployeeName,
                dynamic);
        organization.setStatus(OrganizationsStatus.Normal);
        return organization;
    }

    public static OrganizationEntity createBasic(String industryCode, String institutionalCode,String name,String telephone) {
        OrganizationEntity organization = new OrganizationEntity(industryCode, institutionalCode, name, telephone);

        return organization;
    }

    @Transient
    public boolean infoCompleted() {
        boolean result = true;
        try {
            CompanyEntity company = this.getCompany();
            if (company.getNature() == null) {
                throw new BadTenantException("公司类型不能为空！");
            }
            if (this.getInstitutionalCode().equals("0102")) {
                //验证机构类型为保安服务公司时必填
                if (this.getIndustryDetailType() == null) {
                    throw new BadTenantException("保安服务公司类型不能为空！");
                }
                if (StringUtils.isBlank(company.getFixedCapital())) {
                    throw new BadTenantException("固定资本不能为空！");
                }
                if (StringUtils.isBlank(company.getAnnualSalesVolume())) {
                    throw new BadTenantException("年营业额不能为空！");
                }
                if (StringUtils.isBlank(company.getAnnualProfitTax())) {
                    throw new BadTenantException("年利税不能为空！");
                }
                if (StringUtils.isBlank(company.getSecurityApprovalNumber())) {
                    throw new BadTenantException("批准文号不能为空！");
                }
                if (company.getServiceScope() == null) {
                    throw new BadTenantException("服务范围不能为空！");
                }
                if (company.getSecurityPreparednessRating() == null) {
                    throw new BadTenantException("人力防范评定等级不能为空！");
                }
                if (company.getSecurityArmedRating() == null) {
                    throw new BadTenantException("武装守护押运评定等级不能为空！");
                }
                if (company.getSecuritySafetyDefenseRating() == null) {
                    throw new BadTenantException("安全技术防范评定等级不能为空！");
                }
                if (company.getIsRiskAssessment() == null) {
                    throw new BadTenantException("是否有风险评估资质不能为空！");
                }
                if (StringUtils.isBlank(company.getServicePermitNumber())) {
                    throw new BadTenantException("保安服务许可证号不能为空！");
                }
                if (StringUtils.isBlank(company.getNameOfIssuingAuthority())) {
                    throw new BadTenantException("发证机关名称不能为空！");
                }
                if (company.getFirstIssueServicePermit() == null) {
                    throw new BadTenantException("发证日期不能为空！");
                }
                if (StringUtils.isBlank(company.getServicePermitAttachment())) {
                    throw new BadTenantException("保安服务许可证扫描件不能为空！");
                }

                if (this.getType().ordinal() == ParentSubsidiary.Branch.ordinal()
                        || this.getType().ordinal() == ParentSubsidiary.Subsidiary.ordinal()) {
                    //验证总/分/子公司 = 分 || 子 必填项
                    if (StringUtils.isBlank(company.getParentName())) {
                        throw new BadTenantException("总公司名称不能为空！");
                    }
                    if (company.getParentCertificateType() == null) {
                        throw new BadTenantException("总公司证件类型不能为空！");
                    }
                    if (StringUtils.isBlank(company.getParentCertificateNumber())) {
                        throw new BadTenantException("总公司证件号码不能为空！");
                    }
                    if (StringUtils.isBlank(company.getParentLegalPersonName())) {
                        throw new BadTenantException("总公司法人姓名不能为空！");
                    }
                    if (StringUtils.isBlank(company.getParentLegalPersonTelephone())) {
                        throw new BadTenantException("总公司联系电话不能为空！");
                    }
                }
            } else if (this.getInstitutionalCode().equals("0103")) {
                //验证机构类型为保安培训单位时必填
                if (StringUtils.isBlank(company.getTrainContent())) {
                    throw new BadTenantException("培训单位的培训内容不能为空！");
                }
                if (StringUtils.isBlank(company.getServicePermitNumber())) {
                    throw new BadTenantException("保安培训许可（备案）证号不能为空！");
                }
                if (StringUtils.isBlank(company.getNameOfIssuingAuthority())) {
                    throw new BadTenantException("发证机关名称不能为空！");
                }
                if (company.getFirstIssueServicePermit() == null) {
                    throw new BadTenantException("发证日期不能为空！");
                }
                if (StringUtils.isBlank(company.getServicePermitAttachment())) {
                    throw new BadTenantException("保安培训许可（备案）证扫描件不能为空！");
                }
            } else if (this.getInstitutionalCode().equals("0104")) {
                //验证机构类型为自行招用保安员单位时必填
                if (StringUtils.isBlank(company.getSecurityPersonName())) {
                    throw new BadTenantException("保安负责人姓名不能为空");
                }
                if (StringUtils.isBlank(company.getSecurityPersonTelephone())) {
                    throw new BadTenantException("保安负责人手机号码不能为空");
                }
                if (company.getSecurityPersonCredentialType() == null) {
                    throw new BadTenantException("保安负责人证件类型不能为空");
                }
                if (StringUtils.isBlank(company.getSecurityPersonCredentialNumber())) {
                    throw new BadTenantException("保安负责人证件编号不能为空");
                }
                if (company.getNumberOfSecurityGuards() == null) {
                    throw new BadTenantException("拟自招保安员数不能为空！");
                }
                if (company.getIsPublicSecuritySecurity() == null) {
                    throw new BadTenantException("是否治安保卫重点单位不能为空！");
                }
                if (company.getIsPropertyEnterprise() == null) {
                    throw new BadTenantException("是否物业企业不能为空！");
                }
                if (StringUtils.isBlank(company.getNatureOfSelfRecruitedUnits())) {
                    throw new BadTenantException("自招保安单位性质不能为空！");
                }
            }
            this.validateLocation(this.getPlaceOfRegister(), "注册地区", true);
            this.validateLocation(this.getPlaceOfBusiness(), "经营地区", true);
        } catch (Exception e) {
            result = false;
        }
        return result;
    }

    @Transient
    public boolean superviseCompleted() {
        boolean result = true;
        try {
            if (StringUtils.isBlank(this.getSuperviseRegionCode()) || "#".equals(this.getSuperviseRegionCode())) {
                throw new BadTenantException("监管地区不能为空！");
            }
            if (StringUtils.isBlank(this.getSuperviseDepartId()) || "#".equals(this.getSuperviseRegionCode())) {
                throw new BadTenantException("监管机构不能为空！");
            }
        } catch (Exception e) {
            result = false;
        }
        return result;
    }


    @Transient
    private void validateLocation(LocationValueType locationValueType, String category, boolean isValidAddress) {
        if (locationValueType == null) {
            throw new BadTenantException(String.format("%s不能为空!", category));
        }

        if (locationValueType.getProvince() == null || StringUtils.isBlank(locationValueType.getProvince().getCode())) {
            throw new BadTenantException(String.format("%s的省份不能为空!", category));
        }

//        if (locationValueType.getCity() == null || StringUtils.isBlank(locationValueType.getCity().getCode())) {
//            throw new BadTenantException(String.format("%s的城市不能为空!", category));
//        }
//
//        if (locationValueType.getDistrict() == null || StringUtils.isBlank(locationValueType.getDistrict().getCode())) {
//            throw new BadTenantException(String.format("%s的区域不能为空!", category));
//        }

        if (isValidAddress && StringUtils.isBlank(locationValueType.getAddress())) {
            throw new BadTenantException(String.format("%s的地址不能为空!", category));
        }
    }
}
