package common

import (
	"errors"
	"fmt"
	"math"
	"strconv"
	"strings"
	"time"

	"git.listensoft.net/tool/jspkit/logger"
	"github.com/go-rod/rod"
)

// GetTimestamp 时间戳
func GetTimestamp(n int) string {
	unixNano := strconv.FormatInt(time.Now().UnixNano(), 10)
	return unixNano[0:n]
}

// BeginOrEedPeriod 获取当前账期第一天日期和最后一天日期 参数e 当前账期 201912  参数status 1获取月初日期 2获取月末日期
func BeginOrEedPeriod(e string, status int) string {
	nian := StrToInt(e[0 : len(e)-2])
	yue := StrToInt(e[4 : len(e)-0])
	if nian%100 == 0 {
		if nian%400 == 0 {
			return leapYear(nian, yue, status, 1)
		} else {
			return leapYear(nian, yue, status, 2)
		}
	} else {
		if nian%4 == 0 {
			return leapYear(nian, yue, status, 1)
		} else {
			return leapYear(nian, yue, status, 2)
		}
	}
}

func leapYear(nian int, yue int, status int, yearStatus int) string {
	if yue == 1 || yue == 3 || yue == 5 || yue == 7 || yue == 8 || yue == 10 || yue == 12 {
		yues := IntToStr(yue)
		if yue < 10 {
			yues = "0" + yues
		}
		if status == 1 {
			return IntToStr(nian) + "-" + yues + "-01"
		} else {
			return IntToStr(nian) + "-" + yues + "-31"
		}

	} else if yue == 4 || yue == 6 || yue == 9 || yue == 11 {
		yues := IntToStr(yue)
		if yue < 10 {
			yues = "0" + yues
		}
		if status == 1 {
			return IntToStr(nian) + "-" + yues + "-01"
		} else {
			return IntToStr(nian) + "-" + yues + "-30"
		}
	} else {
		yues := IntToStr(yue)
		if yue < 10 {
			yues = "0" + yues
		}
		if status == 1 {
			return IntToStr(nian) + "-" + yues + "-01"
		} else {
			if yearStatus == 1 {
				return IntToStr(nian) + "-" + yues + "-29"
			} else {
				return IntToStr(nian) + "-" + yues + "-28"
			}

		}
	}
}

// GetBeginAndEndTime 获取本月开始和结束的时间
func GetBeginAndEndTime(period string) (string, string) {
	loc, _ := time.LoadLocation("Local")
	the_time, _ := time.ParseInLocation("200601", period, loc)
	year, month, _ := the_time.Date()
	thisMonth := time.Date(year, month, 1, 0, 0, 0, 0, time.Local)
	start := thisMonth.AddDate(0, 0, 0).Format("2006-01-02")
	end := thisMonth.AddDate(0, 1, -1).Format("2006-01-02")
	return start, end
}

// 根据本账期查询上个账期 例如 201812 -> 201811
func LastPeriod(startAccountPeriod string) string {
	if len(startAccountPeriod) < 6 {
		return ""
	}
	qian4 := startAccountPeriod[0 : len(startAccountPeriod)-2]
	hou2 := startAccountPeriod[4 : len(startAccountPeriod)-0]
	newPeriod := ""
	if StrToInt(hou2) == 1 {
		newPeriod = IntToStr(StrToInt(qian4)-1) + "12"
	} else {
		newPeriod = IntToStr(StrToInt(startAccountPeriod) - 1)
	}
	return newPeriod
}

func GetCurrentDate() string {
	tm := time.Unix(time.Now().Unix(), 0)
	currentYear, currentMonth, _ := tm.Date()
	currentLocation := tm.Location()
	firstOfMonth := time.Date(currentYear, currentMonth, 10, 0, 0, 0, 0, currentLocation)
	period := firstOfMonth.AddDate(0, 0, 0).Format("200601") // 当前日期
	return period
}

// 获取当前账期
func GetCurrentPeriod() string { //仅本期报税使用
	tm := time.Unix(time.Now().Unix(), 0)
	currentYear, currentMonth, _ := tm.Date()
	currentLocation := tm.Location()
	firstOfMonth := time.Date(currentYear, currentMonth, 10, 0, 0, 0, 0, currentLocation)
	period := firstOfMonth.AddDate(0, -1, 0).Format("200601") // 当前账期
	return period
}

func GetPeriod(f int) string {
	t := time.Now()
	year, month, _ := t.Date()
	thisMonthFirstDay := time.Date(year, month, 1, 1, 1, 1, 1, t.Location())
	a := thisMonthFirstDay.AddDate(0, f, 0).Format("200601")
	return a
}

func GetNextPeriod(period string) string {
	currentTime, _ := time.Parse("200601", period)
	next := currentTime.AddDate(0, 1, 0)
	return next.Format("200601")
}

// 传入账期区间返回中间的月份 fmtData 1 - 返回"200601" 2 -返回"2006-01"
func PeriodBetweenStartEnd(start, end string, fmtData int) (err error, periods []string) {
	if start == "" || end == "" {
		return errors.New("时间错误"), periods
	}
	var startTime time.Time
	var endTime time.Time

	//格式化时间
	if strings.Contains(start, "-") && strings.Contains(end, "-") {
		timeTemplate := "2006-01"
		startTime, _ = time.ParseInLocation(timeTemplate, start, time.Local)
		endTime, _ = time.ParseInLocation(timeTemplate, end, time.Local)
	} else if !strings.Contains(start, "-") && !strings.Contains(end, "-") {
		timeTemplate := "200601"
		startTime, _ = time.ParseInLocation(timeTemplate, start, time.Local)
		endTime, _ = time.ParseInLocation(timeTemplate, end, time.Local)
	} else {
		return errors.New("传入参数格式错误"), periods
	}

	//结束日期包含本月
	endTime = endTime.AddDate(0, 1, 0)

	//判断结束时间在开始时间之后
	if !endTime.After(startTime) {
		return errors.New("结束时间在开始时间之前"), periods
	}

	for {
		//如果时间相等 则跳出
		if startTime.Equal(endTime) {
			break
		}
		if fmtData == 1 {
			periods = append(periods, startTime.Format("200601"))
		}
		if fmtData == 2 {
			periods = append(periods, startTime.Format("2006-01"))
		}
		startTime = startTime.AddDate(0, 1, 0)
	}
	return
}

// 传入period 返回 最后一天 201902-》
func GetLastDay(period string) time.Time {
	//获取本地location
	toBeCharge := period                                            //待转化为时间戳的字符串 注意 这里的小时和分钟还要秒必须写 因为是跟着模板走的 修改模板的话也可以不写
	timeLayout := "200601"                                          //转化所需模板
	loc, _ := time.LoadLocation("Local")                            //重要：获取时区
	theTime, _ := time.ParseInLocation(timeLayout, toBeCharge, loc) //使用模板在对应时区转化为time.time类型
	sr := theTime.Unix()                                            //转化为时间戳 类型是int64
	//logger.Info(theTime)                                            //打印输出theTime 2015-01-01 15:15:00 +0800 CST
	//logger.Info(sr)                                                 //打印输出时间戳 1420041600

	tm := time.Unix(sr, 0)
	currentYear, currentMonth, _ := tm.Date()
	currentLocation := tm.Location()
	firstOfMonth := time.Date(currentYear, currentMonth, 1, 0, 0, 0, 0, currentLocation)
	lastOfMonth := firstOfMonth.AddDate(0, 1, -1)
	//return firstOfMonth.Format("2006-01-02"), lastOfMonth.Format("2006-01-02")
	logger.Info(firstOfMonth, lastOfMonth)
	return lastOfMonth
}

// 传入period 返回 第一天 201902-》
func GetFirstDay(period string) time.Time {
	//获取本地location
	toBeCharge := period                                            //待转化为时间戳的字符串 注意 这里的小时和分钟还要秒必须写 因为是跟着模板走的 修改模板的话也可以不写
	timeLayout := "200601"                                          //转化所需模板
	loc, _ := time.LoadLocation("Local")                            //重要：获取时区
	theTime, _ := time.ParseInLocation(timeLayout, toBeCharge, loc) //使用模板在对应时区转化为time.time类型
	sr := theTime.Unix()                                            //转化为时间戳 类型是int64
	//logger.Info(theTime)                                            //打印输出theTime 2015-01-01 15:15:00 +0800 CST
	//logger.Info(sr)                                                 //打印输出时间戳 1420041600

	tm := time.Unix(sr, 0)
	currentYear, currentMonth, _ := tm.Date()
	currentLocation := tm.Location()
	firstOfMonth := time.Date(currentYear, currentMonth, 1, 0, 0, 0, 0, currentLocation)
	lastOfMonth := firstOfMonth.AddDate(0, 1, -1)
	//return firstOfMonth.Format("2006-01-02"), lastOfMonth.Format("2006-01-02")
	logger.Info(firstOfMonth, lastOfMonth)
	return firstOfMonth
}

func GetPrevQuarterStartTimeAndEndTime(period string) (string, string) {
	quarterStart := ""
	quarterEnd := ""
	quarter := math.Ceil(StrToFloat(period[4:6])/3) - 1
	if quarter == 1 { //第一季度
		quarterStart = period[0:4] + "-01-01"
		quarterEnd = period[0:4] + "-03-31"
	}
	if quarter == 2 { //第二季度
		quarterStart = period[0:4] + "-04-01"
		quarterEnd = period[0:4] + "-06-30"
	}
	if quarter == 3 { //第三季度
		quarterStart = period[0:4] + "-07-01"
		quarterEnd = period[0:4] + "-09-30"
	}
	if quarter == 0 { //第四季度
		quarterStart = IntToStr(StrToInt(period[0:4])-1) + "-10-01"
		quarterEnd = IntToStr(StrToInt(period[0:4])-1) + "-12-31"
	}
	return quarterStart, quarterEnd
}

// 根据本账期查询上季度末账期 例如 201812 -> 201809
func LastJiDu(startAccountPeriod string) string {
	if len(startAccountPeriod) < 6 {
		return ""
	}
	qian4 := startAccountPeriod[0 : len(startAccountPeriod)-2]
	hou2 := startAccountPeriod[4 : len(startAccountPeriod)-0]
	newPeriod := ""
	if StrToInt(hou2) == 1 || StrToInt(hou2) == 2 || StrToInt(hou2) == 3 {
		newPeriod = IntToStr(StrToInt(qian4)-1) + "12"
	} else if StrToInt(hou2) == 4 || StrToInt(hou2) == 5 || StrToInt(hou2) == 6 {
		newPeriod = IntToStr(StrToInt(qian4)-0) + "03"
	} else if StrToInt(hou2) == 7 || StrToInt(hou2) == 8 || StrToInt(hou2) == 9 {
		newPeriod = IntToStr(StrToInt(qian4)-0) + "06"
	} else if StrToInt(hou2) == 10 || StrToInt(hou2) == 11 || StrToInt(hou2) == 12 {
		newPeriod = IntToStr(StrToInt(qian4)-0) + "09"
	}
	return newPeriod
}

// 根据本账期查询上个账期 例如 201812 -> 2018-11
func LastPeriod1(startAccountPeriod string) string {
	if len(startAccountPeriod) < 6 {
		return ""
	}
	qian4 := startAccountPeriod[0 : len(startAccountPeriod)-2]
	hou2 := startAccountPeriod[4 : len(startAccountPeriod)-0]
	newPeriod := ""
	if StrToInt(hou2) == 1 {
		newPeriod = IntToStr(StrToInt(qian4)-1) + "12"
	} else {
		newPeriod = IntToStr(StrToInt(startAccountPeriod) - 1)
	}
	return newPeriod[:4] + "-" + newPeriod[4:]
}

// GetLastBeginAndEndTime 获取上个账期的起止时间
func GetLastBeginAndEndTime(period string) (string, string) {
	lastP := getCurrentPeriod(period)
	return GetBeginAndEndTime(lastP)
}

// 获取上月
func getCurrentPeriod(period string) string {
	parse, _ := time.Parse(`200601`, period)
	period = parse.AddDate(0, -1, 0).Format("200601") // 获取上月
	return period
}

func GetFirstAndLastDayOfPeriod(period string) (string, string) {
	t, _ := time.Parse("200601", period)
	firstDay := t.AddDate(0, 0, 0)
	lastDay := t.AddDate(0, 1, -1)
	return firstDay.Format("2006-01-02"), lastDay.Format("2006-01-02")
}

// RFC3339     = "2006-01-02T15:04:05Z07:00"
const TimeFormat = "2006-01-02 15:04:05"

// DateFormatter 将YYYYMMDD格式改为YYYY-MM-DD格式
func DateFormatter(date string) string {
	if len(date) != 8 {
		return "" // 返回空字符串表示输入格式不正确
	}

	return fmt.Sprintf("%s-%s-%s", date[:4], date[4:6], date[6:])
}

// GetNextDateTime 获取传入日期的明天 0 点
func GetNextDateTime(d time.Time) time.Time {
	return time.Date(d.Year(), d.Month(), d.Day()+1, 0, 0, 0, 0, d.Location())
}

// 获取去年的第一天和最后一天
func GetLastYearFirstTimeAndEndTime() (string, string) {
	now := time.Now()
	logger.Info(now)
	currentYear, _, _ := now.Date()
	currentLocation := now.Location()
	logger.Info(currentLocation)
	firstOfYear := time.Date(currentYear-1, time.January, 1, 0, 0, 0, 0, currentLocation)
	lastOfYear := firstOfYear.AddDate(1, 0, -1)
	return firstOfYear.Format("2006-01-02"), lastOfYear.Format("2006-01-02")
}

// 获取今年的第一天和最后一天
func GetCurrentYearFirstTimeAndEndTime() (string, string) {
	now := time.Now()
	logger.Info(now)
	currentYear, _, _ := now.Date()
	currentLocation := now.Location()
	logger.Info(currentLocation)
	firstOfYear := time.Date(currentYear, time.January, 1, 0, 0, 0, 0, currentLocation)
	lastOfYear := firstOfYear.AddDate(1, 0, -1)
	return firstOfYear.Format("2006-01-02"), lastOfYear.Format("2006-01-02")
}

// 获取上个月的最后一天
func GetLastMonthLastDate() string {
	now := time.Now()
	firstOfMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.Local)
	return firstOfMonth.AddDate(0, 0, -1).Format(`2006-01-02`)
}

// 获取当月的最后一天
func GetCurMonthLastDate() string {
	now := time.Now()
	firstOfMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.Local)
	return firstOfMonth.AddDate(0, 1, -1).Format(`2006-01-02`)
}

// GetLastYear 获取上一年 202210 => 2021
func GetLastYear() string {
	now := time.Now()
	return now.AddDate(-1, 0, 0).Format(`2006`)
}

// 等待所有 iframe 中 xpath 对应的元素加载。
// 注意：加载失败 panic 的是税局卡顿错误。非税局采集任务不应使用该函数。
func WaitElementX5(page *rod.Page, xpath string) *rod.Element {
	return WaitElementXFoTimes(page, xpath, 5)
}

// 获取上一年的最后一天
func GetLastYearLastDate() string {
	now := time.Now()
	lastYear := now.AddDate(-1, 0, 0)
	lastDayOfLastYear := time.Date(lastYear.Year(), 12, 31, 0, 0, 0, 0, time.Local)
	return lastDayOfLastYear.Format(`2006-01-02`)
}

// 获取本账期开始和结束日期
func GetQuarterStartTimeAndEndTime(period string) (string, string) {
	quarterStart := ""
	quarterEnd := ""
	quarter := math.Ceil(StrToFloat(period[4:6])/3) - 1
	if quarter == 0 { //第一季度
		quarterStart = period[0:4] + "-01-01"
		quarterEnd = period[0:4] + "-03-31"
	}
	if quarter == 1 { //第二季度
		quarterStart = period[0:4] + "-04-01"
		quarterEnd = period[0:4] + "-06-30"
	}
	if quarter == 2 { //第三季度
		quarterStart = period[0:4] + "-07-01"
		quarterEnd = period[0:4] + "-09-30"
	}
	if quarter == 3 { //第四季度
		quarterStart = period[0:4] + "-10-01"
		quarterEnd = period[0:4] + "-12-31"
	}
	return quarterStart, quarterEnd
}

func GetCurrentPeriod3() string { //仅本期报税使用
	tm := time.Unix(time.Now().Unix(), 0)
	currentYear, currentMonth, _ := tm.Date()
	currentLocation := tm.Location()
	firstOfMonth := time.Date(currentYear, currentMonth, 10, 0, 0, 0, 0, currentLocation)
	period := firstOfMonth.AddDate(0, -1, 0).Format("2006-01") // 当前账期-1
	return period
}

func GetThisPrevQuarterStartTimeAndEndTimeNew(period string) (string, string) {
	quarterStart := ""
	quarterEnd := ""
	m := period[4:6]
	switch m {
	case "03":
		quarterStart = period[0:4] + "-01-01"
		quarterEnd = period[0:4] + "-03-31"
	case "06":
		quarterStart = period[0:4] + "-04-01"
		quarterEnd = period[0:4] + "-06-30"
	case "09":
		quarterStart = period[0:4] + "-07-01"
		quarterEnd = period[0:4] + "-09-30"
	case "12":
		quarterStart = IntToStr(StrToInt(period[0:4])) + "-10-01"
		quarterEnd = IntToStr(StrToInt(period[0:4])) + "-12-31"
	default:
		quarterStart, quarterEnd = GetBeginAndEndTime(period)
	}
	return quarterStart, quarterEnd
}

// 是否是季度报
func IsJdSb(period string) bool {
	if len(period) == 6 && (period[4:] == "03" || period[4:] == "06" || period[4:] == "09" || period[4:] == "12") {
		return true
	}
	return false
}

func GetMonthEnd(t time.Time) time.Time {
	return t.AddDate(0, 1, -t.Day())
}

func GetCurrentDate1() string {
	tm := time.Unix(time.Now().Unix(), 0)
	currentYear, currentMonth, _ := tm.Date()
	currentLocation := tm.Location()
	firstOfMonth := time.Date(currentYear, currentMonth, 10, 0, 0, 0, 0, currentLocation)
	period := firstOfMonth.AddDate(0, 0, 0).Format("2006-01") // 当前日期
	return period
}

// 获取本月开始和结束的时间
func GetBeginAndEndTime1(period string) (string, string) {
	loc, _ := time.LoadLocation("Local")
	the_time, _ := time.ParseInLocation("200601", period, loc)
	year, month, _ := the_time.Date()
	thisMonth := time.Date(year, month, 1, 0, 0, 0, 0, time.Local)
	start := thisMonth.AddDate(0, 0, 0).Format("2006-1-2")
	end := thisMonth.AddDate(0, 1, -1).Format("2006-1-2")
	return start, end
}

// 根据时间戳获取 月初 月末 0代表本月
func GetMonthBeginTimeAndEndTime(num int64) (string, string) {
	if num == 0 {
		num = time.Now().Unix()
	}
	tm := time.Unix(num, 0)
	currentYear, currentMonth, _ := tm.Date()
	currentLocation := tm.Location()
	firstOfMonth := time.Date(currentYear, currentMonth, 1, 0, 0, 0, 0, currentLocation)
	lastOfMonth := firstOfMonth.AddDate(0, 1, -1)
	return firstOfMonth.Format("2006-01-02"), lastOfMonth.Format("2006-01-02")
}

// 获取当前账期
func GetThisYearMonth() string {
	return time.Now().Format("2006-01")
}
