package repository

import (
	"encoding/csv"
	"encoding/json"
	"errors"
	"github.com/extrame/xls"
	"gorm.io/gorm"
	"log"
	"os"
	"path/filepath"
	"strings"
	"testData/global"
	"testData/model"
	"testData/utils"
)

func HandlerTQT601Excel(fileText *model.FileText, step string) {
	var isXls bool
	file, err := os.Open(fileText.Path)
	if err != nil {
		log.Println("open err:", err)
		return
	}
	reader := csv.NewReader(file)
	reader.FieldsPerRecord = -1
	reader.LazyQuotes = true
	rows, err := reader.ReadAll()
	if err != nil {
		if xlFile, err := xls.Open(fileText.Path, "utf-8"); err == nil {
			//第一个sheet
			sheet := xlFile.GetSheet(0)
			if sheet.MaxRow != 0 {
				temp := make([][]string, sheet.MaxRow)
				for i := 0; i < int(sheet.MaxRow); i++ {
					row := sheet.Row(i)
					data := make([]string, 0)
					if row.LastCol() > 0 {
						for j := 0; j < row.LastCol(); j++ {
							col := row.Col(j)
							data = append(data, col)
						}
						temp[i] = data
					}
				}
				rows = append(rows, temp...)
			}
			isXls = true
		} else {
			log.Println("open err:", err)
			return
		}
	}

	newExcel := make([][]string, 0)
	var title []string
	details := make(map[string]string)
	titleInfoMap := make(map[string]model.DataInfo)
	index, titleIndex, unitIndex, limitLIndex, limitUIndex := 0, -1, -1, -1, -1
	if len(rows) == 0 {
		log.Println(fileText.Path, "文件为空")
		return
	}
	for {
		if index == len(rows)-1 {
			break
		}
		if !isXls {
			rows[index][0], err = utils.DecodeToUnicode(rows[index][0])
			if err != nil {
				return
			}
			rows[index] = strings.Split(rows[index][0], "\t")
		}
		if len(titleInfoMap) == 0 {
			if strings.Contains(rows[index][0], "=") {
				splitIndex := strings.Index(rows[index][0], "=")
				details[rows[index][0][:splitIndex]] = rows[index][0][splitIndex+1:]
			}
			if titleIndex < 0 && len(rows[index]) > 1 {
				if strings.Contains(rows[index][1], "Test") {
					titleIndex = index
					index++
					continue
				}
			} else {
				if limitUIndex < 0 && len(rows[index]) > 1 {
					if strings.Contains(rows[index][1], "High_limits") {
						limitUIndex = index
						index++
						continue
					}
				}
				if limitLIndex < 0 && len(rows[index]) > 1 {
					if strings.Contains(rows[index][1], "Low_limits") {
						limitLIndex = index
						index++
						continue
					}
				}
				if unitIndex < 0 && len(rows[index]) > 1 {
					if strings.Contains(rows[index][1], "Units") {
						unitIndex = index
						rows[limitUIndex] = append(rows[limitUIndex], utils.FillData(len(rows[titleIndex])-len(rows[limitUIndex]))...)
						rows[limitLIndex] = append(rows[limitLIndex], utils.FillData(len(rows[titleIndex])-len(rows[limitLIndex]))...)
						rows[unitIndex] = append(rows[unitIndex], utils.FillData(len(rows[titleIndex])-len(rows[unitIndex]))...)
						title = append(title, []string{"DieID", "SBIN"}...)
						for rowIndex := 2; rowIndex < len(rows[index]); rowIndex++ {
							title = append(title, rows[titleIndex][rowIndex])
							titleInfoMap[rows[titleIndex][rowIndex]] = model.DataInfo{
								Unit:   rows[unitIndex][rowIndex],
								LimitL: rows[limitLIndex][rowIndex],
								LimitU: rows[limitUIndex][rowIndex],
							}
						}
						//newExcel = append(newExcel, title)
						index++
						continue
					}
				}
			}
		} else {
			if len(rows[index]) > 1 {
				if strings.Contains(rows[index][1], "Test") || strings.Contains(rows[index][1], "High_limits") ||
					strings.Contains(rows[index][1], "Low_limits") || strings.Contains(rows[index][1], "Units") {
					index++
					continue
				}
				if !strings.Contains(rows[index][1], "SBIN") {
					rows[index] = append(rows[index], utils.FillData(len(rows[titleIndex])-len(rows[index]))...)
					newExcel = append(newExcel, rows[index])
				}
			}
		}
		index++
	}
	fileText.Name = strings.ReplaceAll(fileText.Name, "__", "_")
	if details["Test_Code"] == "" {
		details["Test_Code"] = step
	} else {
		details["Test_Code"] = details["Test_Code"][:2]
	}
	pointLastIndex := strings.LastIndex(fileText.Name, ".")
	pointIndex := pointLastIndex - 1
	for {
		if pointIndex == 0 {
			log.Println("文件名格式错误:", fileText.Path)
			return
		}
		if fileText.Name[pointIndex] == '.' {
			break
		}
		pointIndex--
	}
	if pointIndex != pointLastIndex {
		start, end := pointIndex, pointIndex+2
		//for {
		//	if fileText.Name[end] == '_' {
		//		break
		//	}
		//	end++
		//	if end > pointLastIndex {
		//		fmt.Println("文件名格式错误:", fileText.Path)
		//		return
		//	}
		//}
		for {
			if fileText.Name[start] == '_' {
				break
			}
			start--
			if start < 0 {
				log.Println("文件名格式错误:", fileText.Path)
				return
			}
		}
		for i := 2; i < start; i++ {
			if details["Test_Code"] == "FT" {
				if fileText.Name[i-2:i] == "FT" {
					for {
						if fileText.Name[i] == '_' {
							break
						}
						i++
					}
					if i > start-1 {
						log.Println("文件名格式错误:", fileText.Path)
						return
					}
					details["product"] = fileText.Name[i+1 : start]
					break
				}
			} else if details["Test_Code"] == "RT" {
				if fileText.Name[i-2:i] == "RT" {
					for {
						if fileText.Name[i] == '_' {
							break
						}
						i++
					}
					details["product"] = fileText.Name[i+1 : start]
					break
				}
			}
		}
		details["lot"] = fileText.Name[start+1 : end]
	}
	testProgram := details["TestProgram"]
	fileName := details["product"] + "_" + details["lot"] + "_" + details["Test_Code"] + ".csv"
	utils.MakeDir("/testData/test")
	filePath := filepath.Join("/testData/test", fileName)
	titleInfo, _ := json.Marshal(&titleInfoMap)
	var fileHandled *model.FileHandled
	if _, err = os.Stat(filePath); err != nil {
		if os.IsNotExist(err) {
			newExcel = append([][]string{title}, newExcel...)
			_, err = os.Create(filePath)
			if err != nil {
				log.Println("创建文件失败:", err)
				return
			}
			if errors.Is(global.PostGreSQL.Where("name = ?", fileName).First(&fileHandled).Error, gorm.ErrRecordNotFound) {
				global.PostGreSQL.Create(&model.FileHandled{
					Name:             fileName,
					Path:             filePath,
					Size:             "",
					Factory:          fileText.Factory,
					Product:          details["product"],
					Step:             details["Test_Code"],
					Lot:              details["lot"],
					TestMachineModel: "TQT601",
					TestMachine:      details["TesterNO."],
					TestProgram:      testProgram,
					BeginningTime:    details["Beginning Time"],
					EndingTime:       details["Ending Time"],
					TitleInfo:        string(titleInfo),
				})
			}
		}
	}
	newCsv, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
	if err != nil {
		log.Println("打开新Excel错误:", err)
		return
	}
	defer newCsv.Close()
	global.PostGreSQL.Where("name = ?", fileName).First(&fileHandled)
	writer := csv.NewWriter(newCsv)
	defer writer.Flush()
	err = writer.WriteAll(newExcel)
	if err != nil {
		log.Println("写入新Excel错误:", err)
		return
	}
	newFile, err := os.Stat(filePath)
	if err != nil {
		log.Println("获取新Excel信息:", err)
		return
	}
	if fileHandled.TestMachine != "" {
		details["TesterNO."] = fileHandled.TestMachine
	}
	if fileHandled.TestProgram != "" {
		testProgram = fileHandled.TestProgram
	}
	if fileHandled.BeginningTime != "" {
		details["Beginning Time"] = fileHandled.BeginningTime
	}
	if fileHandled.EndingTime != "" {
		details["Ending Time"] = fileHandled.EndingTime
	}
	if fileHandled.TitleInfo != "" {
		titleInfo = []byte(fileHandled.TitleInfo)
	}
	global.PostGreSQL.Where("name = ?", fileName).Model(&fileHandled).Updates(map[string]interface{}{
		"product":            details["product"],
		"step":               details["Test_Code"],
		"test_machine_model": "TQT601",
		"test_machine":       details["TesterNO."],
		"test_program":       testProgram,
		"beginning_time":     details["Beginning Time"],
		"ending_time":        details["Ending Time"],
		"title_info":         string(titleInfo),
		"size":               utils.FormatFileSize(float64(newFile.Size())),
	})
}
