package main

import (
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"strings"
	"time"
)

// generateShortCode creates a short code from a URL
// Uses first 6 characters of base64-encoded SHA256 hash
func generateShortCode(url string) string {
	hash := sha256.Sum256([]byte(url))
	encoded := base64.URLEncoding.EncodeToString(hash[:])
	// Take first 6 chars, replace URL-unsafe chars
	code := encoded[:6]
	code = strings.ReplaceAll(code, "-", "x")
	code = strings.ReplaceAll(code, "_", "y")
	return code
}

// CreateShortURL creates or retrieves a short URL for the given original URL
func (c *Crawler) CreateShortURL(originalURL string, itemGUID, feedURL string) (string, error) {
	// Check if we already have this URL
	var existingCode string
	err := c.db.QueryRow(`
		SELECT code FROM short_urls WHERE original_url = $1
	`, originalURL).Scan(&existingCode)

	if err == nil {
		return existingCode, nil
	}

	// Generate new short code
	code := generateShortCode(originalURL)

	// Handle collision by appending counter
	baseCode := code
	for i := 0; i < 100; i++ {
		if i > 0 {
			code = fmt.Sprintf("%s%d", baseCode, i)
		}

		var existingURL string
		err := c.db.QueryRow("SELECT original_url FROM short_urls WHERE code = $1", code).Scan(&existingURL)
		if err != nil {
			// Code doesn't exist, use it
			break
		}
		if existingURL == originalURL {
			// Same URL, return existing
			return code, nil
		}
		// Collision with different URL, try next
	}

	// Insert new short URL
	_, err = c.db.Exec(`
		INSERT INTO short_urls (code, original_url, item_guid, feed_url, created_at, click_count)
		VALUES ($1, $2, $3, $4, $5, 0)
	`, code, originalURL, NullableString(itemGUID), NullableString(feedURL), time.Now())

	if err != nil {
		return "", fmt.Errorf("failed to create short URL: %v", err)
	}

	return code, nil
}

// GetShortURLForPost returns the short URL string for use in posts
// Format: https://news.1440.news/{code}
func (c *Crawler) GetShortURLForPost(originalURL, itemGUID, feedURL string) (string, error) {
	code, err := c.CreateShortURL(originalURL, itemGUID, feedURL)
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("https://news.1440.news/%s", code), nil
}
