package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"path/filepath"
	"strings"

	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/logger"
)

type Product struct {
	Name         map[string]string `json:"name"`
	Images       []string          `json:"images"`
	ReferralLink string            `json:"referralLink"`
	Description  map[string]string `json:"overview"`
}

type ApiResponse struct {
	Product Product `json:"product"`
}

func main() {
	app := fiber.New()
	app.Use(logger.New())

	app.Static("/", "./build")

	app.Get("/product-detail/:id", func(c *fiber.Ctx) error {
		productId := c.Params("id")
		if productId == "" {
			log.Println("ID not provided")
			return c.Status(fiber.StatusBadRequest).SendFile(filepath.Join("build", "index.html"))
		}

		indexPath := filepath.Join("build", "index.html")
		templateData, err := ioutil.ReadFile(indexPath)
		if err != nil {
			log.Printf("File not found: %v\n", err)
			return c.Status(fiber.StatusInternalServerError).SendString("index.html not found")
		}

		apiURL := fmt.Sprintf("https://api.onlybrands.ge/api/products/%s", productId)
		resp, err := http.Get(apiURL)
		if err != nil || resp.StatusCode != http.StatusOK {
			log.Printf("HTTP error: %v\n", err)
			c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
			return c.SendString(string(templateData))
		}
		defer resp.Body.Close()

		var apiResp ApiResponse
		if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil {
			log.Printf("JSON decode error: %v\n", err)
			c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
			return c.SendString(string(templateData))
		}

		product := apiResp.Product

		language := "en"
		title := "Onlybrands.ge"
		description := "100% Original"
		if product.Name != nil && product.Name[language] != "" {
			title = product.Name[language]
		}
		if product.Description != nil && product.Description[language] != "" {
			description = product.Description[language]
		}

		imageURL := ""
		if len(product.Images) > 0 {
			imageURL = fmt.Sprintf("https://api.onlybrands.ge/storage/%s", url.PathEscape(product.Images[0]))
		} else {
			log.Println("No images found for product")
			imageURL = "https://example.com/default-image.jpg"
		}

		log.Printf("Image URL: %s\n", imageURL)
		updatedHtml := string(templateData)
		updatedHtml = MetaChanger(updatedHtml, "<title>", fmt.Sprintf("<title>%s</title>", title))
		updatedHtml = MetaChanger(updatedHtml, `<meta property="og:title"`, fmt.Sprintf(`<meta property="og:title" content="%s" />`, title))
		updatedHtml = MetaChanger(updatedHtml, `<meta property="og:description"`, fmt.Sprintf(`<meta property="og:description" content="%s" />`, description))
		updatedHtml = MetaChanger(updatedHtml, `<meta property="og:image"`, fmt.Sprintf(`<meta property="og:image" content="%s" />`, imageURL))

		c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
		return c.SendString(updatedHtml)
	})

	app.Use(func(c *fiber.Ctx) error {
		indexPath := filepath.Join("build", "index.html")
		c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
		return c.SendFile(indexPath)
	})

	log.Println("Server started successfully")
	log.Fatal(app.Listen(":3000"))
}

func MetaChanger(html, target, replacement string) string {
	if strings.Contains(html, target) {
		startIndex := strings.Index(html, target)
		endIndex := strings.Index(html[startIndex:], ">") + startIndex + 1

		if strings.Contains(target, "<title>") {
			closeTag := "</title>"
			closeIndex := strings.Index(html[endIndex:], closeTag) + endIndex
			if closeIndex > endIndex {
				return html[:startIndex] + replacement + html[closeIndex+len(closeTag):]
			}
		} else {
			contentStart := strings.Index(html[startIndex:], `content="`) + startIndex + 9
			contentEnd := strings.Index(html[contentStart:], `"`) + contentStart
			if contentStart > 0 && contentEnd > contentStart {
				return html[:contentStart] + replacement + html[contentEnd:]
			}
		}
	} else {
		log.Println("Meta tag not found")
		headEndIndex := strings.Index(html, "</head>")
		if headEndIndex != -1 {
			return html[:headEndIndex] + replacement + "\n" + html[headEndIndex:]
		}
	}
	return html
}
