package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"strings"
	"time"
)

func pollForAudioAndImage(id string) (string, string, float64, string, []string) {
	if id == "" {
		panic("id is empty")
	}
	bearer := os.Getenv("SUNO_BEARER_TOKEN")
	if bearer == "" {
		panic("SUNO_BEARER_TOKEN not set in environment")
	}
	url := "https://studio-api.staging.suno.com/api/v2/external/clips/?ids=" + id
	client := &http.Client{}
	for {
		req, err := http.NewRequest("GET", url, nil)
		if err != nil {
			panic(err)
		}
		req.Header.Set("Authorization", "Bearer "+bearer)
		resp, err := client.Do(req)
		if err != nil {
			panic(err)
		}
		var clips []struct {
			AudioURL      string `json:"audio_url"`
			ImageLargeURL string `json:"image_large_url"`
			Title         string `json:"title"`
			Metadata      struct {
				Duration float64 `json:"duration"`
				Tags     string  `json:"tags"`
			} `json:"metadata"`
		}
		err = json.NewDecoder(resp.Body).Decode(&clips)
		resp.Body.Close()
		if err != nil {
			panic(err)
		}
		if len(clips) > 0 && clips[0].AudioURL != "" && clips[0].ImageLargeURL != "" {
			tags := []string{}
			if clips[0].Metadata.Tags != "" {
				for _, tag := range strings.Split(clips[0].Metadata.Tags, ",") {
					tag = strings.TrimSpace(tag)
					if tag != "" {
						tags = append(tags, tag)
					}
				}
			}
			return clips[0].AudioURL, clips[0].ImageLargeURL, clips[0].Metadata.Duration, clips[0].Title, tags
		}
		time.Sleep(3 * time.Second)
	}
}

func GenerateSongRequest(topic string) (string, string, float64, string, []string) {
	url := "https://studio-api.staging.suno.com/api/v2/external/generate/"
	type requestBody struct {
		Topic            string `json:"topic"`
		MakeInstrumental bool   `json:"make_instrumental"`
		Model            string `json:"model"`
		Prompt           string `json:"prompt"`
	}
	body := requestBody{
		Topic:            topic,
		MakeInstrumental: true,
		Model:            "chirp-auk",
		Prompt:           "[Instrumental]",
	}
	jsonBody, err := json.Marshal(body)
	fmt.Println(string(jsonBody))
	if err != nil {
		panic(err)
	}
	bearer := os.Getenv("SUNO_BEARER_TOKEN")
	if bearer == "" {
		panic("SUNO_BEARER_TOKEN not set in environment")
	}

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonBody))
	if err != nil {
		panic(err)
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer "+bearer)

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		panic("Non-200 response: " + resp.Status)
	}

	var result struct {
		ID string `json:"id"`
	}
	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		panic(err)
	}
	if result.ID == "" {
		panic("No id in response")
	}

	return pollForAudioAndImage(result.ID)
}
