/*
 * Author: Bubba Li
 * Created Date: 01/19/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditLeadController
 * History:
 *      01/19/2022 - Bubba Li - Initial Code.
 *
 * */
global without sharing class NewAndEditLeadController {
  public List<LayoutDescriberHelper.LayoutSection> layoutSections { get; set; }
  public String awsToken { get; set; }
  public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
  public static String sobjectTypeValue = 'Lead';
  public Boolean isNewMode { get; set; }
  public Boolean isCloneMode { get; protected set; }
  public String rtTypeId { get; set; }
  public String AWSDataId { get; set; }
  public String AWSDataIdInquiryForm { get; set; }
  public String contactId { get; set; } //For Lookup field
  public List<String> encryptedAPIList { get; set; }
  public String staticResource { get; set; }
  public String staticResourceContact { get; set; }
  public String staticResourceInquiryForm { get; set; }
  public String requiredFieldAPIListStr { get; set; }
  public String fieldAPIToLabelMapStr { get; set; }
  public String Input_Required_Field_Msg { get; set; }
  public String PIPL_Name_Label { get; set; }
  public String PIPL_Input_Account_Error_Msg { get; set; }
  public String sobjectPrefix { get; set; }
  public String sobjecttypeForFrontEnd { get; set; }
  public String contactsInfo { get; set; } //key sfid;value awsid
  public Inquiry_form__c ifc { get; private set; }
  public String contactDataId { get; set; }
  public String layoutSectionsStr { get; set; }
  public String isDecryptContact { get; set; }
  public final string ApiPrefix { get; private set; } //Add By Li Jun 20220403
  public Map<string, string> AWSToSobjectEncryptedMap { get; private set; }
  public string AWSToSobjectEncryptedMapJson {
    get {
      return JSON.serialize(AWSToSobjectEncryptedMap);
    }
  }
  public String LeadCreatedDate { get; set; } // XLIU-CFE8M7 20220624 ssm
  public String VLookUpFieldsJson { get; private set; }
  //zhj MEBG新方案改造 2022-11-29 start
  public String staticResourceV2 { get; set; }
  //zhj MEBG新方案改造 2022-11-29 end

  public NewAndEditLeadController(ApexPages.StandardController controller) {
    ApiPrefix = 'PIBackApi';
    isDecryptContact = '0';
    isNewMode = true;
    isCloneMode = false;
    Input_Required_Field_Msg = Label.Input_Required_Field_Msg;
    PIPL_Name_Label = Label.PIPL_Name_Label;
    PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
    sobjecttypeForFrontEnd = sobjectTypeValue;
    Map<string, string> mso = ApexPages.currentPage().getParameters();
    if (mso != null && mso.containsKey('newclone')) {
      isCloneMode = true;
    }
    //获取所有字段
    List<String> fieldList = new List<String>(
      Schema.getGlobalDescribe()
        .get('Lead')
        .getDescribe()
        .fields.getMap()
        .keyset()
    );
    // Add fields to controller. This is to avoid the SOQL error in visualforce page
    if (!Test.isRunningTest()) {
      controller.addFields(fieldList);
    }
    SObject obj = controller.getRecord();

    // XLIU-CFE8M7 20220624 ssm
    this.LeadCreatedDate = obj.get('CreatedDate') != null
      ? Date.newInstance(
            ((Datetime) obj.get('CreatedDate')).year(),
            ((Datetime) obj.get('CreatedDate')).month(),
            ((Datetime) obj.get('CreatedDate')).day()
          )
          .format()
      : Date.today().format();
    // this.LeadCreatedDate = Date.today().format();

    if (
      ApexPages.currentPage().getParameters().get('CF00N1000000962np_lkid') !=
      null
    ) {
      System.debug('CF00N1000000962np_lkid');
      //产品咨询单过来的
      String InquiryFormId = ApexPages.currentPage()
        .getParameters()
        .get('CF00N1000000962np_lkid');
      ifc = [
        SELECT
          Id,
          AWS_Data_Id__c,
          Contact_Name__c,
          Contact_Id__c,
          Hospital_Name__c,
          Hospital_ID__c,
          Department_Class__c,
          Department_ID__c,
          Opp_Name_Search__c,
          Opp_Name_Search_ID__c,
          Campaign__c,
          Campaign_ID__c,
          Name,
          Cancel_Reason__c,
          Phone__c,
          Email__c,
          Last_Name__c,
          LeadSource__c,
          Opportunity_Division__c,
          Request1__c,
          Urgent__c,
          Inquiry_Num__c,
          Product_Owner__c
        FROM Inquiry_form__c
        WHERE id = :InquiryFormId
      ];
      System.debug('ifc = ' + ifc);
      if (ifc.Contact_Id__c != null && ifc.Contact_Id__c != '') {
        Contact c = [
          SELECT AWS_Data_Id__c
          FROM Contact
          WHERE id = :ifc.Contact_Id__c
        ];
        contactDataId = c.AWS_Data_Id__c;
      }
      AWSDataIdInquiryForm = ifc.AWS_Data_Id__c;
      System.debug('ifc = ' + ifc);
      rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
      obj.put('OwnerId', UserInfo.getUserId());
      obj.put('Inquiry_Num__c', ifc.Inquiry_Num__c); // 20220413 SWAG-CBUB2W you
      obj.put('owner_not_automatically_update__c', ifc.Product_Owner__c);
      controller.getRecord().put('LeadSource', ifc.LeadSource__c);
      // controller.getRecord().put('Lead_Inquiry_form__c', ifc.Id);
    } else if (obj.Id != null) {
      //更新
      isNewMode = false;
      Lead leadData = [
        SELECT
          Id,
          RecordTypeId,
          AWS_Data_Id__c,
          Contact_Name__r.Id,
          Contact_Name__r.AWS_Data_Id__c
        FROM Lead
        WHERE id = :obj.Id
      ];
      rtTypeId = leadData.RecordTypeId;
      AWSDataId = leadData.AWS_Data_Id__c;
      Map<String, String> sfIdToAWSIdMap = new Map<String, String>();
      if (leadData.Contact_Name__r.Id != null) {
        sfIdToAWSIdMap.put(
          String.valueof(leadData.Contact_Name__r.Id).subString(0, 15),
          leadData.Contact_Name__r.AWS_Data_Id__c
        );
      }
      contactsInfo = JSON.serialize(sfIdToAWSIdMap);
    } else {
      //看链接中有无带过来的参数(客户人员)
      // Map<string,string> mso = ApexPages.currentPage().getParameters();
      for (String key : mso.keySet()) {
        System.debug('key=' + key + ',value=' + mso.get(key));
      }
      //联系人
      if (mso.containsKey('CF00N10000006ps6f_lkid')) {
        isDecryptContact = '1';
        String contactId = mso.get('CF00N10000006ps6f_lkid');
        //查询AWS_Data_Id__c
        List<Contact> contactList = new List<Contact>(
          [SELECT AWS_Data_Id__c FROM Contact WHERE id = :contactId]
        );
        Contact c = new Contact();
        if (contactList != null && contactList.size() > 0) {
          c = contactList[0];
        }
        if (c != null && c.AWS_Data_Id__c != '') {
          contactDataId = c.AWS_Data_Id__c;
        }
        //查询战略科室分类
        List<Contact> cs = [
          SELECT Account.Department_Class__c
          FROM Contact
          WHERE id = :contactId
        ];
        if (cs.size() > 0) {
          controller.getRecord()
            .put('Department_Class__c', cs[0].Account.Department_Class__c);
        }
        controller.getRecord()
          .put('Contact_Name__c', mso.get('CF00N10000006ps6f_lkid'));
      }
      //医院名
      if (mso.containsKey('CF00N10000002CvC5_lkid')) {
        controller.getRecord()
          .put('Hospital_Name__c', mso.get('CF00N10000002CvC5_lkid'));
        //通过医院id查询战略科室分类
        String hospitalId = mso.get('CF00N10000002CvC5_lkid');
        List<Account> hospitalAccount = [
          SELECT Department_Class__c
          FROM Account
          WHERE Id = :hospitalId
        ];
        if (hospitalAccount.size() > 0) {
          List<Account> departmentAccount = [
            SELECT Id
            FROM Account
            WHERE Id = :hospitalAccount[0].Department_Class__c
          ];
          if (departmentAccount.size() > 0) {
            System.debug('Department_Class__c = ' + departmentAccount[0].Id);
            controller.getRecord()
              .put('Department_Class__c', departmentAccount[0].Id);
          }
        }
      }
      //公司（科室）
      if (mso.containsKey('CF00N10000002CvC5')) {
        controller.getRecord().put('Company', mso.get('CF00N10000002CvC5'));
      }
      //战略科室CF00N10000006qNtt_lkid
      // if(mso.containsKey('CF00N10000006qNtt_lkid ')){
      //     controller.getRecord().put('Department_Class__c',mso.get('CF00N10000006qNtt_lkid '));
      // }
      // 2022-04-13 来源 jz start 0414 lt
      if (mso.containsKey('LeadSource')) {
        controller.getRecord().put('LeadSource', mso.get('LeadSource'));
      }
      if (mso.containsKey(System.Label.Opportunity_stage)) {
        controller.getRecord()
          .put('Opportunity_stage__c', mso.get(System.Label.Opportunity_stage));
      }
      //20220505 lt 注释掉
      // if (mso.containsKey('00N10000006qOF0')) {
      //     controller.getRecord().put('Close_Forecasted_Date__c', Date.parse(mso.get('00N10000006qOF0')));
      // }
      if (mso.containsKey(System.Label.Opp_Name)) {
        controller.getRecord()
          .put('Opp_Name__c', mso.get(System.Label.Opp_Name));
      }
      // if (mso.containsKey('00N100000048UBf')) {
      //     controller.getRecord().put('Contact__c', mso.get('00N100000048UBf'));
      // }
      if (mso.containsKey(System.Label.Purchase_Reason)) {
        controller.getRecord()
          .put('Purchase_Reason__c', mso.get(System.Label.Purchase_Reason));
      }
      if (mso.containsKey(System.Label.Fund_Basis)) {
        controller.getRecord()
          .put('Fund_Basis__c', mso.get(System.Label.Fund_Basis));
      }
      if (mso.containsKey(System.Label.Purchase_Type)) {
        controller.getRecord()
          .put('Purchase_Type__c', mso.get(System.Label.Purchase_Type));
      }
      //20220427
      if (mso.containsKey(System.Label.Tender_information)) {
        //招标项目Id
        controller.getRecord()
          .put(
            'Tender_information__c',
            mso.get(System.Label.Tender_information)
          );
      }
      if (mso.containsKey(System.Label.Agency_Opportunity)) {
        //经销商询价Id
        controller.getRecord()
          .put(
            'Agency_Opportunity__c',
            mso.get(System.Label.Agency_Opportunity)
          );
      }
      if (mso.containsKey(System.Label.Sales_Method)) {
        //经销商询价--招标方式
        controller.getRecord()
          .put('Sales_Method__c', mso.get(System.Label.Sales_Method));
      }
      if (mso.containsKey(System.Label.Request)) {
        controller.getRecord().put('Request__c', mso.get(System.Label.Request));
      }
      if (mso.containsKey(System.Label.Request_Detail)) {
        controller.getRecord()
          .put('Request_Detail__c', mso.get(System.Label.Request_Detail));
      }
      // 2022-04-13 来源 jz end 0414 lt
      rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
      // 20220420 lt OBSAP start
      if (String.isBlank(rtTypeId) && mso.containsKey('RecordTypeId')) {
        rtTypeId = mso.get('RecordTypeId');
      }
      // 20220420 lt OBSAP end
      obj.put('OwnerId', UserInfo.getUserId());
    }
    system.debug('RecordTypeId:' + rtTypeId);
    LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(
      rtTypeId,
      'Lead',
      'classic'
    );
    layoutSections = LayoutWrapperValue.layoutSections;
    List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
    Map<String, String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
    requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
    fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
    PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo(
      'Lead'
    );
    staticResource = JSON.serialize(piIntegration);
    staticResourceContact = JSON.serialize(
      PIHelper.getPIIntegrationInfo('Contact')
    );
    staticResourceInquiryForm = JSON.serialize(
      PIHelper.getPIIntegrationInfo('Inquiry_form__c')
    );
    //zhj MEBG新方案改造 2022-11-29 start
    staticResourceV2 = JSON.serialize(PIHelper.getPIIntegrationInfo('LeadV2'));
    //zhj MEBG新方案改造 2022-11-29 end
    encryptedAPIList = piIntegration.PIFields;
    sobjectPrefix = piIntegration.sobjectPrefix;
    layoutSectionsStr = JSON.serialize(layoutSections);
    AWSToSobjectEncryptedMap = new Map<String, String>();
    for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
      AWSToSobjectEncryptedMap.put(
        PIDetail.AWS_Field_API__c,
        PIDetail.SF_Field_API_Name__c
      );
    }
    //获取lookup字段
    List<String> VLookUpFields = new List<String>();
    for (LayoutDescriberHelper.LayoutSection ls : layoutSections) {
      for (LayoutDescriberHelper.LayoutField lf : ls.layoutFields) {
        if (lf.fieldAPI != '' && lf.fieldType == 'reference') {
          VLookUpFields.add(lf.fieldAPI);
        }
      }
    }
    VLookUpFieldsJson = Json.serialize(VLookUpFields);
  }

  global class Response {
    public String recordId { get; set; }
    public String message { get; set; }
    public String status { get; set; }
  }

  @RemoteAction
  global static Response saveLead(
    String leadJson,
    String transId,
    Boolean isNew
  ) {
    System.debug('Lead Info:' + JSON.serialize(leadJson));
    //1. Prepare the payload for  Lead
    Schema.SObjectType leadSchema = schemaMap.get(sobjectTypeValue);
    Map<String, Schema.SObjectField> fieldAPIToTypeMap = leadSchema.getDescribe()
      .fields.getMap();
    Map<String, Object> fieldValueMap = (Map<String, Object>) JSON.deserializeUntyped(
      leadJson
    );
    Lead leadInfo = new Lead();
    String status = 'success';
    Response resp = new Response();
    Savepoint sp = Database.setSavepoint();
    Boolean isClone = false;
    String rid = '';
    String awsDataId = '';
    try {
      //自定义格式转换
      for (String fieldAPI : fieldValueMap.keySet()) {
        system.debug('field API=' + fieldAPI);
        if (!fieldAPIToTypeMap.containskey(fieldAPI)) {
          continue;
        }
        Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI)
          .getDescribe()
          .getType();
        String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
        system.debug(
          'Field Type:' + fielddataType + ' field Value=' + fieldValue
        );
        if (String.valueOf(fielddataType) == 'DATE') {
          leadInfo.put(
            fieldAPI,
            (String.isBlank(fieldValue) || String.isEmpty(fieldValue))
              ? null
              : Date.valueOf(fieldValue.replace('/', '-'))
          );
        } else if (String.valueOf(fielddataType) == 'DATETIME') {
          if (String.isNotBlank(fieldValue) && fieldValue.contains('T')) {
            fieldValue = fieldValue.replace('T', ' ');
            leadInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
          } else {
            leadInfo.put(fieldAPI, null);
          }
        } else if (
          String.valueof(fielddataType) == 'CURRENCY' ||
          String.valueof(fielddataType) == 'PERCENT' ||
          String.valueOf(fielddataType) == 'Number' ||
          String.valueOf(fielddataType) == 'DOUBLE'
        ) {
          leadInfo.put(
            fieldAPI,
            (String.isBlank(fieldValue) || String.isEmpty(fieldValue))
              ? null
              : Decimal.valueOf(fieldValue.replace(',', ''))
          );
        } else if (String.valueof(fielddataType) == 'BOOLEAN') {
          leadInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
        } else {
          leadInfo.put(fieldAPI, fieldValue);
        }
      }

      //2. Save Record Process

      System.debug('abcde');
      awsDataId = (String) leadInfo.get('AWS_Data_Id__c');
      System.debug('awsDataId = ' + awsDataId);
      Lead[] leads = [SELECT id FROM Lead WHERE AWS_Data_Id__c = :awsDataId];

      if (!isNew) {
        isClone = leads.size() == 0;
      }
      System.debug('isClone---------' + isClone);
      //2022-6-10 yjk SWAG-CEY8GZ start
      if (leadInfo.Hospital_Name__c != null) {
        Account acc = [
          SELECT id, Hospital__c
          FROM Account
          WHERE id = :leadInfo.Hospital_Name__c
        ];
        leadInfo.hospital__c = acc.Hospital__c;
      }
      //2022-6-10 yjk SWAG-CEY8GZ end
      if (isNew || isClone) {
        System.debug('leadInfozhj = ' + leadInfo);
        if (!Test.isRunningTest()) {
          insert leadInfo;
        }
      } else {
        System.debug('into update');
        // String awsDataId = (String)leadInfo.get('AWS_Data_Id__c');
        // System.debug('awsDataId = ' + awsDataId);
        // Lead[] leads = [select id from Lead where AWS_Data_Id__c =:awsDataId];
        System.debug('leads[0].id = ' + leads[0].id);
        leadInfo.put('Id', leads[0].id); //For testing;
        if (!Test.isRunningTest()) {
          update leadInfo;
        }
      }
      rid = leadInfo.Id;
      PIHelper.saveTransLog(
        sobjectTypeValue,
        (String) leadInfo.get('AWS_Data_Id__c'),
        rid,
        transId,
        leadJson,
        status,
        ''
      );
      resp.recordId = leadInfo.Id;
      resp.message = '';
      resp.status = status;
      System.debug('resp from sfdx back-end' + resp);
      return resp;
    } catch (DmlException e) {
      Integer index = 0;
      System.debug(e.getNumDml());
      System.debug(e.getDmlFields(index));
      System.debug(e.getDmlId(index));
      System.debug(e.getDmlIndex(index));
      System.debug(e.getDmlMessage(index));
      System.debug(e.getDmlStatusCode(index));
      System.debug(e.getDmlType(index));
      system.debug(e.getMessage());
      system.debug(e.getStackTraceString());

      System.debug('into catch' + e.getMessage());
      Database.rollback(sp);
      resp.status = 'Exception';
      resp.message = '保存失败，原因:' + e.getDmlMessage(index);
      PIHelper.saveTransLog(
        sobjectTypeValue,
        (String) leadInfo.get('AWS_Data_Id__c'),
        rid,
        transId,
        leadJson,
        status,
        e.getMessage() + e.getStackTraceString()
      );
      return resp;
    } catch (Exception e) {
      System.debug('into catch' + e.getMessage());
      Database.rollback(sp);
      status = 'fail';
      PIHelper.saveTransLog(
        sobjectTypeValue,
        (String) leadInfo.get('AWS_Data_Id__c'),
        rid,
        transId,
        leadJson,
        status,
        e.getMessage()
      );
      resp.message = e.getMessage();
      resp.status = status;
      return resp;
    }
  }

  @RemoteAction
  global static String queryAccount(String accountTypes, String accountId) {
    System.debug('accountType=' + accountTypes);
    System.debug('accountId=' + accountId);
    List<Object> types = (List<Object>) JSON.deserializeUntyped(accountTypes);
    System.debug('types=' + types);
    String soql = 'select Id,Name,';
    for (Object t : types) {
      soql += (String) t + ',';
    }
    soql = soql.substring(0, soql.length() - 1);
    soql += ' from Account where id=\'' + accountId + '\'';
    System.debug('soql=' + soql);
    Sobject account = new Account();
    if (!Test.isRunningTest()) {
      account = Database.query(soql);
    } else {
      account.put('Id', '000000000000000');
    }

    Map<String, Map<String, String>> m = new Map<String, Map<String, String>>();

    System.debug('account=' + account);
    for (Object ty : types) {
      String t = (String) ty;
      if (account.get(t) != null || Test.isRunningTest()) {
        Sobject acc = new Account();
        if (Test.isRunningTest()) {
          acc.put('Id', '000000000000000');
          acc.put('Name', 'Name');
        } else {
          acc = Database.query(
            'select Id,Name from Account where id=\'' + account.get(t) + '\''
          );
        }
        Map<String, String> n = new Map<String, String>();
        n.put('Id', (String) acc.get('Id'));
        n.put('Name', (String) acc.get('Name'));
        m.put(t, n);
      }
    }
    // if (account.get('Hospital__c') != null){
    //     m.put('Hospital__c', (String)account.get('Hospital__c'));
    //     m.put('Hospital__r.Name', (String)account.get('Hospital__r.Name'));
    // }
    // if (account.get('Department_Class__c') != null){
    //     m.put('Department_Class__c', (String)account.get('Department_Class__c'));
    //     m.put('Department_Class__r.Name', (String)account.get('Department_Class__r.Name'));
    // }
    System.debug('m=' + m);
    return JSON.serialize(m);

    // return (String)account.get('Hospital__c');
  }

  public static Integer ControllerUtil() {
    Integer i = 0;
    return i;
  }
}
