package sample

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

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

func HTTPConfig(w http.ResponseWriter, r *http.Request) {
	client := &http.Client{}
	re := regexp.MustCompile("^hot$")
	first := os.Getenv("API_HOST")
	second := os.Getenv("API_TOKEN")
	third := os.Getenv("API_REGION")
	_ = client
	_ = re
	_ = first
	_ = second
	_ = third
	_, _ = w.Write([]byte("ok"))
}

func HTTPTemplate(w http.ResponseWriter, r *http.Request) {
	tmpl, _ := template.New("page").Parse("<html>{{.}}</html>")
	_ = tmpl
	_, _ = w.Write([]byte("ok"))
}

func HTTPFileRead(w http.ResponseWriter, r *http.Request) {
	blob, _ := os.ReadFile("template.html")
	_, _ = w.Write(blob)
}

func HTTPUpstreamLoop(w http.ResponseWriter, r *http.Request, ids []string) {
	for _, id := range ids {
		resp, _ := http.Get("https://api.example.com/user/" + id)
		_ = resp
	}
	_, _ = w.Write([]byte("done"))
}

func EchoDuplicate(c echo.Context) error {
	resp1, _ := http.Get("https://api.example.com/config")
	resp2, _ := http.Get("https://api.example.com/config")
	_ = resp1
	_ = resp2
	return c.NoContent(http.StatusNoContent)
}

func FiberFanout(c *fiber.Ctx, ids []string) error {
	eg := errgroup.Group{}
	for _, id := range ids {
		id := id
		eg.Go(func() error {
			resp, _ := http.Get("https://api.example.com/" + id)
			_ = resp
			return nil
		})
	}
	_ = eg.Wait()
	return c.SendStatus(http.StatusOK)
}

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

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

func HTTPDBOpen(w http.ResponseWriter, r *http.Request) {
	db, _ := gorm.Open(nil, nil)
	_ = db
	_, _ = w.Write([]byte("ok"))
}

func HTTPMarshalExport(w http.ResponseWriter, r *http.Request, items []string) {
	var all []map[string]string
	for _, item := range items {
		all = append(all, map[string]string{"name": item})
	}
	payload, _ := json.Marshal(all)
	_, _ = w.Write(payload)
}

func HTTPLargeMap(w http.ResponseWriter, r *http.Request) {
	resp := map[string]any{
		"id":     1,
		"name":   "test",
		"email":  "test@example.com",
		"role":   "admin",
		"status": "active",
	}
	payload, _ := json.Marshal(resp)
	_, _ = w.Write(payload)
}

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

func FiberDBOpen(c *fiber.Ctx) error {
	db, _ := gorm.Open(nil, nil)
	_ = db
	return c.SendStatus(http.StatusOK)
}

func HTTPDBWrites(w http.ResponseWriter, r *http.Request, db *gorm.DB, ids []int) {
	for _, id := range ids {
		db.Exec("INSERT INTO users (id) VALUES (?)", id)
		db.Exec("UPDATE users SET active = true WHERE id = ?", id)
	}
	_, _ = w.Write([]byte("done"))
}

func GinStillCounts(c *gin.Context) {
	c.JSON(200, gin.H{"ok": true})
}
