package utils

import (
	"bytes"
	"encoding/csv"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"

	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/dto"
)

func WriteFile(filePath string, data interface{}) error {
	dir := filepath.Dir(filePath)
	if err := os.MkdirAll(dir, 0755); err != nil {
		return err
	}
	file, err := os.Create(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	encoder := json.NewEncoder(file)
	encoder.SetIndent("", "  ")
	return encoder.Encode(data)
}
func WriteJsonFile(filePath string, data interface{}) error {
	dir := filepath.Dir(filePath)
	if err := os.MkdirAll(dir, 0755); err != nil {
		return err
	}
	file, err := os.Create(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	jsonData, err := json.Marshal(data)
	if err != nil {
		log.Printf("Marshal error: %v", err)
		return err
	}

	_, err = file.Write(jsonData)
	if err != nil {
		log.Printf("Write file error: %v", err)
		return err
	}

	log.Println("Write file success: " + filePath)
	return nil
}

func WritePointDataForTestToCSV(prodCSVPath, testCSVPath string, diffMetric dto.DiffMetric) error {
	// Create directory if needed
	dir := filepath.Dir(prodCSVPath)
	if err := os.MkdirAll(dir, 0755); err != nil {
		return err
	}

	// Ensure filenames are lowercase
	prodFileName := strings.ToLower(filepath.Base(prodCSVPath))
	testFileName := strings.ToLower(filepath.Base(testCSVPath))
	prodCSVPath = filepath.Join(dir, prodFileName)
	testCSVPath = filepath.Join(dir, testFileName)

	// Write prod CSV (TimeA, ClusterA from DiffPoint)
	prodFile, err := os.Create(prodCSVPath)
	if err != nil {
		return fmt.Errorf("failed to create prod CSV file: %w", err)
	}
	defer prodFile.Close()

	prodWriter := csv.NewWriter(prodFile)
	defer prodWriter.Flush()

	// Write prod header
	if err := prodWriter.Write([]string{"Time", "Value"}); err != nil {
		return fmt.Errorf("failed to write prod CSV header: %w", err)
	}

	// Write prod data rows from DiffPoint
	for _, diffPoint := range diffMetric.Points {
		row := []string{
			diffPoint.TimeA,
			fmt.Sprintf("%.4f", diffPoint.ClusterA),
		}
		if err := prodWriter.Write(row); err != nil {
			return fmt.Errorf("failed to write prod CSV row: %w", err)
		}
	}

	// Write test CSV (TimeB, ClusterB from DiffPoint)
	testFile, err := os.Create(testCSVPath)
	if err != nil {
		return fmt.Errorf("failed to create test CSV file: %w", err)
	}
	defer testFile.Close()

	testWriter := csv.NewWriter(testFile)
	defer testWriter.Flush()

	// Write test header
	if err := testWriter.Write([]string{"Time", "Value"}); err != nil {
		return fmt.Errorf("failed to write test CSV header: %w", err)
	}

	// Write test data rows from DiffPoint
	for _, diffPoint := range diffMetric.Points {
		row := []string{
			diffPoint.TimeB,
			fmt.Sprintf("%.4f", diffPoint.ClusterB),
		}
		if err := testWriter.Write(row); err != nil {
			return fmt.Errorf("failed to write test CSV row: %w", err)
		}
	}

	log.Printf("Write CSV files success: %s, %s", prodCSVPath, testCSVPath)
	return nil
}


func WriteJSONNoEscape(path string, v interface{}) error {
	var buf bytes.Buffer

	encoder := json.NewEncoder(&buf)
	encoder.SetEscapeHTML(false)
	encoder.SetIndent("", "  ")

	if err := encoder.Encode(v); err != nil {
		return err
	}

	data := bytes.TrimRight(buf.Bytes(), "\n")
	dir := filepath.Dir(path)
	if err := os.MkdirAll(dir, 0755); err != nil {
		return err
	}


	return os.WriteFile(path, data, 0644)
}