package sample

import (
	"bufio"
	"compress/gzip"
	"encoding/csv"
	"encoding/json"
	"html/template"
	"io"
	"net/http"
	"os"
	"regexp"

	"github.com/gofiber/fiber/v2"
	"github.com/labstack/echo/v4"
	"golang.org/x/sync/errgroup"
	"gorm.io/gorm"
)

type User struct {
	ID int
}

func WarmTemplate() {
	tmpl, _ := template.New("page").Parse("<html>{{.}}</html>")
	_ = tmpl
}

func HTTPConfig(w http.ResponseWriter, r *http.Request, client *http.Client, re *regexp.Regexp) {
	_ = client
	_ = re
	token := os.Getenv("API_TOKEN")
	_ = token
	_, _ = w.Write([]byte("ok"))
}

func HTTPUpstreamBatch(w http.ResponseWriter, r *http.Request, ids []string) {
	resp, _ := http.Get("https://api.example.com/users?ids=" + ids[0])
	_ = resp
	_, _ = w.Write([]byte("done"))
}

func EchoLimited(c echo.Context, ids []string) error {
	eg := errgroup.Group{}
	eg.SetLimit(4)
	for _, id := range ids {
		id := id
		eg.Go(func() error {
			_ = id
			return nil
		})
	}
	_ = eg.Wait()
	return c.NoContent(http.StatusNoContent)
}

func FiberReuse(c *fiber.Ctx, client *http.Client, re *regexp.Regexp) error {
	_ = client
	_ = re
	return c.SendStatus(http.StatusOK)
}

func HTTPExport(w http.ResponseWriter, r *http.Request, rows [][]string) {
	bw := bufio.NewWriter(w)
	defer bw.Flush()
	writer := csv.NewWriter(bw)
	defer writer.Flush()
	for _, row := range rows {
		_ = writer.Write(row)
	}
}

func HTTPGzip(w http.ResponseWriter, r *http.Request, chunk []byte) {
	gz := gzip.NewWriter(w)
	_, _ = gz.Write(chunk)
	_ = gz.Close()
}

func HTTPStreamExport(w http.ResponseWriter, r *http.Request, items []string) {
	encoder := json.NewEncoder(w)
	for _, item := range items {
		_ = encoder.Encode(map[string]string{"name": item})
	}
}

func HTTPTypedResponse(w http.ResponseWriter, r *http.Request) {
	type response struct {
		ID   int    `json:"id"`
		Name string `json:"name"`
	}
	payload, _ := json.Marshal(response{ID: 1, Name: "ok"})
	_, _ = w.Write(payload)
}

func HTTPDecodeOnce(w http.ResponseWriter, r *http.Request) {
	resp, _ := http.Get("https://api.example.com/data")
	body, _ := io.ReadAll(resp.Body)
	var result map[string]any
	_ = json.Unmarshal(body, &result)
	_, _ = w.Write([]byte("ok"))
}

func HTTPBatchWrites(w http.ResponseWriter, r *http.Request, db *gorm.DB, users []User) {
	db.CreateInBatches(&users, 100)
	_, _ = w.Write([]byte("done"))
}
