package contact

import (
	"context"
	"encoding/csv"
	"fmt"
	"github.com/suyuan32/simple-admin-common/msg/errormsg"
	"github.com/suyuan32/simple-admin-common/utils/uuidx"
	"mime/multipart"
	"strconv"
	"strings"
	"time"
	"wechat-api/ent"
	"wechat-api/ent/contact"
	"wechat-api/ent/label"
	"wechat-api/internal/svc"
	"wechat-api/internal/types"
	"wechat-api/internal/utils"

	"github.com/zeromicro/go-zero/core/logx"
)

type ImportWhatsappContactLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewImportWhatsappContactLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ImportWhatsappContactLogic {
	return &ImportWhatsappContactLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx}
}

func (l *ImportWhatsappContactLogic) ImportWhatsappContact(req *types.ImportWhatsappContactReq, file multipart.File) (*types.BaseDataInfo, error) {
	organizationId := l.ctx.Value("organizationId").(uint64)

	resp := types.BaseDataInfo{}

	reader := csv.NewReader(file)
	records, err := reader.ReadAll()
	if err != nil {
		return nil, err
	}

	var total, success, fail, add_labels int
	var conditions = "{}"
	for idx, record := range records {
		l.Logger.Infof("record=%v\n", record)
		if idx == 0 {
			continue
		}
		total++

		_, err := l.svcCtx.DB.Contact.Query().Where(
			contact.OrganizationID(organizationId),
			contact.Ctype(2),
			contact.Cc(utils.Trim(record[0])),
			contact.Phone(utils.Trim(record[1])),
		).First(l.ctx)
		if err == nil || !ent.IsNotFound(err) {
			fail++
			continue
		}

		uuidstr := uuidx.NewUUID().String()
		sex, _ := strconv.Atoi(utils.Trim(record[5]))
		cage, _ := strconv.Atoi(utils.Trim(record[7]))
		var cbirthday string
		t, err := time.Parse("2006/01/02", utils.Trim(record[8]))
		if err == nil {
			cbirthday = t.Format("2006-01-02")
		}
		newContact, err := l.svcCtx.DB.Contact.Create().SetCtype(2).
			SetCc(utils.Trim(record[0])).
			SetPhone(utils.Trim(record[1])).
			SetType(5).
			SetWxWxid(uuidstr).
			SetWxid(uuidstr).
			SetCname(transCharset(record[2])).
			SetMarkname(transCharset(record[3])).
			SetSex(sex).
			SetCage(cage).
			SetCtitle(transCharset(record[6])).
			SetCarea(transCharset(record[9])).
			SetCbirthday(cbirthday).
			SetCbirtharea(transCharset(record[10])).
			SetCidcardNo(utils.Trim(record[11])).
			SetOrganizationID(organizationId).
			Save(l.ctx)
		if err != nil {
			l.Logger.Errorf("insert to whatsapp contact failed. err=%v\n", err)
			fail++
			continue
		} else {
			success++
		}

		labels := utils.Trim(record[4])
		if labels != "" {
			for _, value := range strings.Split(labels, "+") {
				_, err = l.svcCtx.DB.Label.Query().Where(
					label.OrganizationID(organizationId),
					label.Name(value),
				).First(l.ctx)
				if err == nil || !ent.IsNotFound(err) {
					continue
				}

				newLabel, err := l.svcCtx.DB.Label.Create().
					SetName(value).
					SetType(1).
					SetNotNilConditions(&conditions).
					SetOrganizationID(organizationId).
					Save(l.ctx)
				if err != nil {
					l.Logger.Errorf("insert into whatsapp label failed.err=%v\n", err)
				}
				_, err = l.svcCtx.DB.LabelRelationship.Create().
					SetLabelID(newLabel.ID).
					SetContactID(newContact.ID).
					SetOrganizationID(organizationId).
					Save(l.ctx)
				if err != nil {
					l.Logger.Errorf("insert into whatsapp label-relationship failed.err=%v\n", err)
				} else {
					add_labels++
				}
			}
		}
	}

	resp.Code = 0
	resp.Msg = errormsg.Success
	resp.Data = fmt.Sprintf("upload finished. tota:%d success:%d failed:%d add_labels:%d\n", total, success, fail, add_labels)
	return &resp, nil
}

func transCharset(s string) string {
	return utils.TransCharset(s)
}
