import { NativeModules, Platform } from 'react-native'
import I18n from '../i18n/index'
import { formatNumber, openDownloadFile } from 'api/native'
import dayjs from 'dayjs'
import RNFetchBlob from 'rn-fetch-blob'
import { cloneDeep, isEqual } from 'lodash'
import { Dialog, Utils } from 'tuya-panel-kit'
import {GlobalParams} from "../models/GlobalParams";

const { toFixedString } = Utils.NumberUtils

export const loopsText = [
  I18n.getLang('timeschedule_add_schedule_weekday7_text'),
  I18n.getLang('timeschedule_add_schedule_weekday1_text'),
  I18n.getLang('timeschedule_add_schedule_weekday2_text'),
  I18n.getLang('timeschedule_add_schedule_weekday3_text'),
  I18n.getLang('timeschedule_add_schedule_weekday4_text'),
  I18n.getLang('timeschedule_add_schedule_weekday5_text'),
  I18n.getLang('timeschedule_add_schedule_weekday6_text'),
]

export const loopText = (loop, time = '') => {
  let isToday = true
  if (time) {
    const currentTime = dayjs()
    const targetTime = dayjs().set('hour', parseInt(time.split(':')[0])).set('minute', parseInt(time.split(':')[1]));
    const isBeforeCurrentTime = targetTime.isBefore(currentTime)
    isToday = !isBeforeCurrentTime
  }
  const loopStrArray = loopsText.filter((_item, index) => Number(loop[index]) === 1)
  return loopStrArray.length === 0 ? (I18n.getLang(isToday ? 'motion_detection_time_schedule_notifications_field_weekdays_text2' : 'motion_detection_time_schedule_notifications_field_weekdays_text3')) : loopStrArray.length === 7 ? I18n.getLang('motion_detection_time_schedule_notifications_field_weekdays_text4') : loopStrArray.join(' ')
}

const tommorrow = () => {
  const text = I18n.getLang('feature_summary_frequency_txt_2').split(' ')
  return text?.length > 0 && text[text.length - 1] || ''
}

export const loopTommorrowText = (loop, isTommorrow) => {
  const loopStrArray = loopsText.filter((_item, index) => loop[index] === 1)
  return loopStrArray.length == 7 ? (I18n.getLang('motion_detection_time_schedule_notifications_field_weekdays_text4') + (isTommorrow && ` ${tommorrow()}` || '')) :
    (loopStrArray.join(' ') && `${I18n.formatValue('timeschedule_add_schedule_text', loopStrArray.join(' '))} ${isTommorrow && `${tommorrow()}` || ''}` ||
      I18n.getLang(isTommorrow && 'feature_summary_frequency_txt_2' || 'motion_detection_time_schedule_notifications_field_weekdays_text2'))
}

export const toFixed = (str, count) => {
  return `${'0'.repeat(count)}${str}`.slice(-1 * count)
}

export function getArray(arr, size) {  // size=5，要分割的长度
  const arrNum = Math.ceil(arr.length / size) // Math.ceil()向上取整的方法，用来计算拆分后数组的长度
  let index = 0 // 定义初始索引
  let resIndex = 0 // 用来保存每次拆分的长度
  const result: string[] = []
  while (index < arrNum) {
    result[index] = arr.slice(resIndex, size + resIndex)
    resIndex += size
    index++
  }
  return result
}

export function getWeek(weekString) {
  const s = parseInt(weekString, 16).toString(2).padStart(8, '0')
  const array = s.split('').map(item => parseInt(item)).reverse()
  array.pop()
  return array
}

/**
 * 按位分割字符串
 * @param {*} str 要分割的字符串
 * @param {*} step 按多少位分割
 * @returns ['','',...]
 */
export function spliceByStep(str: string, step: number): string[] {
  let res: string[] = []
  for (let i = 0; i < str.length; i += step) {
    res.push(str.substr(i, step))
  }
  return res
}

export function hex2Int(hex: string): number {
  return parseInt(hex, 16)
}

let defaultLocale = 'en'
if (Platform.OS === 'ios') {
  defaultLocale =
    Platform.OS === 'ios'
      ? NativeModules.SettingsManager.settings.AppleLocale
      : NativeModules.SettingsManager.settings.AppleLanguages[0]
} else if (Platform.OS === 'android') {
  defaultLocale = NativeModules.I18nManager.localeIdentifier
}

// 德国数字格式化
export const localeNumber = (v: number | string, fixed?: number, showGroup?: boolean) => {
  const mFixed = fixed ?? 2
  const n = isNaN(Number(v)) ? 0 : Number(v)
  try {
    if (Platform.OS === 'android') return formatNumber(n, mFixed, showGroup)
    let local = defaultLocale
    if (defaultLocale !== 'pt_BR' && defaultLocale !== 'pt-BR') {
      local = defaultLocale.split('_')[0]
    }
    return new Intl.NumberFormat(local, {
      useGrouping: showGroup !== undefined ? showGroup : true,
      maximumFractionDigits: mFixed
    }).format(n)
  } catch (_) {
    return n === 0 ? n : n.toFixed(mFixed)
  }
}

// 转换成国际数字
export const exchangeNumber = (v: number | string) => {
  return v.toString().replace(/[\,]/g, '.')
}

/**
 * 判断数字精度是否匹配
 * @param num
 * @param precision
 */
export const isPrecisionValid = (num: number | string, precision: number): boolean => {
  const numStr = num.toString()
  const index = numStr.indexOf('.')
  const decimalPlaces = index != -1 ? numStr.length - index - 1 : 0
  return decimalPlaces <= precision
}

export const exportCsvFile = (headers: any[], values: any[][], functionName: string = '') => {
  const data = [
    headers,
    ...values,
  ]
  const timestamp = dayjs().format('YYYYMMDDHHmmss')

  // Excel默认并不是以UTF-8来打开文件，所以在csv开头加入BOM，告诉Excel文件使用utf-8的编码方式
  const BOM = "\uFEFF";
  // 将CSV数据转换为CSV格式的字符串
  const csvData = data.map(row => row.join(','))

  // 创建 CSV 文件内容
  const csvContent = csvData.join('\n')

  // 定义文件保存路径
  const documentsPath = RNFetchBlob.fs.dirs.DocumentDir
  const filePath = Platform.OS === 'android' ? RNFetchBlob.fs.dirs.DownloadDir + `/${functionName}${timestamp}.csv` : `${documentsPath}/${functionName}${timestamp}.csv`
  RNFetchBlob.fs.writeFile(filePath, BOM + csvContent, 'utf8')
    .then(() => {
      openDownloadFile(filePath)
    })
    .catch(error => {
      console.error('导出 CSV 文件时出现错误：', error)
    })
}

// 导出文件
export const exportFile = (list, priceStr, priceUnit) => {
  const price = isNaN(Number(priceStr)) ? 0 : Number(priceStr)
  const value = list?.map(item => {
    return [item?.key, item?.value, price * item?.value]
  })
  const data = [
    ['Date', `${I18n.getLang('consumption_data_annual_bar_chart_system_back_text')} (kWh)`,`Price(${priceUnit})`],
    ...value,
  ]
  const timestamp = dayjs().format('YYYYMMDDHHmmss')

  // Excel默认并不是以UTF-8来打开文件，所以在csv开头加入BOM，告诉Excel文件使用utf-8的编码方式
  const BOM = "\uFEFF";
  // 将CSV数据转换为CSV格式的字符串
  const csvData = data.map(row => row.join(','))

  // 创建 CSV 文件内容
  const csvContent = csvData.join('\n')

  // 定义文件保存路径
  const documentsPath = RNFetchBlob.fs.dirs.DocumentDir
  const filePath = Platform.OS === 'android' ? RNFetchBlob.fs.dirs.DownloadDir + `/energyConsumption${timestamp}.csv` : `${documentsPath}/energyConsumption${timestamp}.csv`
  RNFetchBlob.fs.writeFile(filePath, BOM + csvContent, 'utf8')
    .then(() => {
      openDownloadFile(filePath)
    })
    .catch(error => {
      console.error('导出 CSV 文件时出现错误：', error)
    })
}

export const exportHistoryFile = (list) => {
  const value = list?.map(item => {
    return item?.actions?.map(val => {
      return [val?.date, val?.time, val?.action, tagTitle[val?.dpId - 1]]
    })
  })
  const data = [
    ['Date', 'Time', 'Status', 'Jack'],
    ...value?.flat(),
  ]
  const timestamp = dayjs().format('YYYYMMDDHHmmss')

  // 将CSV数据转换为CSV格式的字符串
  const csvData = data.map(row => row.join(','))

  // 创建 CSV 文件内容
  const csvContent = csvData.join('\n')

  // 定义文件保存路径
  const documentsPath = RNFetchBlob.fs.dirs.DocumentDir
  const filePath = Platform.OS === 'android' ? RNFetchBlob.fs.dirs.DownloadDir + `/history${timestamp}.csv` : `${documentsPath}/history${timestamp}.csv`
  RNFetchBlob.fs.writeFile(filePath, csvContent, 'utf8')
    .then(() => {
      openDownloadFile(filePath)
    })
    .catch(error => {
      console.error('导出 CSV 文件时出现错误：', error)
    })
}

//月份格式化
export const monthFormat = (v: number | string) => {
  const monthText = [
    I18n.getLang('consumption_data_field4_month1_value_text'),
    I18n.getLang('consumption_data_field4_month2_value_text'),
    I18n.getLang('consumption_data_field4_month3_value_text'),
    I18n.getLang('consumption_data_field4_month4_value_text'),
    I18n.getLang('consumption_data_field4_month5_value_text'),
    I18n.getLang('consumption_data_field4_month6_value_text'),
    I18n.getLang('consumption_data_field4_month7_value_text'),
    I18n.getLang('consumption_data_field4_month8_value_text'),
    I18n.getLang('consumption_data_field4_month9_value_text'),
    I18n.getLang('consumption_data_field4_month10_value_text'),
    I18n.getLang('consumption_data_field4_month11_value_text'),
    I18n.getLang('consumption_data_field4_month12_value_text'),
  ]
  return monthText[Number(v) - 1]
}

//月份格式化
export const monthFormatShort = (v: number | string) => {
  const monthText = [
    I18n.getLang('month_short_january'),
    I18n.getLang('month_short_february'),
    I18n.getLang('month_short_march'),
    I18n.getLang('month_short_april'),
    I18n.getLang('month_short_may'),
    I18n.getLang('month_short_june'),
    I18n.getLang('month_short_july'),
    I18n.getLang('month_short_august'),
    I18n.getLang('month_short_september'),
    I18n.getLang('month_short_october'),
    I18n.getLang('month_short_november'),
    I18n.getLang('month_short_december'),
  ]
  return monthText[Number(v) - 1]
}

export const tagTitle = [
  I18n.getLang('feature_summary_action_component_6'),
  I18n.getLang('feature_summary_action_component_7'),
  I18n.getLang('feature_summary_action_component_8'),
  I18n.getLang('feature_summary_action_component_9'),
]

export function isTimeSpanValid(timeData) {
  const startTime = timeData.startTime
  const endTime = timeData.endTime
  // 将小时和分钟转换为分钟总数
  const startMinutes = parseInt(startTime[0]) * 60 + parseInt(startTime[1])
  const endMinutes = parseInt(endTime[0]) * 60 + parseInt(endTime[1])
  // 判断是否跨天，如果开始时间大于结束时间，则跨天
  if (startMinutes > endMinutes) {
    // 计算跨天情况下的时间间隔
    const overnightInterval = 1440 - startMinutes + endMinutes
    return overnightInterval
  } else {
    // 计算非跨天情况下的时间间隔
    const interval = endMinutes - startMinutes
    return interval
  }
}

export function modifyPopup(beforeValue: object, editValue: object) {
  return !isEqual(beforeValue, editValue)
}

// dialog
interface DialogProps {
  method: 'alert' | 'confirm'
  title: string
  showCancelText?: boolean
  showConfirmText?: boolean
  cancelText?: string
  confirmText?: string
  subTitle?: string
  onConfirm: (data: any, args: { close: () => void }) => void
  onCancel?: () => void
}

// 获取文本的默认值
const getText = (text: string | undefined, defaultText: string | undefined, show: boolean) => {
  return show ? text || defaultText || '' : '';
};

export function showDialog(props: DialogProps) {
  const {
    method,
    showCancelText = true,
    showConfirmText = true,
    title,
    cancelText,
    confirmText,
    subTitle,
    onConfirm,
    onCancel
  } = props

  const defDialogProps = {
    title,
    confirmText: getText(confirmText, I18n.getLang('conflict_dialog_save_item_fixedtimecycle_answer_yes_text'), showConfirmText),
    cancelText: getText(cancelText, I18n.getLang('conflict_dialog_save_item_fixedtimecycle_answer_no_text'), showCancelText),
    subTitle,
    onConfirm,
    motionConfig: {
      hideDuration: 0,
      showDuration: 100
    }
  }
  const cancelProps = onCancel ? { onCancel } : {};
  return (
    method === 'confirm' ? Dialog.confirm({ ...defDialogProps, ...cancelProps }) : Dialog.alert(defDialogProps)
  )
}

export function formatHourAndMinute(hour: number, minute: number, is24Hour: boolean = true) {
  const time = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`;
  return is24Hour ? time : convertTo12HourFormat(time)
}

export function convertTo12HourFormat(time24: string) {
  // 将字符串按照':'分割成小时和分钟
  var timeParts = time24.split(':');
  var hours = parseInt(timeParts[0]);
  var minutes = parseInt(timeParts[1]);

  // 检查小时是否大于等于12
  var suffix = (hours >= 12) ? I18n.getLang('manage_user_calendar_label_pm') : I18n.getLang('manage_user_calendar_label_am');

  // 如果小时大于12，将小时减去12
  hours = (hours > 12) ? hours - 12 : hours;

  // 如果小时为0，则表示为12小时制中的12点
  hours = (hours == 0) ? 12 : hours;

  // 返回转换后的时间字符串
  return suffix + ' ' + hours + ':' + (minutes < 10 ? '0' : '') + minutes;
}

// 将分钟数转换为12小时制时间
export function convertMinutesTo12HourFormat(minutes: number, is24: boolean) {
  let hours = Math.floor(minutes / 60); // 获取小时数
  const mins = minutes % 60; // 获取剩余分钟数
  if(is24){
    return `${toFixedString(hours, 2)}:${toFixedString(mins, 2)}`
  }
  // 构造12小时制时间字符串
  const suffix = (hours >= 12) ? I18n.getLang('manage_user_calendar_label_pm') : I18n.getLang('manage_user_calendar_label_am');
  // 检查小时数是否大于12，并调整
  if (hours > 12) {
    hours -= 12;
  }
  hours = (hours == 0) ? 12 : hours; // 处理午夜0点为12小时制的12点
  const time12Hour = suffix + ' ' + hours + ':' + (mins < 10 ? '0' : '') + mins;

  return time12Hour;
}

export function getGlobalParamsDp(key: string) {
  return GlobalParams.dpSchemaMap[key] && GlobalParams.dpSchemaMap[key].dp.toString()
}

export function isSupportFunctions(...keys: string[]) {
  return keys.every(key => key in GlobalParams.dpSchemaMap)
}

// 判断时间毫秒数在这一天中多少分钟
export function getMinutesOfTheDay(milliseconds: number) {
  // 将给定的毫秒数转换为 Date 对象
  const date = new Date(milliseconds);

  // 获取该日期的起始时间（午夜 00:00:00）的时间戳（毫秒）
  const startOfDay = new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();

  // 计算给定毫秒数与当天起始时间的差值（毫秒）
  const differenceMillis = milliseconds - startOfDay;

  // 将差值转换为分钟数
  const minutes = Math.floor(differenceMillis / 60000);

  return minutes;
}

export function getIsClosed(item: {weeks: number[], settingTime: number, endTime: number}){
  const isOnce = item?.weeks?.every(w => w === 0)
  let undone = true
  if(isOnce && item.settingTime){
    const setting = new Date(item.settingTime).toDateString()
    const settingMin = getMinutesOfTheDay(item.settingTime)
    const current = new Date().toDateString()
    const currentMin = getMinutesOfTheDay(new Date().getTime())
    if(setting !== current){
      undone = false
    }else{
      if(settingMin < item.endTime && currentMin > item.endTime){
        undone = false
      }
    }
  }
  return undone
}

type AsyncFunction<T extends any[], R> = (...args: T) => Promise<R>

export function withErrorHandling<T extends any[], R>(
  asyncFn: AsyncFunction<T, R>
): AsyncFunction<T, R> {
  return async (...args: T): Promise<R> => {
    try {
      return await asyncFn(...args);
    } catch (error) {
      console.error(`Error in ${asyncFn.name || 'anonymous function'}:`, error)
      // 可以在这里添加更多的错误处理逻辑，比如发送到错误跟踪服务
      throw error // 重新抛出错误，以便调用者可以选择进一步处理
    }
  }
}

export function isConflictTask(task1, task2) {
  // 检查两个时间段是否有重叠
  function checkOverlap(start1, end1, start2, end2) {
    return (start1 <= end2 && start2 <= end1);
  }
  const cloneTask1 = cloneDeep(task1)
  const cloneTask2 = cloneDeep(task2)
  const weekDay = dayjs().day()
  if (cloneTask1.weeks.every(w => Number(w) === 0)){
    cloneTask1.weeks[weekDay] = 1
  }
  if (cloneTask2.weeks.every(w => Number(w) === 0)){
    cloneTask2.weeks[weekDay] = 1
  }
  // 检查一周的每一天
  for (let i = 0; i < 7; i++) {
    // 如果 task1 在该天执行
    if (Number(cloneTask1.weeks[i]) === 1) {
      const [start1, end1] = [cloneTask1.startTime, cloneTask1.endTime];
      const task1CrossDay = start1 > end1;

      // 如果 task2 在该天或跨天执行
      for (let j = 0; j < 7; j++) {
        if (Number(cloneTask2.weeks[j]) === 1) {
          const [start2, end2] = [cloneTask2.startTime, cloneTask2.endTime];
          const task2CrossDay = start2 > end2;
          // 检查当前天是否有重叠
          if (i === j && checkOverlap(start1, end1, start2, end2)) {
            return true;
          }

          // 检查 task1 跨天并延伸到次日的情况
          if (task1CrossDay && ((i + 1) % 7 === j) && checkOverlap(0, end1, start2, end2)) {
            return true;
          }

          // 检查 task2 跨天并延伸到次日的情况
          if (task2CrossDay && ((j + 1) % 7 === i) && checkOverlap(0, end2, start1, end1)) {
            return true;
          }
        }
      }
    }
  }
  return false;
}
