global without sharing class Batch_FixnoteToFiles implements Database.Batchable<sObject> {
    // Id batchJobId = Database.executeBatch(new Batch_FixAttachmentToFiles('Consumable_order__c',Datetime.newInstance(2023, 1, 1, 8, 0, 0),Datetime.newInstance(2024, 1, 1, 8, 0, 0)),2000);
    private Datetime creStartDate = null;
    private Datetime creEndDate = null;
    private String objectApiName  = null;
    private Set<String> parentIds = new Set<String>();
    global Batch_FixnoteToFiles(String objectType, Datetime startTime, Datetime endTime) {
        creStartDate = startTime;
        creEndDate = endTime;
        objectApiName = objectType;
    }
    public Batch_FixnoteToFiles(Set<String> parentIds) {
        this.parentIds = parentIds;
    }
    public Batch_FixnoteToFiles() {

    }

    global Database.QueryLocator start(Database.BatchableContext bc) {
        String queryObject = 'SELECT Id, title, OwnerId, ParentId, Parent.Name, Parent.Type, Body, CreatedDate, CreatedById FROM note';
        if (String.isNotBlank(objectApiName)) {
            queryObject = 'SELECT Id, title, OwnerId, ParentId, Parent.Name, Parent.Type, Body, CreatedDate, CreatedById FROM note WHERE Parent.Type =:objectApiName AND CreatedDate >=:creStartDate AND CreatedDate <:creEndDate Order by CreatedDate ASC';
        }
        if(parentIds.size() > 0){
            queryObject = 'SELECT Id, title, OwnerId, ParentId, Parent.Name, Parent.Type, Body, CreatedDate, CreatedById FROM note WHERE ParentId in:parentIds';
        }
        return Database.getQueryLocator(queryObject);
    }

    global void execute(Database.BatchableContext BC, List<note> scope) {
        List<ContentVersion> insertContents = new List<ContentVersion>();
        Map<string,id> nameParentMaps = new Map<string,id>();  
        Set<String> noteIds = new Set<String>();   
        for (note att : scope) {
            nameParentMaps.put(att.Id, att.ParentId);
            noteIds.add(att.Id);
            ContentVersion cVersion = new ContentVersion();
            //cVersion.ContentLocation = 'S';     //S-Document is in Salesforce. E-Document is outside of Salesforce. L-Document is on a Social Netork.
            cVersion.PathOnClient = att.Title + '.snote';   //File name with extention
            //cVersion.Origin = 'H';              //C-Content Origin. H-Chatter Origin.   
            cVersion.Title = att.Title;          //Name of the file
			cVersion.FirstPublishLocationId = att.ParentId;
            String body = String.valueOf(att.Body);
            if (String.isNotBlank(body)) {
                cVersion.VersionData = Blob.valueOf(Body);
            }
            //cVersion.VersionData = Blob.valueOf(att.Body);
            insertContents.add(cVersion);
        }
        if(insertContents.isEmpty()){
            return;
        }
        //Insert insertContents;
        List<Database.SaveResult> saveResultsContents = Database.insert(insertContents, false);
        insertLog(saveResultsContents,noteIds);
        /*set<Id> contentIds = new set<Id>();
        for(ContentVersion cv : insertContents){
            contentIds.add(cv.id);
        }
        List<ContentVersion> conDocuments = [SELECT ContentDocumentId, Title,PathOnClient FROM ContentVersion WHERE Id in: contentIds];
        List<ContentDocumentLink> insertDocLinks = new List<ContentDocumentLink>();  
        for(ContentVersion cv : conDocuments){
            ContentDocumentLink cDocLink = new ContentDocumentLink();
            cDocLink.ContentDocumentId = cv.ContentDocumentId;          //Add ContentDocumentId
            cDocLink.LinkedEntityId = nameParentMaps.get(cv.PathOnClient);     //Add attachment parentId
            cDocLink.ShareType = 'V';                                   //V - Viewer permission. C - Collaborator permission. I - Inferred permission.
            cDocLink.Visibility = 'AllUsers';
            insertDocLinks.add(cDocLink);
        }
        //Insert insertDocLinks;
        List<Database.SaveResult> saveResultsLinks = Database.insert(insertDocLinks, false);
        insertLog(saveResultsLinks,noteIds);*/
    }

    global void insertLog(List<Database.SaveResult> saveResults,Set<String> noteIds) {
        Transaction_Log__c traLog = new Transaction_Log__c();
        List<Map<String,String>> logMapList = new List<Map<String,String>>();
        for (Database.SaveResult result : saveResults) {
            String recordId = result.getId();
            if (!result.isSuccess()) {
                for (Database.Error error : result.getErrors()) {
                    Map<String,String> logMap = new Map<String,String>();
                    String errorMsg = error.getMessage();
                    logMap.put('recordId',recordId);
                    logMap.put('errorMsg',errorMsg);
                    logMapList.add(logMap);
                }
            }
        }
        if(logMapList.size() > 0){
            Map<String,String> attachmentIdMap = new Map<String,String>();
            attachmentIdMap.put('noteIds',JSON.serialize(noteIds));
            logMapList.add(attachmentIdMap);
            traLog.Response__c = JSON.serialize(logMapList);
            traLog.Module__c = 'note COnvert Transaction ';
            Insert traLog;
        }
    }

    global void finish(Database.BatchableContext BC) {

    }
}