package excel

import (
	"bytes"
	"fmt"
	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/jx-callback/globals"
	"github.com/360EntSecGroup-Skylar/excelize"
	"io"
	"reflect"
)

type Obj2ExcelSheetConfig struct {
	Title       string
	Data        interface{}
	CaptionList []string
}

func Obj2Excel(sheetList []*Obj2ExcelSheetConfig) []byte {
	excelFile := excelize.NewFile()
	//for sheetIndex, sheetConfig := range sheetList {
	for _, sheetConfig := range sheetList {
		obj := sheetConfig.Data

		typeInfo := reflect.TypeOf(obj)
		if typeInfo.Kind() == reflect.Ptr {
			typeInfo = typeInfo.Elem()
		}
		if typeInfo.Kind() != reflect.Slice {
			panic("obj must be slice type")
		}
		typeInfo = typeInfo.Elem()
		if typeInfo.Kind() == reflect.Ptr {
			typeInfo = typeInfo.Elem()
		}
		if typeInfo.Kind() != reflect.Struct && typeInfo.Kind() != reflect.Map {
			panic("obj must be slice of map or struct")
		}

		valueInfo := reflect.Indirect(reflect.ValueOf(obj))
		/*因爲默認是Sheet1，所以直接賦值就叫sheet1，然後再改名字就行了，不然會默認多一頁空白頁為sheet1*/
		//if sheetIndex == 0 {
		index := excelFile.NewSheet("Sheet1")
		//	sheetName := excelFile.GetSheetName(1)
		excelFile.SetSheetName("Sheet1", sheetConfig.Title)
		//} else {
		//	excelFile.NewSheet(sheetConfig.Title)
		//}
		isMemberStruct := typeInfo.Kind() == reflect.Struct
		colWithList := make([]float64, len(sheetConfig.CaptionList))
		if isMemberStruct {
			var indexSlice [][]int
			name2IndexMap := utils.GetStructNameIndex(typeInfo, "json")
			for col, name := range sheetConfig.CaptionList {
				if colWith := float64(len(name)); colWith > colWithList[col] {
					colWithList[col] = colWith
				}
				if _, ok := name2IndexMap[name]; !ok {
					panic(fmt.Sprintf("col:%s不能找到相应的数据", name))
				}
				indexSlice = append(indexSlice, name2IndexMap[name])
				excelFile.SetCellStr(sheetConfig.Title, genAxis(0, col), name)
			}
			for i := 0; i < valueInfo.Len(); i++ {
				for col, index := range indexSlice {
					str := fmt.Sprint(reflect.Indirect(valueInfo.Index(i)).FieldByIndex(index).Interface())
					//// if colWith := float64(len(str)); colWith > colWithList[col] {
					//// 	colWithList[col] = colWith
					//// }
					excelFile.SetCellStr(sheetConfig.Title, genAxis(i+1, col), str)
				}
			}
		} else {
			var name2IndexMap map[string]int
			if valueInfo.Len() > 0 {
				oneData := valueInfo.Index(0).Interface().(map[string]interface{})
				name2IndexMap = make(map[string]int)
				for k := range oneData {
					name2IndexMap[k] = 1
				}
			}
			for col, name := range sheetConfig.CaptionList {
				if colWith := float64(len(name)); colWith > colWithList[col] {
					colWithList[col] = colWith
				}
				if name2IndexMap != nil {
					if _, ok := name2IndexMap[name]; !ok {
						panic(fmt.Sprintf("col:%s不能找到相应的数据", name))
					}
				}
				excelFile.SetCellStr(sheetConfig.Title, genAxis(0, col), name)
			}
			for i := 0; i < valueInfo.Len(); i++ {
				mapData := valueInfo.Index(i).Interface().(map[string]interface{})
				for col, name := range sheetConfig.CaptionList {
					str := fmt.Sprint(mapData[name])
					// if colWith := float64(len(str)); colWith > colWithList[col] {
					// 	colWithList[col] = colWith
					// }
					excelFile.SetCellStr(sheetConfig.Title, genAxis(i+1, col), str)
				}
			}
		}
		// for col := range sheetConfig.CaptionList {
		// 	colName, _ := excelize.ColumnNumberToName(col + 1)
		// 	excelFile.SetColWidth(sheetConfig.Title, colName, colName, colWithList[col])
		// }
		excelFile.SetActiveSheet(index)
	}
	buf := &bytes.Buffer{}
	excelFile.Write(buf)
	return buf.Bytes()
}

func Excel2Slice(reader io.Reader) (contents map[string][][]string) {
	if excelFile, err := excelize.OpenReader(reader); err == nil {
		contents = make(map[string][][]string)
		for _, v := range excelFile.GetSheetMap() {
			contents[v], _ = excelFile.GetRows(v)
		}
	}
	return contents
}

func genAxis(row, col int) (pos string) {
	pos, err := excelize.CoordinatesToCellName(col+1, row+1)
	if err != nil {
		globals.SugarLogger.Debugf("err:%v", err)
	}
	return pos
}
