/**************
 * 필드 공통 유효성 검사
 * watch, focus
 * form 필드는 반응형데이터 감지를 위해 ref 데이터 그대로 보내야한다
 **************/
export function useWatchFocusValidate(form, pageId) {
  const errMsgObj = ref({}) // 에러메시지 객체
  const ipv4Pattern = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
  const ipv6Pattern = /^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,7}:$|^(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}$|^(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}$|^(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}$|^[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,6}$|^:(?::[0-9a-fA-F]{1,4}){1,7}$|^::$|^::(?:[0-9a-fA-F]{1,4}:){1,7}$|^(?:[0-9a-fA-F]{1,4}:){1,7}:$|^(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}$|^(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}$|^(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}$|^[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,6}$|^:(?::[0-9a-fA-F]{1,4}){1,7}$|^::$|^::(?:[0-9a-fA-F]{1,4}:){1,7}$/;
  const portPattern = /^[1-9][0-9]{0,4}$/
  const idPattern = /^[a-zA-Z][a-zA-Z0-9._-]{4,19}$/
  let namePattern = /^[a-zA-Z가-힣]{2,10}$/
  //const emailPattern = /^(?=.{1,40}$)[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; // /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
  const emailPattern = /^(?=.{1,40}$)[A-Za-z0-9]([-_.]?[A-Za-z0-9])*@[A-Za-z0-9]([-_.]?[A-Za-z0-9])*\.[A-Za-z]{2,3}$/;
  /**
   * 마지막 글자 받침체크
   */
  function isSingleCharacter(text){
    var strGa = 44032 //가
    var strHih = 55203 //힣
    let lastStrCode = text.charCodeAt(text.length-1)

    if(lastStrCode < strGa || lastStrCode > strHih){
      return false //한글이 아닌 경우
    }
    return ((lastStrCode - strGa) % 28 == 0)
  }
  /**
   * 를/을 필터
   * @param {*} text 필터 문자열
   * @param {*} filter 필터 조사 neun : 는/은   leul :를/을   ro: 로/으로
   */
  function filterCheck(text, filter){
    if(filter == '은' || filter == '는') return text + (isSingleCharacter(text) ? '는' : '은')
    if(filter == '을' || filter == '를') return text + (isSingleCharacter(text) ? '를' : '을')
    if(filter == '으로' || filter == '로') return text + (isSingleCharacter(text) ? '로' : '으로')
    if(filter == '이' || filter == '가') return text + (isSingleCharacter(text) ? '가' : '이')
    if(filter == '과' || filter == '와') return text + (isSingleCharacter(text) ? '와' : '과')
  }
  /**
   * @param {*} str  원본 문자열
   * @param {*} target 문자열 교체 대상
   * @param {*} filter 필터 조사 neun : 는/은   leul :를/을   ro: 로/으로
   * @returns
   */
  function getChangedStr(str, target){
    if(!useUtil.isNull(str)){
      let result = ''
      if(str.includes(target)){
        let targetStr = str.substr(0, target.length+1)   //조사를 변경하기 위해 교체대상의 다음문자까지 가져오기.
        let target2Str = str.substr(0, target.length+2)
        let lastStr = targetStr.substr(-1)
        if(target2Str.substr(-2) === '으로'){
          lastStr = '으로'
          result = str.replace(target2Str, filterCheck(target, lastStr))
        }else{
          result = str.replace(targetStr, filterCheck(target, lastStr))
        }
      }else{
        result = str
      }
      return result
    }
  }
  /**
   * 에러메시지 리턴
   * @param {*} key 필드 키
   * @param {*} fieldName  필드 명
   * @param {*} regex  필드 정규식
   * @param {boolean} isRequire  필드 필수여부
   * @param {boolean} requiredUpdate 필드 필수 상태 업데이트 여부
   * @param {Object} params 나머지 항목
   * @returns 
   */
  function fnErrorHandler(key, fieldName, regex=null, {...params}) {
    const value = form.value[key]
    // 필수 필드 항목 변경 시 빈값인 경우 초기 메시지 노출x
    if (params.requiredUpdate && useUtil.isNull(value)){
      errMsgObj.value[key] = []
      return;
    }

    // 현재 필드 필수 && 빈 값
    if(params.fieldType === 'input') {
      if (params.isRequired && useUtil.isNull(value)) {
        errMsgObj.value[key] = [`${getChangedStr(fieldName + '을', fieldName)} 입력하세요.`];
        return;
      }
    }else if(params.fieldType === 'select') {
      if (params.isRequired && useUtil.isNull(value)) {
        errMsgObj.value[key] = [`${getChangedStr(fieldName + '을', fieldName)} 선택하세요.`];
        return;
      }
    }
    
    // 입력값이 있고
    // 정규식을 사용하는 경우
    if (!useUtil.isNull(value) && regex && regex.length > 0) {
      let isValid = null

      if(key === 'accountName') {
        const koreanRegex = /^[\uAC00-\uD7A3]+$/
        const englishRegex = /^[A-Za-z,\.\-'\s]+$/

        if (koreanRegex.test(value)) {
          regex[0] = /^[가-힣]{2,4}$/
          isValid = regex.some(pattern => pattern.test(value))
        } else if (englishRegex.test(value)) {
          regex[0] = /^[A-Za-z,\.\-'\s]{2,30}$/
          isValid = regex.some(pattern => pattern.test(value))
        } else {
          isValid = false
        }
      } else {
        isValid = regex.some(pattern => pattern.test(value))
      }
      
      switch (key) {
        case 'ipAddrWeb':
        case 'ipAddrWeb':
        case 'udcIpAddrSubs':
        case 'statusIpAddr':
        case 'usmMcmIpAddr':
        case 'fmAuditIpAddr':
          errMsgObj.value[key] = isValid ? [] : [`IPv4 또는 IPv6 형식으로 입력하세요.`];
          break;
        case 'portWeb':
        case 'udcPortSubs':
        case 'statusPort':
        case 'usmPsmPort':
        case 'usmMcmPort':
        case 'fmAuditPort':
          errMsgObj.value[key] = isValid && Number(value) >= 1 && Number(value) <= 65535 ? [] : [`1~65535 범위 내의 유효한 포트 번호를 입력하세요.`];
          break;

        case 'accountId':
          errMsgObj.value[key] = isValid ? [] : [`영문, 숫자 5자리 ~ 20자리 입력하세요.`]
          break;
        
        case 'accountName':
          errMsgObj.value[key] = isValid ? [] : [`한글 입력 시 2~4자리 , 영문 입력 시 띄어쓰기&특문 , . - ' 포함 2자리 ~ 30자리 입력하세요.`]
          break;
        
        case 'email':
          errMsgObj.value[key] = isValid ? [] : [`한글, 영문, 특수문자, 숫자, 공백 1자리 ~ 40자리 입력하세요.`]
          break;

        default:
          errMsgObj.value[key] = isValid ? [] : [`${getChangedStr(fieldName + '을', fieldName)} 올바른 형식으로 입력하세요.`];
          break;
      }

    } else {
      errMsgObj.value[key] = [];
    }
  }

  let fields = ref([])

  switch (pageId) {
    case 'tenantMgmt':
      fields.value = [
        { key: 'tenantName', name: '테넌트 이름', fieldType: 'input', isRequired: true},
        { key: 'corpNum', name: '사업자번호', fieldType: 'input', isRequired: true},
        { key: 'customerType', name: '고객 유형', fieldType: 'select', isRequired: true},
        { key: 'imsiPrefix', name: 'IMSI Prefix', fieldType: 'input', isRequired: true},
        { key: 'tenantCode', name: '테넌트 고유번호', fieldType: 'input', isRequired: true},
        { key: 'tenantAddress', name: '테넌트 주소', fieldType: 'input', isRequired: true},
      ]
      break;w
    case 'equipMgmt':
      fields.value = [
        // 시스템 기본 정보
        { key: 'emsName', name: '수집 시스템', fieldType: 'input', isRequired: true},
        { key: 'tenantName', name: '테넌트 이름', fieldType: 'select', isRequired: true},
        { key: 'systemType', name: '시스템 유형', fieldType: 'select', isRequired: true},
        { key: 'ipAddrWeb', name: 'WEB 접속 IP', regex: [ipv4Pattern, ipv6Pattern], fieldType: 'input', isRequired: true},
        { key: 'portWeb', name: 'WEB 접속 Port', regex: [portPattern], fieldType: 'input', isRequired: true},
        // 연동 설정 정보
        { key: 'udcIpAddrSubs', name: '가입자 관리 IP', regex: [ipv4Pattern, ipv6Pattern], fieldType: 'input', isRequired: false },
        { key: 'udcPortSubs', name: '가입자 관리 Port', regex: [portPattern], fieldType: 'input', isRequired: false },
        { key: 'usmPsmIpAddr', name: '통계 수집 IP (PSM)', regex: [ipv4Pattern, ipv6Pattern], fieldType: 'input', isRequired: false },
        { key: 'usmMcmIpAddr', name: '형상정보 수집 IP (MCM)', regex: [ipv4Pattern, ipv6Pattern], fieldType: 'input', isRequired: false },
        { key: 'usmPsmPort', name: '통계 수집 Port (PSM)', regex: [portPattern], fieldType: 'input', isRequired: false },
        { key: 'usmMcmPort', name: '형상정보 수집 Port (MCM)', regex: [portPattern], fieldType: 'input', isRequired: false },
        { key: 'statusIpAddr', name: '연결 확인 IP', regex: [ipv4Pattern, ipv6Pattern], fieldType: 'input', isRequired: false},
        { key: 'statusPort', name: '연결 확인 Port', regex: [portPattern], fieldType: 'input', isRequired: false},
        { key: 'usmFtpId', name: 'FTP ID', fieldType: 'input', isRequired: false},
        { key: 'usmFtpPassword', name: 'FTP PASSWORD', fieldType: 'input', isRequired: false},
        
        // 이벤트 AUDIT 연동 정보
        { key: 'fmAuditIpAddr', name: 'Audit IP', regex: [ipv4Pattern, ipv6Pattern], fieldType: 'input', isRequired: false },
        { key: 'fmAuditPort', name: 'Audit Port', regex: [portPattern], fieldType: 'input', isRequired: false },
        { key: 'fmAuditId', name: 'AUDIT ID', fieldType: 'input', isRequired: false},
        { key: 'fmAuditPassword', name: 'AUDIT 비밀번호', fieldType: 'input', isRequired: false},
        // 이벤트 TRAP 연동 정보
        { key: 'trapVersion', name: 'TRAP 버전', fieldType: 'input', isRequired: true},
        { key: 'trapV2CommunityName', name: 'TRAP V2 Community', fieldType: 'input', isRequired: true},
        { key: 'trapV3SecurityName', name: 'TRAP V3 Security 이름', fieldType: 'input', isRequired: true},
        { key: 'trapV3SecurityLevel', name: 'TRAP V3 Security 레벨', fieldType: 'input', isRequired: true},
        { key: 'trapV3AuthProtocol', name: 'TRAP V3 인증 프로토콜', fieldType: 'input', isRequired: true},
        { key: 'trapV3AuthPassword', name: 'TRAP V3 인증 비밀번호', fieldType: 'input', isRequired: true},
        { key: 'trapV3PrivProtocol', name: 'TRAP V3 암호화 프로토콜', fieldType: 'input', isRequired: true},
        { key: 'trapV3PrivPassword', name: 'TRAP V3 암호화 비밀번호', fieldType: 'input', isRequired: true}
      ]
      break;
    case 'neMgmt':
      fields.value = [
        { key: 'tenantName', name: '테넌트 이름', fieldType: 'select', isRequired: true},
        { key: 'neGroup', name: 'NE 그룹 이름', fieldType: 'select', isRequired: true},
        { key: 'neType', name: 'NE 유형', fieldType: 'select', isRequired: true},
        { key: 'neName', name: 'NE 이름', fieldType: 'input', isRequired: true},
        { key: 'emsName', name: '수집 시스템', fieldType: 'select', isRequired: true},
        { key: 'neAddress', name: '위치 정보', fieldType: 'input', isRequired: true},
        { key: 'neLocLatitude', name: '위도 값', fieldType: 'input', isRequired: true},
        { key: 'neLocLongitude', name: '경도 값', fieldType: 'input', isRequired: true},
      ]
      break;

    case 'neGroupMgmt':
      fields.value = [
        { key: 'tenantName', name: '테넌트 이름', fieldType: 'select', isRequired: true},
        { key: 'neGroup', name: 'NE 그룹 이름', fieldType: 'input', isRequired: true},
        { key: 'neGroupAddress', name: '위치 정보', fieldType: 'input', isRequired: true},
        { key: 'neGroupLocLatitude', name: '위도 값', fieldType: 'input', isRequired: true},
        { key: 'neGroupLocLongitude', name: '경도 값', fieldType: 'input', isRequired: true},
      ]
      break;

    case 'userMgmt':
      fields.value = [
        { key: 'tenantName', name: '테넌트 이름', fieldType: 'select', isRequired: true},
        { key: 'imsi2', name: 'IMSI', fieldType: 'input', isRequired: true},
        { key: 'msisdns', name: 'MSISDN', fieldType: 'input', isRequired: true},
        { key: 'skey', name: 'SKEY', fieldType: 'input', isRequired: true},
        { key: 'opc', name: 'OPC', fieldType: 'input', isRequired: true},
        { key: 'uplink', name: 'UE AMBR Uplink', fieldType: 'input', isRequired: true},
        { key: 'downlink', name: 'UE AMBR Downlink', fieldType: 'input', isRequired: true},
        { key: 'singleNssais', name: 'Single Nssai List', fieldType: 'input', isRequired: true},
        { key: 'defaultNssais', name: 'Default Nssai List', fieldType: 'input', isRequired: true},
      ]
      break;

    case 'accountMgmt':
      fields.value = [
        { key: 'accountId', name: '계정ID', regex: [idPattern], fieldType: 'input', isRequired: true},
        { key: 'accountName', name: '계정이름', regex: [namePattern], fieldType: 'input', isRequired: true},
        { key: 'email', name: '이메일 주소', regex: [emailPattern], fieldType: 'input', isRequired: true},
        { key: 'phoneNumber', name: '휴대폰번호', fieldType: 'input', isRequired: true},
      ]
      break;
    case 'termsMgmt':
      fields.value = []
      break;
    case 'connectSetMgmtTab4':
      fields.value = [
        { key: 'ipAddr', name: 'IP', regex: [ipv4Pattern], fieldType: 'input', isRequired: true}
      ]
      break;
    default:
      fields.value = []
      break;
  }
  fields.value.forEach((item) => {
    watch(() => form.value[item.key], () => {
      fnErrorHandler(item.key, item.name, item.regex, {isRequired: item.isRequired, fieldType: item.fieldType})
    })
  })

  // 필수항목 변경 사항 있을 때 업데이트
  function fnDataUpdate(requireFields){
    fields.value.forEach((item) => {
      item.isRequired = requireFields.includes(item.key)
      // 모든 항목 재검사
      fnErrorHandler(item.key, item.name, item.regex, { isRequired: item.isRequire, requiredUpdate:true, fieldType: item.fieldType})

      watch(() => form.value[item.key], () => {
        fnErrorHandler(item.key, item.name, item.regex, {isRequired: item.isRequired, fieldType: item.fieldType})
      })
    })
  }
  /**
   * 포커스 시 유효성 검사
   * @param {*} key 필드 키
   * @param {*} fieldName 필드이름
   * @param {*} isRequired 필드필수여부
   */
  function fnFocusValidateField(key, fieldName, {...params}) {
    let ipKeys = ['ipAddrWeb', 'udcIpAddrSubs', 'usmPsmIpAddr', 'usmMcmIpAddr', 'statusIpAddr', 'ipAddr', 'fmAuditIpAddr']
    let portKeys = ['portWeb', 'udcPortSubs', 'statusPort', 'usmMcmPort', 'usmPsmPort', 'fmAuditPort']
    let idKeys = ['accountId']
    let nameKeys = ['accountName']

    let regex = []
    if(ipKeys.includes(key)) regex = [ipv4Pattern, ipv6Pattern]
    else if(portKeys.includes(key)) regex = [portPattern]
    else if(idKeys.includes(key)) regex = [idPattern]
    else if(nameKeys.includes(key)) regex = [namePattern]
    else if(key == 'email') regex = [emailPattern]

    fnErrorHandler(key, fieldName, regex, {...params})
  }

  return  {errMsgObj, fnFocusValidateField, fnDataUpdate}
}