package util

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"
)

type YahooChartResponse struct {
	Chart struct {
		Result []struct {
			Meta struct {
				Symbol             string  `json:"symbol"`
				RegularMarketPrice float64 `json:"regularMarketPrice"`
				Exchange           string  `json:"exchangeName"`
				Currency           string  `json:"currency"`
				Instrument         string  `json:"instrumentType"`
				FirstTrade         int64   `json:"firstTradeDate"`
				GMTOffset          int64   `json:"gmtoffset"`
				Timezone           string  `json:"exchangeTimezoneName"`
				ShortName          string  `json:"shortName"`
				LongName           string  `json:"longName"`
				Range              string  `json:"range"`
				DataGranularity    string  `json:"dataGranularity"`
				PriceHint          int     `json:"priceHint"`
				PreviousClose      float64 `json:"previousClose"`
				Scale              int     `json:"scale"`
				HasPrePostMarket   bool    `json:"hasPrePostMarketData"`
				TradingPeriods     [][]struct {
					Timezone  string `json:"timezone"`
					Start     int64  `json:"start"`
					End       int64  `json:"end"`
					GMTOffset int64  `json:"gmtoffset"`
				} `json:"tradingPeriods"`
				ValidRanges []string `json:"validRanges"`
			} `json:"meta"`
			Timestamp  []int64 `json:"timestamp"`
			Indicators struct {
				Quote []struct {
					Open   []float64 `json:"open"`
					High   []float64 `json:"high"`
					Low    []float64 `json:"low"`
					Close  []float64 `json:"close"`
					Volume []int64   `json:"volume"`
				} `json:"quote"`
				Adjclose []struct {
					Adjclose []float64 `json:"adjclose"`
				} `json:"adjclose,omitempty"`
			} `json:"indicators"`
			Events struct {
				Dividends map[string]struct {
					Amount float64 `json:"amount"`
					Date   int64   `json:"date"`
				} `json:"dividends,omitempty"`
				Splits map[string]struct {
					Date        int64   `json:"date"`
					Numerator   float64 `json:"numerator"`
					Denominator float64 `json:"denominator"`
					SplitRatio  string  `json:"splitRatio"`
				} `json:"splits,omitempty"`
			} `json:"events,omitempty"`
		} `json:"result"`
		Error interface{} `json:"error"`
	} `json:"chart"`
}

func StockSearch(query string) (string, error) {
	url := fmt.Sprintf("https://query2.finance.yahoo.com/v1/finance/search?q=%s", query)

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return "", fmt.Errorf("Fehler beim Erstellen der Anfrage: %v", err)
	}

	req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("Fehler beim Abrufen der URL: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("Fehler: HTTP Status %s", resp.Status)
	}

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("Fehler beim Lesen der Antwort: %v", err)
	}

	return string(body), nil
}

func FetchYahooFinanceData(stock string) (string, error) {
	url := fmt.Sprintf(
		"https://query2.finance.yahoo.com/v8/finance/chart/%s?range=1y&interval=1d&events=history",
		stock,
	)

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return "", fmt.Errorf("Fehler beim Erstellen der Anfrage: %v", err)
	}

	req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("Fehler beim Abrufen der URL: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("Fehler: HTTP Status %s", resp.Status)
	}

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("Fehler beim Lesen der Antwort: %v", err)
	}

	return string(body), nil
}

func FetchYahooFinanceDataMax(stock string) (string, error) {
	url := fmt.Sprintf(
		"https://query2.finance.yahoo.com/v8/finance/chart/%s?range=max&interval=1mo&events=div",
		stock,
	)

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return "", fmt.Errorf("Fehler beim Erstellen der Anfrage: %v", err)
	}

	req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("Fehler beim Abrufen der URL: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("Fehler: HTTP Status %s", resp.Status)
	}

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("Fehler beim Lesen der Antwort: %v", err)
	}

	return string(body), nil
}

// Neu: Daten für das Chart extrahieren
func ExtractChartData(jsonStr string) ([]string, []float64, error) {
	var data YahooChartResponse
	err := json.Unmarshal([]byte(jsonStr), &data)
	if err != nil {
		return nil, nil, fmt.Errorf("Fehler beim Parsen des JSON: %v", err)
	}
	if len(data.Chart.Result) == 0 {
		return nil, nil, fmt.Errorf("Keine Daten gefunden")
	}
	timestamps := data.Chart.Result[0].Timestamp
	closes := data.Chart.Result[0].Indicators.Quote[0].Close

	labels := make([]string, len(timestamps))
	for i, ts := range timestamps {
		labels[i] = time.Unix(ts, 0).Format("2006-01-02")
	}
	return labels, closes, nil
}
