package main

import (
	"flag"
	"log"
	"reflect"

	json "github.com/json-iterator/go"

	"github.com/pingcap/crm-bot/crm"
	"github.com/pingcap/crm-bot/model"
	"github.com/pingcap/crm-bot/pkg/config"
	"github.com/pingcap/crm-bot/pkg/db"
	"github.com/pingcap/crm-bot/pkg/job"
	"github.com/pingcap/crm-bot/pkg/util"
)

func main() {
	configName := flag.String("c", "config.yml", "set config file")
	flag.Parse()

	config.InitConfig(*configName, "yml", "./etc")
	if config.GetString("env") == "aws" {
		//lambda.Start(crm.CrmSqs)
	} else {
		gdb, err := db.InitDb(config.GetString("db"))
		if err != nil {
			log.Fatal(err)
		}
		err = gdb.AutoMigrate(&model.PingcapCrmActivity{},
			&model.PingcapCrmRevrec{}, &model.PingcapCrmOpportunity{},
			&model.PingcapCrmPayment{}, &model.PingcapCrmOrder{},
			&model.PingcapCrmPaymentPlan{})
		if err != nil {
			log.Fatal(err)
		}

		getDataFn := func() {
			sources := []crm.CrmDataSource{
				{
					ApiName:           "PaymentObj",
					FieldDescFileName: "./etc/payment-fielddesc.json",
					NeedFieldFileName: "./etc/payment-crm.csv",
					Topic:             "pingcap-crm-payment",
					Type:              reflect.TypeOf(model.PingcapCrmPayment{}),
				},
				{
					ApiName:           "NewOpportunityObj",
					FieldDescFileName: "./etc/business-opportunity-fielddesc.json",
					NeedFieldFileName: "./etc/business-opportunity-crm.csv",
					Topic:             "pingcap-crm-opportunity",
					Type:              reflect.TypeOf(model.PingcapCrmOpportunity{}),
				},
				{
					ApiName:           "SalesOrderObj",
					FieldDescFileName: "./etc/order-fielddesc.json",
					NeedFieldFileName: "./etc/order-crm.csv",
					Topic:             "pingcap-crm-order",
					Type:              reflect.TypeOf(model.PingcapCrmOrder{}),
				},
				{
					ApiName:           "ActiveRecordObj",
					FieldDescFileName: "./etc/activerecord-fielddesc.json",
					NeedFieldFileName: "./etc/activerecord-crm.csv",
					Topic:             "ActiveRecord",
					Type:              reflect.TypeOf(model.PingcapCrmActivity{}),
				},
				{
					ApiName:           "object_wr96N__c",
					FieldDescFileName: "./etc/revrec-fielddesc.json",
					NeedFieldFileName: "./etc/revrec-crm.csv",
					Topic:             "Revrec",
					Url:               "https://open.fxiaoke.com/cgi/crm/custom/v2/data/query",
					Type:              reflect.TypeOf(model.PingcapCrmRevrec{}),
				},
				{
					ApiName:           "PaymentPlanObj",
					FieldDescFileName: "./etc/paymentplan-fielddesc.json",
					NeedFieldFileName: "./etc/paymentplan-crm.csv",
					Topic:             "pingcap-crm-paymentplan",
					Type:              reflect.TypeOf(model.PingcapCrmPaymentPlan{}),
				},
			}

			for _, source := range sources {
				output := crm.CrmData(&source, nil)
				log.Println(len(output.Data))
				outputByts, _ := json.Marshal(output.Data)
				sliT := reflect.SliceOf(source.Type)
				SliceValue := reflect.New(sliT).Interface()
				err = json.Unmarshal(outputByts, SliceValue)
				if err != nil {
					log.Println(err)
					return
				}

				err = gdb.Where("1=1").Delete(reflect.New(source.Type).Interface()).Error
				if err != nil {
					log.Println("[error] delete table failed ", source.Topic)
				}

				SliceValueElem := reflect.ValueOf(SliceValue).Elem()
				totalLen := SliceValueElem.Len()
				step := 250
				for i := 0; i < totalLen; i += step {
					end := totalLen
					if i+step < totalLen {
						end = i + step
					}
					stepSliceValue := SliceValueElem.Slice(i, end)
					data := stepSliceValue.Convert(sliT).Interface()
					err = gdb.Save(data).Error
					if err != nil {
						log.Println("[error] sql ", err)
					}
				}
			}
		}

		getDataFn()
		job.Start()
		job.AddJob("@every 2h", job.JobRunner(getDataFn))

		log.Println("Server Started")
		util.GracefulShutdown(nil, nil)
		log.Println("Server exiting")
	}
}

var sources = []crm.CrmDataSource{
	{
		ApiName:           "PaymentObj",
		FieldDescFileName: "./etc/payment-fielddesc.json",
		NeedFieldFileName: "./etc/payment-crm.csv",
		Topic:             "pingcap-crm-payment",
		Type:              reflect.TypeOf(model.PingcapCrmPayment{}),
	},
	{
		ApiName:           "NewOpportunityObj",
		FieldDescFileName: "./etc/business-opportunity-fielddesc.json",
		NeedFieldFileName: "./etc/business-opportunity-crm.csv",
		Topic:             "pingcap-crm-opportunity",
		Type:              reflect.TypeOf(model.PingcapCrmOpportunity{}),
	},
	{
		ApiName:           "SalesOrderObj",
		FieldDescFileName: "./etc/order-fielddesc.json",
		NeedFieldFileName: "./etc/order-crm.csv",
		Topic:             "pingcap-crm-order",
		Type:              reflect.TypeOf(model.PingcapCrmOrder{}),
	},
	{
		ApiName:           "ActiveRecordObj",
		FieldDescFileName: "./etc/activerecord-fielddesc.json",
		NeedFieldFileName: "./etc/activerecord-crm.csv",
		Topic:             "ActiveRecord",
		Type:              reflect.TypeOf(model.PingcapCrmActivity{}),
	},
	{
		ApiName:           "object_wr96N__c",
		FieldDescFileName: "./etc/revrec-fielddesc.json",
		NeedFieldFileName: "./etc/revrec-crm.csv",
		Topic:             "Revrec",
		Url:               "https://open.fxiaoke.com/cgi/crm/custom/v2/data/query",
		Type:              reflect.TypeOf(model.PingcapCrmRevrec{}),
	},
}
