package dao

import (
	"strings"
	"time"

	"git.rosy.net.cn/baseapi/utils"

	"git.rosy.net.cn/jx-callback/business/model"
)

type OperateEventExt struct {
	model.OperateEvent
	Detail []*model.OperateEventDetail `json:"detail"`
	Name   string                      `json:"name"`
}

func DeleteOperateEventDetail(db *DaoDB, deleteTime time.Time) (err error) {
	sql := `
	DELETE FROM a 
	USING operate_event_detail a,operate_event b 
	WHERE a.access_uuid = b.access_uuid
	AND b.created_at < ?
	`
	sqlParams := []interface{}{
		deleteTime,
	}
	_, err = ExecuteSQL(db, sql, sqlParams...)
	return err
}

func DeleteOperateEvent(db *DaoDB, deleteTime time.Time) (err error) {
	sql := `
	DELETE FROM operate_event 
	WHERE created_at < ?
	`
	sqlParams := []interface{}{
		deleteTime,
	}
	_, err = ExecuteSQL(db, sql, sqlParams...)
	return err
}

func GetOperateEvents(db *DaoDB, name string, apiFunctions []string, operateTypes, skuIDs, storeIDs []int, fromTime, toTime time.Time, keyword string, errType, offset, pageSize int) (operateEventExt []*OperateEventExt, totalCount int, err error) {
	sql := `
		SELECT SQL_CALC_FOUND_ROWS DISTINCT a.*, c.name 
		  FROM operate_event a
	`
	if len(operateTypes) > 0 || len(skuIDs) > 0 || len(storeIDs) > 0 || keyword != "" {
		sql += " LEFT JOIN operate_event_detail b ON a.access_uuid = b.access_uuid"
	}
	sql += `
		  LEFT JOIN user c ON c.user_id = a.user_id
		  WHERE 1=1
	`
	sqlParams := []interface{}{}
	if errType == 1 {
		sql += " AND a.err_msg = ''"
	}
	if errType == -1 {
		sql += " AND a.err_msg <> ''"
	}
	if name != "" {
		sql += " AND c.name LIKE ?"
		sqlParams = append(sqlParams, "%"+name+"%")
	}
	if !utils.IsTimeZero(fromTime) {
		sql += " AND a.created_at >= ?"
		sqlParams = append(sqlParams, fromTime)
	}
	if !utils.IsTimeZero(toTime) {
		sql += " AND a.created_at <= ?"
		sqlParams = append(sqlParams, toTime)
	}
	if len(apiFunctions) > 0 {
		sql += " AND a.api_function IN (" + GenQuestionMarks(len(apiFunctions)) + ")"
		sqlParams = append(sqlParams, apiFunctions)
	}
	if len(operateTypes) > 0 {
		sql += " AND b.operate_type IN (" + GenQuestionMarks(len(operateTypes)) + ")"
		sqlParams = append(sqlParams, operateTypes)
	}
	if len(skuIDs) > 0 {
		sql += " AND b.thing_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
		sqlParams = append(sqlParams, skuIDs)
	}
	if len(storeIDs) > 0 {
		sql += " AND b.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	if keyword != "" {
		sql += " AND ("
		var apiList []string
		for k, v := range model.ApiFunctionName {
			if strings.Contains(v, keyword) {
				apiList = append(apiList, k)
			}
		}
		if len(apiList) > 0 {
			sql += "a.api_function IN (" + GenQuestionMarks(len(apiList)) + ") OR"
			sqlParams = append(sqlParams, apiList)
		}
		sql += " a.err_msg LIKE ? OR b.thing_id LIKE ? OR b.store_id LIKE ? OR c.name LIKE ? OR a.user_id LIKE ?)"
		sqlParams = append(sqlParams, "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%")
	}
	sql += ` 
	ORDER BY a.created_at DESC
	LIMIT ? OFFSET ?
	`
	sqlParams = append(sqlParams, pageSize, offset)
	txDB, _ := Begin(db)
	defer Commit(db, txDB)
	if err = GetRowsTx(txDB, &operateEventExt, sql, sqlParams...); err == nil {
		totalCount = GetLastTotalRowCount2(db, txDB)
	}
	var (
		accessUUidList []string
		details        []*model.OperateEventDetail
		detailMap      = make(map[string][]*model.OperateEventDetail)
	)
	for _, v := range operateEventExt {
		accessUUidList = append(accessUUidList, v.AccessUUID)
	}
	if len(accessUUidList) == 0 {
		return operateEventExt, totalCount, err
	}
	sql2 := `
			SELECT * 
			  FROM operate_event_detail
			 WHERE access_uuid IN (` + GenQuestionMarks(len(accessUUidList)) + `)
		`
	sqlParams2 := []interface{}{accessUUidList}
	err = GetRows(db, &details, sql2, sqlParams2...)
	for _, v := range details {
		detailMap[v.AccessUUID] = append(detailMap[v.AccessUUID], v)
	}
	for _, v := range operateEventExt {
		if detailMap[v.AccessUUID] != nil {
			v.Detail = detailMap[v.AccessUUID]
		}
	}
	return operateEventExt, totalCount, err
}

func GetImMessageRecord(db *DaoDB, vendorOrderID, userID string, storeID, vendorID int) (msg []*model.ImMessageRecord, err error) {
	sql := `
		SELECT * 
		  FROM im_message_record
		 WHERE deleted_at = ? 
	`
	sqlParams := []interface{}{
		utils.DefaultTimeValue,
	}
	if vendorOrderID != "" {
		sql += " AND vendor_order_id = ?"
		sqlParams = append(sqlParams, vendorOrderID)
	}
	if userID != "" {
		sql += " AND user_id = ?"
		sqlParams = append(sqlParams, userID)
	}
	if storeID != 0 {
		sql += " AND store_id = ?"
		sqlParams = append(sqlParams, storeID)
	}
	if vendorID >= 0 {
		sql += " AND vendor_id = ?"
		sqlParams = append(sqlParams, vendorID)
	}
	err = GetRows(db, &msg, sql, sqlParams)
	return msg, err
}
