package db

import (
	"fmt"
	"github.com/jinzhu/copier"
	"gorm.io/gorm"
	"time"
	"video_data_copy/data"
)

func copyOrders(db *gorm.DB, timeNow time.Time) {
	order := &data.Orders{}
	start := timeNow.Format("2006-01-02 15:04:05")
	first := db.Debug().Where("create_time < ?", start).Order("create_time asc").First(order)
	if first.RowsAffected == 0 {
		fmt.Println("no orders data")
		return
	}

	deleteTime := order.CreateTime
	fmt.Println("copy orders from:", deleteTime)

	db.Debug().Where("create_time >= ?", deleteTime).Delete(&data.OrdersCopy1{})

	var totalCount int64 = 0
	db.Debug().Model(&data.Orders{}).Where("create_time >= ?", deleteTime).Count(&totalCount)

	_execOrders(db, start, 0, totalCount)

	db.Debug().Where("create_time < ?", start).Delete(&data.Orders{})
}

func _execOrders(db *gorm.DB, timeNow string, index int, totalCount int64) {
	var orders []*data.Orders

	db.Debug().Where("create_time < ?", timeNow).Limit(1000).Offset(index * 1000).Find(&orders)

	fmt.Printf("index: %d, timeNow: %s ,orders count: %d, totalCount: %d\n", index, timeNow, len(orders), totalCount)
	if len(orders) == 0 {
		return
	}

	var copyList []*data.OrdersCopy1
	for _, order := range orders {
		copyOrder := &data.OrdersCopy1{}
		CopyStruct(order, copyOrder)
		copyList = append(copyList, copyOrder)
	}

	db.Create(&copyList)

	//time.Sleep(1500 * time.Millisecond)

	_execOrders(db, timeNow, index+1, totalCount)
}

func copyPayDetails(db *gorm.DB, timeNow time.Time) {
	detail := &data.PayDetails{}
	start := timeNow.Format("2006-01-02 15:04:05")
	first := db.Model(detail).Where("create_time < ?", start).Order("create_time asc").First(detail)
	if first.RowsAffected == 0 {
		fmt.Println("no pay_details data")
		return
	}

	deleteTime := detail.CreateTime

	db.Debug().Where("create_time >= ?", deleteTime).Delete(&data.PayDetailsCopy1{})

	var totalCount int64 = 0
	db.Debug().Model(&data.PayDetails{}).Where("create_time >= ?", deleteTime).Count(&totalCount)

	_execPayDetails(db, start, 0, totalCount)

	db.Debug().Where("create_time < ?", start).Delete(&data.PayDetails{})
}

func _execPayDetails(db *gorm.DB, timeNow string, index int, totalCount int64) {
	var details []*data.PayDetails

	db.Debug().Where("create_time < ?", timeNow).Limit(1000).Offset(index * 1000).Find(&details)

	fmt.Printf("index: %d, timeNow: %s ,pay_details count: %d, totalCount: %d\n", index, timeNow, len(details), totalCount)
	if len(details) == 0 {
		return
	}

	var copyList []*data.PayDetailsCopy1
	for _, detail := range details {
		detailCopy := &data.PayDetailsCopy1{}
		CopyStruct(detail, detailCopy)
		copyList = append(copyList, detailCopy)
	}

	db.Create(&copyList)

	//time.Sleep(1500 * time.Millisecond)

	_execPayDetails(db, timeNow, index+1, totalCount)
}

func copyUserMoneyDetails(db *gorm.DB, timeNow time.Time) {
	detail := &data.UserMoneyDetails{}
	start := timeNow.Format("2006-01-02 15:04:05")
	first := db.Model(detail).Where("create_time < ?", start).Order("create_time asc").First(detail)
	if first.RowsAffected == 0 {
		fmt.Println("no user_money_details data")
		return
	}

	deleteTime := detail.CreateTime

	db.Debug().Where("create_time >= ?", deleteTime).Delete(&data.UserMoneyDetailsCopy1{})

	var totalCount int64 = 0
	db.Debug().Model(&data.UserMoneyDetails{}).Where("create_time >= ?", deleteTime).Count(&totalCount)

	_execUserMoneyDetails(db, start, 0, totalCount)

	db.Debug().Where("create_time < ?", start).Delete(&data.UserMoneyDetails{})
}

func _execUserMoneyDetails(db *gorm.DB, timeNow string, index int, totalCount int64) {
	var details []*data.UserMoneyDetails

	db.Debug().Where("create_time < ?", timeNow).Limit(1000).Offset(index * 1000).Find(&details)

	fmt.Printf("index: %d, timeNow: %s ,user_money_details count: %d, totalCount: %d\n", index, timeNow, len(details), totalCount)
	if len(details) == 0 {
		return
	}

	var copyList []*data.UserMoneyDetailsCopy1
	for _, detail := range details {
		detailCopy := &data.UserMoneyDetailsCopy1{}
		CopyStruct(detail, detailCopy)
		copyList = append(copyList, detailCopy)
	}

	db.Create(&copyList)

	//time.Sleep(1500 * time.Millisecond)

	_execUserMoneyDetails(db, timeNow, index+1, totalCount)
}

func copyCourseCollect(db *gorm.DB, timeNow time.Time) {
	collect := &data.CourseCollect{}
	start := timeNow.Format("2006-01-02 15:04:05")
	first := db.Model(collect).Where("create_time < ?", start).Order("create_time asc").First(collect)
	if first.RowsAffected == 0 {
		fmt.Println("no course_collect data")
		return
	}

	deleteTime := collect.CreateTime

	db.Debug().Where("create_time >= ?", deleteTime).Delete(&data.CourseCollectCopy1{})

	var totalCount int64 = 0
	db.Debug().Model(&data.CourseCollect{}).Where("create_time >= ?", deleteTime).Count(&totalCount)

	_execCourseCollect(db, start, 0, totalCount)

	db.Debug().Where("create_time < ?", start).Delete(&data.CourseCollect{})
}

func _execCourseCollect(db *gorm.DB, timeNow string, index int, totalCount int64) {
	var collects []*data.CourseCollect

	db.Debug().Where("create_time < ?", timeNow).Limit(1000).Offset(index * 1000).Find(&collects)

	fmt.Printf("index: %d, timeNow: %s ,course_collect count: %d, totalCount: %d\n", index, timeNow, len(collects), totalCount)
	if len(collects) == 0 {
		return
	}

	var copyList []*data.CourseCollectCopy1
	for _, collect := range collects {
		collectCopy := &data.CourseCollectCopy1{}
		CopyStruct(collect, collectCopy)
		copyList = append(copyList, collectCopy)
	}

	db.Create(&copyList)

	//time.Sleep(1500 * time.Millisecond)

	_execCourseCollect(db, timeNow, index+1, totalCount)
}

func copyCourseUser(db *gorm.DB, timeNow time.Time) {
	user := &data.CourseUser{}
	start := timeNow.Format("2006-01-02 15:04:05")
	first := db.Model(user).Where("create_time < ?", start).Order("create_time asc").First(user)
	if first.RowsAffected == 0 {
		fmt.Println("no course_user data")
		return
	}

	deleteTime := user.CreateTime

	db.Debug().Where("create_time >= ?", deleteTime).Delete(&data.CourseUserCopy1{})

	var totalCount int64 = 0
	db.Debug().Model(&data.CourseUser{}).Where("create_time >= ?", deleteTime).Count(&totalCount)

	_execCourseUser(db, start, 0, totalCount)

	db.Debug().Where("create_time < ?", start).Delete(&data.CourseUser{})
}

func _execCourseUser(db *gorm.DB, timeNow string, index int, totalCount int64) {
	var users []*data.CourseUser

	db.Debug().Where("create_time < ?", timeNow).Limit(1000).Offset(index * 1000).Find(&users)

	fmt.Printf("index: %d, timeNow: %s ,course_user count: %d, totalCount: %d\n", index, timeNow, len(users), totalCount)
	if len(users) == 0 {
		return
	}

	var copyList []*data.CourseUserCopy1
	for _, user := range users {
		userCopy := &data.CourseUserCopy1{}
		CopyStruct(user, userCopy)
		copyList = append(copyList, userCopy)
	}

	db.Create(&copyList)

	//time.Sleep(1500 * time.Millisecond)

	_execCourseUser(db, timeNow, index+1, totalCount)
}

func copyDiscSpinningRecord(db *gorm.DB, timeNow time.Time) {
	record := &data.DiscSpinningRecord{}
	start := timeNow.Format("2006-01-02 15:04:05")
	first := db.Model(record).Where("create_time < ?", start).Order("create_time asc").First(record)
	if first.RowsAffected == 0 {
		fmt.Println("no disc_spinning_record data")
		return
	}

	deleteTime := record.CreateTime

	db.Debug().Where("create_time >= ?", deleteTime).Delete(&data.DiscSpinningRecordCopy1{})

	var totalCount int64 = 0
	db.Debug().Model(&data.DiscSpinningRecord{}).Where("create_time >= ?", deleteTime).Count(&totalCount)

	_execDiscSpinningRecord(db, start, 0, totalCount)

	db.Debug().Where("create_time < ?", start).Delete(&data.DiscSpinningRecord{})
}

func _execDiscSpinningRecord(db *gorm.DB, timeNow string, index int, totalCount int64) {
	var records []*data.DiscSpinningRecord

	db.Debug().Where("create_time < ?", timeNow).Limit(1000).Offset(index * 1000).Find(&records)

	fmt.Printf("index: %d, timeNow: %s ,disc_spinning_record count: %d, totalCount: %d\n", index, timeNow, len(records), totalCount)
	if len(records) == 0 {
		return
	}

	var copyList []*data.DiscSpinningRecordCopy1
	for _, record := range records {
		recordCopy := &data.DiscSpinningRecordCopy1{}
		CopyStruct(record, recordCopy)
		copyList = append(copyList, recordCopy)
	}

	db.Create(&copyList)

	//time.Sleep(1500 * time.Millisecond)

	_execDiscSpinningRecord(db, timeNow, index+1, totalCount)
}

func copyCashOut(db *gorm.DB, timeNow time.Time) {
	record := &data.CashOut{}
	start := timeNow.Format("2006-01-02 15:04:05")
	first := db.Model(record).Where("create_at < ?", start).Order("create_at asc").First(record)
	if first.RowsAffected == 0 {
		fmt.Println("no cash_out data")
		return
	}

	deleteTime := record.CreateAt

	db.Debug().Where("create_at >= ?", deleteTime).Delete(&data.CashOutCopy1{})

	var totalCount int64 = 0
	db.Debug().Model(&data.CashOut{}).Where("create_at >= ?", deleteTime).Count(&totalCount)

	_execCashOut(db, start, 0, totalCount)

	db.Debug().Where("create_at < ?", start).Delete(&data.CashOut{})
}

func _execCashOut(db *gorm.DB, timeNow string, index int, totalCount int64) {
	var records []*data.CashOut
	db.Debug().Where("create_at < ?", timeNow).Limit(1000).Offset(index * 1000).Find(&records)
	fmt.Printf("index: %d, timeNow: %s ,cash_out count: %d, totalCount: %d\n", index, timeNow, len(records), totalCount)
	if len(records) == 0 {
		return
	}

	var copyList []*data.CashOutCopy1
	for _, record := range records {
		recordCopy := &data.CashOutCopy1{}
		CopyStruct(record, recordCopy)
		copyList = append(copyList, recordCopy)
	}

	db.Create(&copyList)

	//time.Sleep(1500 * time.Millisecond)

	_execCashOut(db, timeNow, index+1, totalCount)
}

func copySysUserMoneyDetails(db *gorm.DB, timeNow time.Time) {
	record := &data.SysUserMoneyDetails{}
	start := timeNow.Format("2006-01-02 15:04:05")
	first := db.Model(record).Where("create_time < ?", start).Order("create_time asc").First(record)
	if first.RowsAffected == 0 {
		fmt.Println("no sys_user_money_detail data")
		return
	}

	deleteTime := record.CreateTime

	db.Debug().Where("create_time >= ?", deleteTime).Delete(&data.SysUserMoneyDetailsCopy1{})

	var totalCount int64 = 0
	db.Debug().Model(&data.SysUserMoneyDetails{}).Where("create_time >= ?", deleteTime).Count(&totalCount)

	_execSysUserMoneyDetails(db, start, 0, totalCount)

	db.Debug().Where("create_time < ?", start).Delete(&data.SysUserMoneyDetails{})
}

func _execSysUserMoneyDetails(db *gorm.DB, timeNow string, index int, totalCount int64) {
	var records []*data.SysUserMoneyDetails
	db.Debug().Where("create_time < ?", timeNow).Limit(1000).Offset(index * 1000).Find(&records)
	fmt.Printf("index: %d, timeNow: %s ,sys_user_money_details count: %d, totalCount: %d\n", index, timeNow, len(records), totalCount)
	if len(records) == 0 {
		return
	}

	var copyList []*data.SysUserMoneyDetailsCopy1
	for _, record := range records {
		recordCopy := &data.SysUserMoneyDetailsCopy1{}
		CopyStruct(record, recordCopy)
		copyList = append(copyList, recordCopy)
	}

	db.Create(&copyList)

	//time.Sleep(1500 * time.Millisecond)

	_execSysUserMoneyDetails(db, timeNow, index+1, totalCount)
}

// CopyStruct 使用反射复制结构体
func CopyStruct(src, dst interface{}) {
	_ = copier.Copy(dst, src)
}
