package plugin

import (
	"database/sql"
	"errors"
	"fmt"
	"moss-dev/datahub/api"
	"moss-dev/datamodels"
	"moss-dev/gpt"
	"moss-dev/utils"

	"github.com/pingcap/log"
	gogpt "github.com/sashabaranov/go-openai"
	"github.com/spf13/cobra"
	"go.uber.org/zap"
)

func NewModelEvalCmd() *cobra.Command {
	cmdEval := &cobra.Command{
		Use:   "eval",
		Short: "evaluate table model in datahub",
		//Args:  cobra.MinimumNArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			if err := utils.InitLogger(LogLevel, ""); err != nil {
				log.Fatal("Failed to initialize log", zap.Error(err))
			}

			if len(DB) == 0 {
				return errors.New("db is must required")
			}
			if len(Table) == 0 {
				return errors.New("table is must required")
			}
			if len(DatahubToken) == 0 {
				return errors.New("datahub access token is must required")
			}
			if len(GPTToken) == 0 {
				return errors.New("gpt access token is must required")
			}

			cli := api.NewDatahubClient(DatahubEndpoint, DatahubToken)
			urn, tbl, err := fetchTableInfo(cli, ProjectID, DB, Table)
			if err != nil {
				log.Fatal("fail to fetch table info", zap.Error(err))
			}
			log.Debug("table info", zap.String("create table statement", tbl.CreateTableStatement(true)))

			gptCli := gpt.NewGPT(gogpt.NewClient(GPTToken))

			modelAid := datamodels.NewModelAid()
			modelAid.SetGPTClient(gptCli)
			ms, err := modelAid.EvaluateSchemaDesign(tbl)
			if err != nil {
				log.Fatal("fail to evaludate schema design", zap.Error(err))
			}

			// Connect to the database
			if len(MySQLConnect) > 0 {
				mysqlCli, err := sql.Open("mysql", MySQLConnect)
				if err != nil {
					log.Error("fail to connect to mysql", zap.String("mysql", MySQLConnect), zap.Error(err))
					return nil
				}
				defer mysqlCli.Close()

				if err := insertModelEvalIntoMySQL(mysqlCli, urn, tbl, ms); err != nil {
					log.Fatal("fail to insert model into mysql", zap.Error(err))
				}
			} else {
				fmt.Printf("####### model evaluation ########\n %s\n ##########", ms)
			}
			return nil
		},
	}

	cmdEval.Flags().StringVar(&ProjectID, "project-id", "gcp-digital-bi", "whichi project that table model belongs to, e.g. bigquery project ID")
	cmdEval.Flags().StringVar(&DB, "db", "", "the database name of the table model, e.g. salesforce")
	cmdEval.Flags().StringVar(&Table, "table", "", "the table name of the table model, e.g. crm_account")
	cmdEval.Flags().StringVar(&DatahubEndpoint, "dh-endpoint", "https://datahub.pingcap.net/api/graphql", "the endpoint of datahub")
	cmdEval.Flags().StringVar(&DatahubToken, "dh-token", "", "the access token of datahub")
	cmdEval.Flags().StringVar(&GPTToken, "gpt-token", "", "the access token of gpt")
	cmdEval.Flags().StringVar(&LogLevel, "log-level", "info", "the output log level: info, debug, warn, error")
	cmdEval.Flags().StringVar(&MySQLConnect, "mysql", "", "mysql connect string. e.g. user:password@tcp(host:port)/database")
	cmdEval.MarkFlagRequired("db")
	cmdEval.MarkFlagRequired("table")
	cmdEval.MarkFlagRequired("dh-token")
	cmdEval.MarkFlagRequired("gpt-token")
	return cmdEval
}
