@isTest
private class SoakupHPDeptTeamBatchTest {

    private static Profile p{get;set;}
    private static Account hp{get;set;}
    private static List<Account> dcList{get;set;}
    private static List<Account> dptList{get;set;}
    private static User dc0Owner{get;set;}
    private static User dc1Owner{get;set;}

    static void initTestData(String Level1_Code) {
        p = [select Id from Profile where id =:System.Label.ProfileId_SystemAdmin];

        // ユーザー作成
        User hpOwner = new User(Test_staff__c = true, LastName = 'hp', FirstName = 'owner', Alias = 'hp', CommunityNickname = 'hpOwner', Email = 'olympus_hpowner@sunbridge.com', Username = 'olympus_hpowner@sunbridge.com', IsActive = true, EmailEncodingKey = 'ISO-2022-JP', TimeZoneSidKey = 'Asia/Tokyo', LocaleSidKey = 'ja_JP', LanguageLocaleKey = 'ja', ProfileId = p.id);
        dc0Owner = new User(Test_staff__c = true, LastName = 'dc0', FirstName = 'owner', Alias = 'dc0', CommunityNickname = 'dc0Owner', Email = 'olympus_dc0Owner@sunbridge.com', Username = 'olympus_dc0Owner@sunbridge.com', IsActive = true, EmailEncodingKey = 'ISO-2022-JP', TimeZoneSidKey = 'Asia/Tokyo', LocaleSidKey = 'ja_JP', LanguageLocaleKey = 'ja', ProfileId = p.id);
        dc1Owner = new User(Test_staff__c = true, LastName = 'dc1', FirstName = 'owner', Alias = 'dc1', CommunityNickname = 'dc1Owner', Email = 'olympus_dc1Owner@sunbridge.com', Username = 'olympus_dc1Owner@sunbridge.com', IsActive = true, EmailEncodingKey = 'ISO-2022-JP', TimeZoneSidKey = 'Asia/Tokyo', LocaleSidKey = 'ja_JP', LanguageLocaleKey = 'ja', ProfileId = p.id);
        User dc0Member = new User(Test_staff__c = true, LastName = 'dc0', FirstName = 'member', Alias = 'dc0Mb', CommunityNickname = 'dc0Member', Email = 'olympus_dc0Member@sunbridge.com', Username = 'olympus_dc0Member@sunbridge.com', IsActive = true, EmailEncodingKey = 'ISO-2022-JP', TimeZoneSidKey = 'Asia/Tokyo', LocaleSidKey = 'ja_JP', LanguageLocaleKey = 'ja', ProfileId = p.id);
        User dc1Member = new User(Test_staff__c = true, LastName = 'dc1', FirstName = 'member', Alias = 'dc1Mb', CommunityNickname = 'dc1Member', Email = 'olympus_dc1Member@sunbridge.com', Username = 'olympus_dc1Member@sunbridge.com', IsActive = true, EmailEncodingKey = 'ISO-2022-JP', TimeZoneSidKey = 'Asia/Tokyo', LocaleSidKey = 'ja_JP', LanguageLocaleKey = 'ja', ProfileId = p.id);
        insert new User[] {hpOwner, dc0Owner, dc1Owner, dc0Member, dc1Member};

        // 取引先作成
        List<RecordType> rectHp = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = '病院'];
        if (rectHp.size() == 0) {
            return;
        }
        List<RecordType> rectDpt = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = '診療科 消化科'];
        if (rectDpt.size() == 0) {
            return;
        }
        
        Address_Level__c sm = new Address_Level__c(Level1_Code__c = Level1_Code, Name='test');
        insert sm;
        
        hp = new Account(RecordTypeId = rectHp[0].Id, Name = 'SoakupTestHp', OwnerId = hpOwner.Id, State_Master__c = sm.Id);
        insert hp;

        // 戦略課室に、担当者とチームを設定
        dcList = [select Id from Account where ParentId = :hp.Id and RecordType.Name in ('戦略科室分類 消化科','戦略科室分類 呼吸科') order by Id];
        dcList[0].OwnerId = dc0Owner.Id;
        dcList[1].OwnerId = dc1Owner.Id;
        update dcList;
        AccountTeamMember dcT0 = new AccountTeamMember();//AccountAccessLevel = 'Read'
        dcT0.UserId = dc0Member.Id;
        dcT0.TeamMemberRole = '営業担当';
        dcT0.AccountId = dcList[0].Id;
        AccountTeamMember dcT1 = new AccountTeamMember();//AccountAccessLevel = 'Edit'
        dcT1.UserId = dc1Member.Id;
        dcT1.TeamMemberRole = 'FSE';
        dcT1.AccountId = dcList[1].Id;
        insert new AccountTeamMember[] {dcT0, dcT1};
        AccountShare dcTS0 = new AccountShare(UserOrGroupId=dcT0.UserId, AccountId=dcT0.AccountId, AccountAccessLevel='Read', OpportunityAccessLevel = 'None');
        AccountShare dcTS1 = new AccountShare(UserOrGroupId=dcT1.UserId, AccountId=dcT1.AccountId, AccountAccessLevel='Edit', OpportunityAccessLevel = 'None');
        insert new AccountShare[] {dcTS0, dcTS1};

        // 診療科作成、Ownerとチームは自動引継ぐと想定
        Account dpt0 = new Account(RecordTypeId = rectDpt[0].Id, Name = '*', Department_Name__c = 'SoakupTestDepart0', ParentId = dcList[0].Id, Department_Class__c = dcList[0].Id, Hospital__c = hp.Id);
        Account dpt1 = new Account(RecordTypeId = rectDpt[0].Id, Name = '*', Department_Name__c = 'SoakupTestDepart1', ParentId = dcList[0].Id, Department_Class__c = dcList[0].Id, Hospital__c = hp.Id);
        dptList = new Account[] {dpt0, dpt1};
        insert dptList;
    }

    static testMethod void testExecute1() {
        String loginId = UserInfo.getUserId();
        SoakupHPDeptTeamBatchTest.initTestData('CN-22');

        // 診療科にチームを追加
        User dpt0Owner = new User(Test_staff__c = true, LastName = 'dpt0', FirstName = 'owner', Alias = 'dpt0', CommunityNickname = 'dpt0Owner', Email = 'olympus_dpt0Owner@sunbridge.com', Username = 'olympus_dpt0Owner@sunbridge.com', IsActive = true, EmailEncodingKey = 'ISO-2022-JP', TimeZoneSidKey = 'Asia/Tokyo', LocaleSidKey = 'ja_JP', LanguageLocaleKey = 'ja', ProfileId = p.id);
        User dpt1Owner = new User(Test_staff__c = true, LastName = 'dpt1', FirstName = 'owner', Alias = 'dpt1', CommunityNickname = 'dpt1Owner', Email = 'olympus_dpt1Owner@sunbridge.com', Username = 'olympus_dpt1Owner@sunbridge.com', IsActive = true, EmailEncodingKey = 'ISO-2022-JP', TimeZoneSidKey = 'Asia/Tokyo', LocaleSidKey = 'ja_JP', LanguageLocaleKey = 'ja', ProfileId = p.id);
        User dpt0Member = new User(Test_staff__c = true, LastName = 'dpt0', FirstName = 'member', Alias = 'dpt0Mb', CommunityNickname = 'dpt0Member', Email = 'olympus_dpt0Member@sunbridge.com', Username = 'olympus_dpt0Member@sunbridge.com', IsActive = true, EmailEncodingKey = 'ISO-2022-JP', TimeZoneSidKey = 'Asia/Tokyo', LocaleSidKey = 'ja_JP', LanguageLocaleKey = 'ja', ProfileId = p.id);
        User dpt1Member = new User(Test_staff__c = true, LastName = 'dpt1', FirstName = 'member', Alias = 'dpt1Mb', CommunityNickname = 'dpt1Member', Email = 'olympus_dpt1Member@sunbridge.com', Username = 'olympus_dpt1Member@sunbridge.com', IsActive = true, EmailEncodingKey = 'ISO-2022-JP', TimeZoneSidKey = 'Asia/Tokyo', LocaleSidKey = 'ja_JP', LanguageLocaleKey = 'ja', ProfileId = p.id);
        insert new User[] {dpt0Owner, dpt1Owner, dpt0Member, dpt1Member};
        
        dptList[0].OwnerId = dpt0Owner.Id;
        dptList[1].OwnerId = dpt1Owner.Id;
        update dptList;

        AccountTeamMember dT00 = new AccountTeamMember();//AccountAccessLevel = 'Read'
        dT00.UserId = dc0Owner.Id;
        dT00.TeamMemberRole = '営業担当';
        dT00.AccountId = dptList[0].Id;
        AccountTeamMember dT0 = new AccountTeamMember();//AccountAccessLevel = 'Read'
        dT0.UserId = dpt0Member.Id;
        dT0.TeamMemberRole = '営業担当';
        dT0.AccountId = dptList[0].Id;
        AccountTeamMember dT1 = new AccountTeamMember();//AccountAccessLevel = 'Edit'
        dT1.UserId = dpt1Member.Id;
        dT1.TeamMemberRole = '営業担当';
        dT1.AccountId = dptList[1].Id;
        insert new AccountTeamMember[] {dT00, dT0, dT1};
        AccountShare dTS00 = new AccountShare(UserOrGroupId=dT00.UserId, AccountId=dT00.AccountId, AccountAccessLevel='Read', OpportunityAccessLevel = 'None');
        AccountShare dTS0 = new AccountShare(UserOrGroupId=dT0.UserId, AccountId=dT0.AccountId, AccountAccessLevel='Read', OpportunityAccessLevel = 'None');
        AccountShare dTS1 = new AccountShare(UserOrGroupId=dT1.UserId, AccountId=dT1.AccountId, AccountAccessLevel='Edit', OpportunityAccessLevel = 'None');
        insert new AccountShare[] {dTS00, dTS0, dTS1};

        // バッチ実行
        String[] recTypes = new String[] {'診療科 その他', '診療科 呼吸科', '診療科 婦人科', '診療科 普外科', '診療科 泌尿科', '診療科 消化科', '診療科 耳鼻喉科'};
        List<RecordType> rects = [select Id, Name from RecordType where IsActive = true and SobjectType = 'Account' and Name IN :recTypes];
        List<String> deptRectIds = new List<String>();
        for (RecordType rect : rects) {
            deptRectIds.add(rect.Id);
        }

        List<User> batchUser = [select Id, Name from User where Name = 'Batch'];
        System.assertEquals(1, batchUser.size());
        if (batchUser.size() == 0) {
            return;
        }
        System.Test.StartTest();
        Id execBTId = Database.executeBatch(new SoakupHPDeptTeamBatch(deptRectIds, batchUser[0].Id, '5.华南', '6.西南'), 5);
        execBTId = Database.executeBatch(new SoakupHPDeptTeamBatch(deptRectIds, batchUser[0].Id, '2.东北', '3.西北'), 5);
        execBTId = Database.executeBatch(new SoakupHPDeptTeamBatch(deptRectIds, batchUser[0].Id, '1.华北', null), 5);
        execBTId = Database.executeBatch(new SoakupHPDeptTeamBatch(deptRectIds, batchUser[0].Id, '4.华东', null), 5);
        System.Test.StopTest();

        // assert しかい、具体的なロジックチェックは SoakupHPDeptTeamTest にて実施
        //List<AccountTeamMember> hpTList = [select Id, UserId, User.Name, TeamMemberRole, AccountId, AccountAccessLevel from AccountTeamMember where AccountId = :hp.Id and UserId <> :loginId order by User.Name];
        //System.assertEquals(3, hpTList.size());
    }
}