package service

import (
	"context"
	"dataapps/commons/grpc"
	"dataapps/commons/logger"
	entity "dataapps/internal/entity/sqleditor"
	repository "dataapps/internal/repository/sqleditor"
	"encoding/json"
	"fmt"

	"github.com/tidbcloud/dataservices/idl/pbgen/proto/dataapi"
	"go.uber.org/zap"
)

// @Time    : 2022/11/14 10:50 AM
// @Author  : lvhongmeng

func UpdateUserSettings(param entity.SQLEditorSettings) error {
	return repository.UpdateSettings(param)
}

func UpdateDataAppSettings(ctx context.Context, param entity.DataAppSettings) error {

	if param.EnableDataAPI {
		// Create app and apikey
		logger.Info(ctx, fmt.Sprintf("UpdateDataAppSettings-CreateDataApp,user:%s", param.CreatedBy))
		dataappResp, err := grpc.CreateDataApp(ctx, &dataapi.CreateDataAppReq{
			OrgId:     param.OrgID,
			ProjectId: param.ProjectID,
			AppType:   "chat2query",
			CreatedBy: param.CreatedBy,
		})
		if err != nil {
			return err
		}
		logger.Info(ctx, "UpdateDataAppSettings-CreateDataApp success", zap.Uint64("app_id", dataappResp.AppInfo.Id), zap.String("user", param.CreatedBy))
	} else {
		// List project's dataapp and delete
		appList, err := grpc.ListDataApp(ctx, &dataapi.ListDataAppReq{
			ProjectId: param.ProjectID,
			AppTypes:  []string{"chat2query"},
		})
		if err != nil {
			return err
		}
		for _, appInfo := range appList.AppList {
			_, err = grpc.DeleteDataApp(ctx, &dataapi.DeleteDataAppReq{AppId: appInfo.Id, Operator: param.CreatedBy})
			if err != nil {
				return err
			}
		}
	}
	logger.Info(ctx, fmt.Sprintf("UpdateDataAppSettings,param:%+v,user:%s", param, param.CreatedBy))
	return nil
}

func ShowDataAppSettings(ctx context.Context, projectId uint64) (*entity.DataAppSettingsFormat, error) {
	appList, err := grpc.ListDataApp(ctx, &dataapi.ListDataAppReq{
		ProjectId: projectId,
		AppTypes:  []string{"chat2query"},
	})
	if err != nil {
		return nil, err
	}
	return &entity.DataAppSettingsFormat{
		EnableDataAPI: len(appList.AppList) > 0,
	}, nil
}

func ShowChat2DataURL(ctx context.Context, projectId, clusterId uint64) (string, error) {

	codeExample, err := grpc.EndpointCodeExample(ctx, &dataapi.EndpointCodeExampleReq{
		ProjectId:    projectId,
		ClusterId:    clusterId,
		EndpointType: "chat2data",
	})
	if err != nil {
		return "", err
	}
	return codeExample.Code, nil
}

func ShowSettings(ctx context.Context, param entity.SQLEditorSettings) (*entity.Settings, error) {
	var userSettings entity.Settings
	settings, err := repository.ShowUserSettings(param)
	if err != nil {
		return nil, err
	}
	basicSettings := settings.BasicSettings
	err = json.Unmarshal([]byte(basicSettings), &userSettings)
	if err != nil {
		return nil, err
	}

	dataAppSettings, err := ShowDataAppSettings(ctx, param.ProjectID)
	if err != nil {
		return nil, err
	}
	userSettings.EnableDataAPI = dataAppSettings.EnableDataAPI
	return &userSettings, nil
}

func ShowSettingsLimit(ctx context.Context, orgid uint64, projectid uint64, clusterid uint64, createdBy string) (int, error) {
	settings := entity.SQLEditorSettings{
		OrgID:     orgid,
		ProjectID: projectid,
		ClusterID: clusterid,
		CreatedBy: createdBy,
	}
	settingEntity, err := ShowSettings(ctx, settings)
	if err != nil {
		return 0, err
	}
	limit := settingEntity.Limit
	return limit, err
}

func ShowUserInfo(createdBy string) (*entity.UserInfo, error) {
	userInfo, err := repository.ShowUserInfo(createdBy)
	if err != nil {
		return nil, err
	}
	return userInfo, nil
}

func UpdateUserInfo(userInfo map[string]interface{}) error {
	err := repository.UpdateUserInfo(userInfo)
	if err != nil {
		return err
	}
	return nil
}
