package modify

import (
	"context"
	"fmt"
	"strconv"

	"edge-infra.dev/pkg/edge/api/graph/model"
	"edge-infra.dev/pkg/edge/edgecli"
	"edge-infra.dev/pkg/edge/edgecli/constructors"
	"edge-infra.dev/pkg/edge/edgecli/flagutil"
	"edge-infra.dev/pkg/lib/cli/command"
	"edge-infra.dev/pkg/lib/cli/rags"
)

func NewCmd(cfg *edgecli.Config) *command.Command {
	var cmd *command.Command
	flagsets := flagutil.GetConnectionFlags(cfg)

	cmd = &command.Command{
		ShortUsage: "edge terminal interface modify",
		ShortHelp:  "Modify an interface for a particular terminal",
		Flags: append(
			flagsets,
			&rags.Rag{
				Name:     flagutil.StoreFlag,
				Value:    &rags.String{},
				Usage:    "Name of the Store - Must be unique",
				Required: true,
			},
			&rags.Rag{
				Name:     flagutil.BannerFlag,
				Value:    &rags.String{},
				Usage:    "Banner name",
				Required: true,
			},
			&rags.Rag{
				Name:     flagutil.TerminalInterfaceID,
				Value:    &rags.String{},
				Usage:    "Unique terminal interface ID",
				Required: true,
			},
			&rags.Rag{
				Name:     flagutil.MacAddressFlag,
				Value:    &rags.String{},
				Usage:    "MAC address of the network interface you want to change",
				Required: false,
			},
			&rags.Rag{
				Name:     flagutil.Gateway4Flag,
				Value:    &rags.String{},
				Usage:    "IPv4 address of interface's gateway",
				Required: false,
			},
			&rags.Rag{
				Name:     flagutil.Gateway6Flag,
				Value:    &rags.String{},
				Usage:    "IPv6 address of interface's gateway",
				Required: false,
			},
			&rags.Rag{
				Name:     flagutil.Dhcp4Flag,
				Value:    &rags.String{},
				Usage:    "Whether to enable DHCP4 for this interface",
				Required: false,
			},
			&rags.Rag{
				Name:     flagutil.Dhcp6Flag,
				Value:    &rags.String{},
				Usage:    "Whether to enable DHCP6 for this interface",
				Required: false,
			},
		),
		Exec: func(_ context.Context, _ []string) error {
			if err := flagutil.ValidateRequiredFlags(cmd.Rags); err != nil {
				return err
			}

			registrar, err := constructors.BuildRegistrar(cmd.Rags)
			if err != nil {
				return err
			}

			terminalInterfaceID := flagutil.GetStringFlag(cmd.Rags, flagutil.TerminalInterfaceID)

			reqCtx, cancelReq := context.WithTimeout(context.Background(), flagutil.BffReqTimeout)
			defer cancelReq()

			dhcp4Str := flagutil.GetOptionalFlagValue[string](cmd.Rags, flagutil.Dhcp4Flag)
			var dhcp4Bool bool
			if dhcp4Str != nil {
				dhcp4Bool, err = strconv.ParseBool(*dhcp4Str)
				if err != nil {
					fmt.Println("unable to parse field dhcp4")
					return err
				}
			}

			dhcp6Str := flagutil.GetOptionalFlagValue[string](cmd.Rags, flagutil.Dhcp6Flag)
			var dhcp6Bool bool
			if dhcp6Str != nil {
				dhcp6Bool, err = strconv.ParseBool(*dhcp6Str)
				if err != nil {
					fmt.Println("unable to parse field dhcp6")
					return err
				}
			}

			updatedIface := model.TerminalInterfaceUpdateInput{
				MacAddress: flagutil.GetOptionalFlagValue[string](cmd.Rags, flagutil.MacAddressFlag),
				Dhcp4:      &dhcp4Bool,
				Dhcp6:      &dhcp6Bool,
				Gateway4:   flagutil.GetOptionalFlagValue[string](cmd.Rags, flagutil.Gateway4Flag),
				Gateway6:   flagutil.GetOptionalFlagValue[string](cmd.Rags, flagutil.Gateway6Flag),
			}

			if _, err = registrar.ModifyTerminalInterface(reqCtx, terminalInterfaceID, &updatedIface); err != nil {
				fmt.Println("unable to modify terminal interface")
				return err
			}

			fmt.Println("successfully modified the terminal interface")

			return nil
		},
	}
	return cmd
}