public without sharing class FixtureOneToOneLinkHandler extends Oly_TriggerHandler {

    private Map<Id, Fixture_OneToOne_Link__c> newMap;
    private Map<Id, Fixture_OneToOne_Link__c> oldMap;
    private List<Fixture_OneToOne_Link__c> newList;
    private List<Fixture_OneToOne_Link__c> oldList;

    private static Map<Id, Fixture_OneToOne_Link__c> assMap = new Map<Id, Fixture_OneToOne_Link__c>();
    private static Map<Id, Fixture_OneToOne_Link__c> assUpdMap = new Map<Id, Fixture_OneToOne_Link__c>();

    public FixtureOneToOneLinkHandler() {
        this.newMap = (Map<Id, Fixture_OneToOne_Link__c>) Trigger.newMap;
        this.oldMap = (Map<Id, Fixture_OneToOne_Link__c>) Trigger.oldMap;
        this.newList = (List<Fixture_OneToOne_Link__c>) Trigger.new;
        this.oldList = (List<Fixture_OneToOne_Link__c>) Trigger.old;
    }

    protected override void beforeInsert() {
        beforeSetValue();
    }

    protected override void beforeUpdate() {
        beforeSetValue();
    }

    protected override void afterInsert() {
        setAssetOntToOne();
    }

    protected override void afterUpdate() {
        setAssetOntToOne();
    }

    protected override void afterDelete() {
        setAssetOntToOne();
    }

    private void beforeSetValue() {
        for (Fixture_OneToOne_Link__c nObj : newList) {
            nObj.In_wh_Fu_Shu_Pin_You_Xiao_Ku_Cun__c = nObj.In_wh_Fu_Shu_Pin_You_Xiao_Ku_Cun_F__c;
            if (String.isNotBlank(nObj.Accessory_Asset__c)
                    && nObj.Manage_type__c == FixtureUtil.managetypeMap.get(FixtureUtil.Managetype.Ge_Ti_Guan_Li)) {
                nObj.Ge_Ti_Fu_Shu_Pin_Key__c = nObj.Accessory_Asset__c;
            } else {
                nObj.Ge_Ti_Fu_Shu_Pin_Key__c = null;
            }
        }
    }

    public void setAssetOntToOne() {
        Map<Id, Asset> assetMap = new Map<Id, Asset>();     // TODO 将来 Static にする
        Map<Id, Asset> checkMainOneToOneMap = new Map<Id, Asset>();   // 主体check用
        List<String> otoId = new List<String>();

        List<Fixture_OneToOne_Link__c> fotos;
        if(!Trigger.isDelete) {
            fotos = newList;
        } else {
            fotos = oldList;
        }

        for (Fixture_OneToOne_Link__c foto : fotos) {
            if (Trigger.isInsert) {
                Fixture_OneToOne_Link__c nObj = foto;
                // 主体的判断
                if (String.isNotBlank(nObj.Main_Asset__c)) {
                    assetMap.put(nObj.Main_Asset__c, new Asset(
                            Id = nObj.Main_Asset__c,
                            Main_OneToOne__c = true));
                }
                // 付属品的判断
                if (String.isNotBlank(nObj.Accessory_Asset__c)
                        && nObj.Manage_type__c == FixtureUtil.managetypeMap.get(FixtureUtil.Managetype.Ge_Ti_Guan_Li)) {
                    assetMap.put(nObj.Accessory_Asset__c, new Asset(
                            Id = nObj.Accessory_Asset__c,
                            Fixture_OneToOne_Link__c = nObj.Id));
                }
            }
            else if (Trigger.isUpdate) {
                Fixture_OneToOne_Link__c nObj = foto;
                Fixture_OneToOne_Link__c oObj = oldMap.get(nObj.Id);
                // 主体的判断
                if (String.isNotBlank(nObj.Main_Asset__c)
                        && (oObj.Main_Asset__c != nObj.Main_Asset__c)) {
                    assetMap.put(nObj.Main_Asset__c, new Asset(
                            Id = nObj.Main_Asset__c,
                            Main_OneToOne__c = true));
                    checkMainOneToOneMap.put(oObj.Main_Asset__c, new Asset(
                            Id = oObj.Main_Asset__c,
                            Main_OneToOne__c = false));
                }
                // 付属品的判断
                if (String.isNotBlank(oObj.Accessory_Asset__c)
                        && oObj.Manage_type__c == FixtureUtil.managetypeMap.get(FixtureUtil.Managetype.Ge_Ti_Guan_Li)
                        && (oObj.Accessory_Asset__c != nObj.Accessory_Asset__c)) {
                    assetMap.put(nObj.Accessory_Asset__c, new Asset(
                            Id = nObj.Accessory_Asset__c,
                            Fixture_OneToOne_Link__c = nObj.Id));
                    assetMap.put(oObj.Accessory_Asset__c, new Asset(
                            Id = oObj.Accessory_Asset__c,
                            Fixture_OneToOne_Link__c = null));
                }
            }
            else if (Trigger.isDelete) {
                Fixture_OneToOne_Link__c oObj = foto;
                // 主体的判断
                if (String.isNotBlank(oObj.Main_Asset__c)) {
                    checkMainOneToOneMap.put(oObj.Main_Asset__c, new Asset(
                            Id = oObj.Main_Asset__c,
                            Main_OneToOne__c = false));
                }
                // 付属品的判断
                if (String.isNotBlank(oObj.Accessory_Asset__c)
                        && oObj.Manage_type__c == FixtureUtil.managetypeMap.get(FixtureUtil.Managetype.Ge_Ti_Guan_Li)) {
                    assetMap.put(oObj.Accessory_Asset__c, new Asset(
                            Id = oObj.Accessory_Asset__c,
                            Fixture_OneToOne_Link__c = null));
                }
                if (String.isNotBlank(oObj.Id)) {
                    otoId.add(oObj.Id);
                }
            }
        }
        System.debug(checkMainOneToOneMap);
        // 主体 checkMainOneToOneMap 再判断
        if (!checkMainOneToOneMap.isEmpty()) {
            Set<Id> aSetId = new Set<Id>();
            // 变更一对一link的主体或删除一对一link时，查找旧的主体是否还存在一对一link
            for (AggregateResult checkedMain : [
                    SELECT Main_Asset__c, count(Id) cnt
                      FROM Fixture_OneToOne_Link__c
                     WHERE Main_Asset__c IN :checkMainOneToOneMap.keyset()
                     GROUP BY Main_Asset__c]) {
                System.debug(checkedMain);
                aSetId.add((Id) checkedMain.get('Main_Asset__c'));
            }

            for (Id mId : checkMainOneToOneMap.keyset()) {
                if (!aSetId.contains(mId)) assetMap.put(mId, checkMainOneToOneMap.get(mId));
            }
        }

        if (Trigger.isDelete) {
            if (otoId.size() > 0) {
                List<Rental_Apply_Equipment_Set_Detail__c> raesdList = [
                    select id, Fixture_OneToOne_Link_Id__c
                      from Rental_Apply_Equipment_Set_Detail__c 
                     where Fixture_OneToOne_Link_Id__c in :otoId and StockDown__c = false];
                if (!raesdList.isEmpty()) {
                    for (Rental_Apply_Equipment_Set_Detail__c raesd : raesdList) {
                        raesd.Fixture_OneToOne_Link_Id__c = null;
                    }
                    update raesdList;
                }
            }
        }

        if (!assetMap.isEmpty()) {
            update assetMap.values();
        }
    }
}