package controllers

import (
	"io/ioutil"
	"net/http"
	"path/filepath"
	"strings"

	"github.com/gin-gonic/gin"
)

type DocsController struct {
	DocsPath string
}

func NewDocsController(docsPath string) *DocsController {
	return &DocsController{
		DocsPath: docsPath,
	}
}

// GetDocFile serves a specific documentation file
func (dc *DocsController) GetDocFile(c *gin.Context) {
	// Get the requested file path from the URL
	docPath := c.Param("filepath")
	
	// Security: Prevent directory traversal
	if strings.Contains(docPath, "..") {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid file path"})
		return
	}
	
	// Build full path
	fullPath := filepath.Join(dc.DocsPath, docPath)
	
	// Check if file exists and is a markdown file
	if !strings.HasSuffix(fullPath, ".md") {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Only markdown files are allowed"})
		return
	}
	
	// Read the file
	content, err := ioutil.ReadFile(fullPath)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Documentation file not found"})
		return
	}
	
	// Return the content as plain text
	c.Header("Content-Type", "text/markdown; charset=utf-8")
	c.String(http.StatusOK, string(content))
}

// ListDocFiles returns a list of available documentation files
func (dc *DocsController) ListDocFiles(c *gin.Context) {
	files, err := ioutil.ReadDir(dc.DocsPath)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read documentation directory"})
		return
	}
	
	var docFiles []map[string]interface{}
	
	for _, file := range files {
		if !file.IsDir() && strings.HasSuffix(file.Name(), ".md") {
			docFiles = append(docFiles, map[string]interface{}{
				"name":         file.Name(),
				"path":         "/DOCS/" + file.Name(),
				"size":         file.Size(),
				"modified_at":  file.ModTime(),
			})
		}
	}
	
	c.JSON(http.StatusOK, gin.H{
		"files": docFiles,
		"total": len(docFiles),
	})
}

// SearchDocs searches through documentation files
func (dc *DocsController) SearchDocs(c *gin.Context) {
	query := c.Query("q")
	if query == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Search query is required"})
		return
	}
	
	query = strings.ToLower(query)
	files, err := ioutil.ReadDir(dc.DocsPath)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read documentation directory"})
		return
	}
	
	var results []map[string]interface{}
	
	for _, file := range files {
		if file.IsDir() || !strings.HasSuffix(file.Name(), ".md") {
			continue
		}
		
		fullPath := filepath.Join(dc.DocsPath, file.Name())
		content, err := ioutil.ReadFile(fullPath)
		if err != nil {
			continue
		}
		
		contentLower := strings.ToLower(string(content))
		nameLower := strings.ToLower(file.Name())
		
		// Check if query matches filename or content
		if strings.Contains(nameLower, query) || strings.Contains(contentLower, query) {
			// Find context around match
			index := strings.Index(contentLower, query)
			start := 0
			end := len(content)
			
			if index > 100 {
				start = index - 100
			}
			if index+len(query)+200 < len(content) {
				end = index + len(query) + 200
			}
			
			excerpt := string(content[start:end])
			
			results = append(results, map[string]interface{}{
				"name":    file.Name(),
				"path":    "/DOCS/" + file.Name(),
				"excerpt": excerpt,
				"matches": strings.Count(contentLower, query),
			})
		}
	}
	
	c.JSON(http.StatusOK, gin.H{
		"results": results,
		"total":   len(results),
		"query":   query,
	})
}
