package api

import (
	"agent/client/events"
	"agent/defines/derrs"
	"context"
	"encoding/json"
)

type UserLoginResult struct {
	OwnerUuid UUID `json:"owner_uuid"`
	Token     struct {
		Value string `json:"value"`
	} `json:"token"`
	SrvTime int64 `json:"srv_time"`
}

func UserLogin(ctx context.Context, client IClient, startupInfo map[string]any) (res UserLoginResult, err error) {
	login, ok := startupInfo["login"].(string)
	if !ok {
		return res, derrs.NewIncorrectParamsError("login is required in startupInfo")
	}
	passw, ok := startupInfo["passw"].(string)
	if !ok {
		return res, derrs.NewIncorrectParamsError("passw is required in startupInfo")
	}

	event, err := EventUserLogin(login, passw)
	if err != nil {
		return res, nil
	}

	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}

	return res, json.Unmarshal(data, &res)
}

func UserLogout(ctx context.Context, client IClient, args UserLogoutArgs) (err error) {
	event, err := EventUserLogout(args)
	if err != nil {
		return err
	}
	_, err = events.ExecuteAndGetData(ctx, client, event)
	return err
}

type UserPingResult = AgentPingResult

func UserPing(ctx context.Context, client IClient,
	utime int64,
) (res UserPingResult, err error) {
	event := EventUserPing(utime)
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func UserTick(ctx context.Context, client IClient) (err error) {
	if _, err := client.Execute(ctx, EventUserTick()); err != nil {
		return err
	}
	return nil
}

func UserConfig(ctx context.Context, client IClient) (res map[string]any, err error) {
	return map[string]any{}, nil
}

type User struct {
	Uuid     UUID            `json:"uuid"`
	Name     string          `json:"name"`
	Login    string          `json:"login"`
	Settings map[string]any  `json:"settings"`
	Rights   map[string]bool `json:"rights"`
	Updated  int64           `json:"updated"`
	Created  int64           `json:"created"`
}

func UserCreate(ctx context.Context, client IClient,
	args UserCreateArgs,
) (res User, err error) {
	event, err := EventUserCreate(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func UserDelete(ctx context.Context, client IClient,
	uuid UUID,
) error {
	event, err := EventUserDelete(uuid)
	if err != nil {
		return err
	}
	_, err = events.ExecuteAndGetData(ctx, client, event)
	return err
}

func UserGet(ctx context.Context, client IClient,
	args UserGetArgs,
) (res User, err error) {
	event, err := EventUserGet(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func UserGetByUuid(ctx context.Context, client IClient,
	uuid UUID,
) (res User, err error) {
	return UserGet(ctx, client, UserGetArgs{
		Uuid: uuid,
	})
}

func UserGetByLogin(ctx context.Context, client IClient,
	login string,
) (res User, err error) {
	return UserGet(ctx, client, UserGetArgs{
		Login: login,
	})
}

func UserGetByToken(ctx context.Context, client IClient,
	token string,
) (res User, err error) {
	return UserGet(ctx, client, UserGetArgs{
		Token: token,
	})
}

func UserGetCurrent(ctx context.Context, client IClient) (res User, err error) {
	event, err := EventUserGetCurrent()
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func UserUpdate(ctx context.Context, client IClient,
	args UserUpdateArgs,
) (res User, err error) {
	event, err := EventUserUpdate(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

type UserListResult struct {
	NextPage NextPage `json:"next_page"`
	Items    []User   `json:"items"`
}

func UserList(ctx context.Context, client IClient,
	args UserListArgs,
) (res UserListResult, err error) {
	event, err := EventUserList(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func UserListByProjectAndUserGroups(ctx context.Context, client IClient,
	args UserListByProjectAndUserGroupsArgs,
) (res UserListResult, err error) {
	event, err := EventUserListByProjectAndUserGroups(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func UserListByProject(ctx context.Context, client IClient,
	args UserListByProjectArgs,
) (res UserListResult, err error) {
	event, err := EventUserListByProject(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func UserListByUserGroups(ctx context.Context, client IClient,
	args UserListByUserGroupsArgs,
) (res UserListResult, err error) {
	event, err := EventUserListByUserGroups(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func UserListByAgentGroups(ctx context.Context, client IClient,
	args UserListByAgentGroupsArgs,
) (res UserListResult, err error) {
	event, err := EventUserListByAgentGroups(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func UserListByAgent(ctx context.Context, client IClient,
	args UserListByAgentArgs,
) (res UserListResult, err error) {
	event, err := EventUserListByAgent(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func UserListAll(ctx context.Context, client IClient,
	args UserListAllArgs,
) (res UserListResult, err error) {
	event, err := EventUserListAll(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}
