package server

import (
	"bytes"
	"fmt"
	"gskaro-v1/internal/llm"
	"net/http"
	"time"
)

type llmLogEntry struct {
	Model        string
	Prompt       string
	Answer       string
	Timestamp    time.Time
	PromptTokens int
	AnswerTokens int
}

var llmHistory []llmLogEntry

// -----------------------------
// LLM Console
// -----------------------------

func llmConsoleHandler(w http.ResponseWriter, r *http.Request) {
	if r.Header.Get("HX-Request") != "true" {
		fmt.Fprintf(w, `
            <!doctype html>
            <html lang="ru">
            <head>
                <meta charset="utf-8">
                <title>LLM Console</title>
                <script src="https://unpkg.com/htmx.org@1.9.10"></script>
            </head>
            <body hx-boost="true">
                <div id="top-bar" style="display:flex; gap:16px; align-items:center; margin-bottom:16px;">
                    <div>
                        <button hx-get="/api/stats" hx-target="#content">Статистика</button>
                        <button hx-get="/api/tasks" hx-target="#content">Задачи</button>
                        <button hx-get="/api/notes" hx-target="#content">AI_NOTES.md</button>
                        <button hx-get="/api/llm/console" hx-target="#content">LLM Console</button>
                        <button hx-get="/api/llm/models" hx-target="#content">LLM Models</button>
                        <button hx-get="/api/llm/history" hx-target="#content">LLM History</button>
                    </div>

                    <div id="model-badge"
                         hx-get="/api/llm/status"
                         hx-trigger="load, every 5s">
                        Текущая модель: <strong>—</strong>
                    </div>
                </div>

                <div id="content">
        `)
		renderConsole(w)
		fmt.Fprintf(w, `
                </div>
            </body>
            </html>
        `)
		return
	}

	renderConsole(w)
}

func renderConsole(w http.ResponseWriter) {
	fmt.Fprintf(w, `
        <h2>LLM Console</h2>

        <p>Текущая модель: <strong>%s</strong></p>

        <form hx-post="/api/llm/query" hx-target="#llm-output" hx-swap="innerHTML">
            <textarea name="prompt" rows="4" style="width:100%%"></textarea>
            <br>
            <button type="submit">Отправить</button>
        </form>

        <div id="llm-output" style="margin-top:20px; border:1px solid #ddd; padding:10px;">
            Ожидание ответа...
        </div>
    `, llm.ActiveModel)
}

// -----------------------------
// Список моделей
// -----------------------------

func llmModelsHandler(w http.ResponseWriter, r *http.Request) {
	host := r.URL.Query().Get("host")

	if host == "" {
		fmt.Fprintf(w, `
            <h2>Подключение к Ollama</h2>
            <form hx-get="/api/llm/models" hx-target="#content">
                <input type="text" name="host" placeholder="http://localhost:11434" style="width:300px;">
                <button type="submit">Получить модели</button>
            </form>
        `)
		return
	}

	models, err := llm.GetModelsFromHost(host)
	if err != nil {
		fmt.Fprintf(w, `<p style="color:red;">Ошибка подключения: %s</p>`, err)
		return
	}

	fmt.Fprintf(w, `<h2>Модели на %s</h2>`, host)
	fmt.Fprintf(w, `<form hx-post="/api/llm/select" hx-target="#content">`)
	fmt.Fprintf(w, `<input type="hidden" name="host" value="%s">`, host)
	fmt.Fprintf(w, `<select name="model">`)

	for _, m := range models {
		fmt.Fprintf(w, `<option value="%s">%s</option>`, m, m)
	}

	fmt.Fprintf(w, `</select>`)
	fmt.Fprintf(w, `<button type="submit">Выбрать</button>`)
	fmt.Fprintf(w, `</form>`)
}

// -----------------------------
// Выбор модели
// -----------------------------

func llmSelectHandler(w http.ResponseWriter, r *http.Request) {
	host := r.FormValue("host")
	model := r.FormValue("model")

	if host != "" {
		llm.ActiveHost = host
	}

	if model != "" {
		llm.ActiveModel = model
	}

	if r.Header.Get("HX-Request") == "true" {
		w.Header().Set("HX-Redirect", "/api/llm/console")
		return
	}

	http.Redirect(w, r, "/api/llm/console", http.StatusSeeOther)
}

// -----------------------------
// Запрос к модели
// -----------------------------

func llmQueryHandler(w http.ResponseWriter, r *http.Request) {
	prompt := r.FormValue("prompt")
	if prompt == "" {
		fmt.Fprintf(w, "<p style='color:red;'>Пустой запрос.</p>")
		return
	}

	client := &llm.OllamaClient{
		Host:  llm.ActiveHost,
		Model: llm.ActiveModel,
	}

	var answerBuf bytes.Buffer
	var promptTokens, answerTokens int

	err := client.Stream(prompt, func(chunk string, meta *llm.OllamaGenerateResponse) {
		answerBuf.WriteString(chunk)
		if meta != nil {
			promptTokens = meta.PromptEvalCount
			answerTokens = meta.EvalCount
		}
	})
	if err != nil {
		fmt.Fprintf(w, "<p style='color:red;'>Ошибка: %s</p>", err)
		return
	}

	resp := answerBuf.String()

	llmHistory = append(llmHistory, llmLogEntry{
		Model:        llm.ActiveModel,
		Prompt:       prompt,
		Answer:       resp,
		Timestamp:    time.Now(),
		PromptTokens: promptTokens,
		AnswerTokens: answerTokens,
	})

	fmt.Fprintf(w, "<pre>%s</pre>", resp)
}

// -----------------------------
// Статус
// -----------------------------

func llmStatusHandler(w http.ResponseWriter, r *http.Request) {
	resp, err := http.Get(llm.ActiveHost + "/api/tags")
	if err != nil {
		fmt.Fprintf(w, `
			<span style="padding:4px 8px; border-radius:4px; background:#fee; color:#900;">
				Ollama: offline
			</span>
			&nbsp;
			<span>Модель: <strong>%s</strong></span>
		`, llm.ActiveModel)
		return
	}
	resp.Body.Close()

	fmt.Fprintf(w, `
		<span style="padding:4px 8px; border-radius:4px; background:#e6ffed; color:#137333;">
			Ollama: online
		</span>
		&nbsp;
		<span>Модель: <strong>%s</strong></span>
	`, llm.ActiveModel)
}

// -----------------------------
// История
// -----------------------------

func llmHistoryHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "<h2>LLM History</h2>")

	if len(llmHistory) == 0 {
		fmt.Fprintf(w, "<p>Пока пусто.</p>")
		return
	}

	fmt.Fprintf(w, `<ul style="list-style:none; padding:0;">`)

	for i := len(llmHistory) - 1; i >= 0; i-- {
		e := llmHistory[i]

		fmt.Fprintf(w, `
			<li style="margin-bottom:16px; padding:12px; border:1px solid #ddd; border-radius:6px;">
				<div style="color:#666; font-size:13px;">
					🕒 %s
				</div>

				<div><strong>Модель:</strong> %s</div>

				<div style="margin-top:8px;"><strong>👤 Запрос:</strong></div>
				<pre style="white-space:pre-wrap; background:#fafafa; padding:8px; border-radius:4px;">%s</pre>

				<div style="margin-top:8px;"><strong>🤖 Ответ модели:</strong></div>
				<pre style="white-space:pre-wrap; background:#f0f7ff; padding:8px; border-radius:4px;">%s</pre>

				<div style="margin-top:8px; color:#555;">
					🔢 Токены: prompt=%d, answer=%d, total=%d
				</div>
			</li>
		`,
			e.Timestamp.Format("2006-01-02 15:04:05"),
			e.Model,
			e.Prompt,
			e.Answer,
			e.PromptTokens,
			e.AnswerTokens,
			e.PromptTokens+e.AnswerTokens,
		)
	}

	fmt.Fprintf(w, `</ul>`)
}
