package cmd

import (
	"fmt"
	"os"

	"github.com/fatih/color"
	"github.com/letta/letta-switchboard-cli/internal/client"
	"github.com/letta/letta-switchboard-cli/internal/config"
	"github.com/letta/letta-switchboard-cli/internal/parser"
	"github.com/olekukonko/tablewriter"
	"github.com/spf13/cobra"
)

var onetimeCmd = &cobra.Command{
	Use:     "onetime",
	Aliases: []string{"send", "message"},
	Short:   "Send messages to agents",
	Long:    "Send one-time messages to Letta agents immediately or scheduled for later",
}

var onetimeCreateCmd = &cobra.Command{
	Use:     "create",
	Aliases: []string{"send"},
	Short:   "Send a message to an agent",
	Long:    "Send a message to an agent immediately or scheduled for later",
	RunE: func(cmd *cobra.Command, args []string) error {
		agentID, _ := cmd.Flags().GetString("agent-id")
		message, _ := cmd.Flags().GetString("message")
		role, _ := cmd.Flags().GetString("role")
		executeAt, _ := cmd.Flags().GetString("execute-at")

		if agentID == "" || message == "" {
			return fmt.Errorf("agent-id and message are required")
		}

		// Default to "now" if no time specified
		if executeAt == "" {
			executeAt = "now"
		}

		// Parse natural language time to ISO 8601
		parsedTime, err := parser.ParseTime(executeAt)
		if err != nil {
			return fmt.Errorf("failed to parse execute-at: %w", err)
		}

		cfg, err := config.Load()
		if err != nil {
			return err
		}
		if err := cfg.Validate(); err != nil {
			return err
		}

		apiClient := client.NewClient(cfg.BaseURL, cfg.APIKey)
		schedule, err := apiClient.CreateOneTimeSchedule(client.OneTimeScheduleCreate{
			AgentID:   agentID,
			Message:   message,
			Role:      role,
			ExecuteAt: parsedTime,
		})
		if err != nil {
			return fmt.Errorf("failed to create schedule: %w", err)
		}

		if executeAt == "now" {
			color.Green("✓ Message sent successfully (executing immediately)")
		} else {
			color.Green("✓ Message scheduled successfully")
		}
		fmt.Printf("\nSchedule ID:  %s\n", schedule.ID)
		fmt.Printf("Agent ID:     %s\n", schedule.AgentID)
		fmt.Printf("Execute At:   %s\n", schedule.ExecuteAt)
		fmt.Printf("Message:      %s\n", schedule.Message)

		return nil
	},
}

var onetimeListCmd = &cobra.Command{
	Use:   "list",
	Short: "List all one-time schedules",
	RunE: func(cmd *cobra.Command, args []string) error {
		cfg, err := config.Load()
		if err != nil {
			return err
		}
		if err := cfg.Validate(); err != nil {
			return err
		}

		apiClient := client.NewClient(cfg.BaseURL, cfg.APIKey)
		schedules, err := apiClient.ListOneTimeSchedules()
		if err != nil {
			return fmt.Errorf("failed to list schedules: %w", err)
		}

		if len(schedules) == 0 {
			fmt.Println("No one-time schedules found")
			return nil
		}

		table := tablewriter.NewWriter(os.Stdout)
		table.SetHeader([]string{"Schedule ID", "Agent ID", "Execute At", "Message"})
		table.SetAutoWrapText(false)
		table.SetAutoFormatHeaders(true)
		table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
		table.SetAlignment(tablewriter.ALIGN_LEFT)
		table.SetCenterSeparator("")
		table.SetColumnSeparator("")
		table.SetRowSeparator("")
		table.SetHeaderLine(false)
		table.SetBorder(false)
		table.SetTablePadding("\t")
		table.SetNoWhiteSpace(true)

		for _, s := range schedules {
			table.Append([]string{
				s.ID,
				s.AgentID,
				s.ExecuteAt,
				truncate(s.Message, 50),
			})
		}

		table.Render()
		return nil
	},
}

var onetimeGetCmd = &cobra.Command{
	Use:   "get [schedule-id]",
	Short: "Get details of a one-time schedule",
	Args:  cobra.ExactArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		scheduleID := args[0]

		cfg, err := config.Load()
		if err != nil {
			return err
		}
		if err := cfg.Validate(); err != nil {
			return err
		}

		apiClient := client.NewClient(cfg.BaseURL, cfg.APIKey)
		schedule, err := apiClient.GetOneTimeSchedule(scheduleID)
		if err != nil {
			return fmt.Errorf("failed to get schedule: %w", err)
		}

		fmt.Printf("Schedule ID:  %s\n", schedule.ID)
		fmt.Printf("Agent ID:     %s\n", schedule.AgentID)
		fmt.Printf("Execute At:   %s\n", schedule.ExecuteAt)
		fmt.Printf("Message:      %s\n", schedule.Message)
		fmt.Printf("Role:         %s\n", schedule.Role)
		fmt.Printf("Created At:   %s\n", schedule.CreatedAt.Format("2006-01-02 15:04:05"))

		return nil
	},
}

var onetimeDeleteCmd = &cobra.Command{
	Use:   "delete [schedule-id]",
	Short: "Delete a one-time schedule",
	Args:  cobra.ExactArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		scheduleID := args[0]

		cfg, err := config.Load()
		if err != nil {
			return err
		}
		if err := cfg.Validate(); err != nil {
			return err
		}

		apiClient := client.NewClient(cfg.BaseURL, cfg.APIKey)
		if err := apiClient.DeleteOneTimeSchedule(scheduleID); err != nil {
			return fmt.Errorf("failed to delete schedule: %w", err)
		}

		color.Green("✓ Schedule deleted successfully")
		return nil
	},
}

func init() {
	rootCmd.AddCommand(onetimeCmd)

	onetimeCmd.AddCommand(onetimeCreateCmd)
	onetimeCreateCmd.Flags().String("agent-id", "", "Agent ID (required)")
	onetimeCreateCmd.Flags().String("message", "", "Message to send (required)")
	onetimeCreateCmd.Flags().String("role", "user", "Message role (default: user)")
	onetimeCreateCmd.Flags().String("execute-at", "", "When to send (optional, defaults to now)\n  Examples: 'in 5 minutes', 'tomorrow at 9am', 'next monday at 3pm', '2025-11-07T10:00:00Z', or omit for immediate delivery")

	onetimeCmd.AddCommand(onetimeListCmd)
	onetimeCmd.AddCommand(onetimeGetCmd)
	onetimeCmd.AddCommand(onetimeDeleteCmd)
}
