package handlers

import (
	"html/template"
	"log"
	"net/http"
	"stocksearch/middleware"
	"stocksearch/services"
)

// PageHandler HTML 페이지 렌더링 핸들러
type PageHandler struct {
	// 페이지별 독립 템플릿 세트 (content 블록 충돌 방지)
	pageTemplates map[string]*template.Template
	stockService  *services.StockService
}

// NewPageHandler 페이지별 템플릿을 분리 파싱하여 핸들러 초기화
func NewPageHandler() *PageHandler {
	base := "templates/layout/base.html"
	pages := []string{"index.html", "stock_detail.html", "theme.html", "kospi200.html", "asset.html", "autotrade.html"}

	fns := templateFuncs()
	tmplMap := make(map[string]*template.Template, len(pages))
	for _, page := range pages {
		tmplMap[page] = template.Must(
			template.New("").Funcs(fns).ParseFiles(base, "templates/pages/"+page),
		)
	}
	return &PageHandler{
		pageTemplates: tmplMap,
		stockService:  services.GetStockService(),
	}
}

// IndexPage GET / - 메인 페이지
func (h *PageHandler) IndexPage(w http.ResponseWriter, r *http.Request) {
	data := withLoggedIn(r, map[string]interface{}{
		"Title":      "주식 시세",
		"ActiveMenu": "시세",
	})
	h.render(w, "index.html", data)
}

// ThemePage GET /theme - 테마 분석 페이지
func (h *PageHandler) ThemePage(w http.ResponseWriter, r *http.Request) {
	data := withLoggedIn(r, map[string]interface{}{
		"Title":      "테마 분석 - 주식 시세",
		"ActiveMenu": "테마",
	})
	h.render(w, "theme.html", data)
}

// Kospi200Page GET /kospi200 - 코스피200 종목 페이지
func (h *PageHandler) Kospi200Page(w http.ResponseWriter, r *http.Request) {
	data := withLoggedIn(r, map[string]interface{}{
		"Title":      "코스피200 - 주식 시세",
		"ActiveMenu": "코스피200",
	})
	h.render(w, "kospi200.html", data)
}

// AssetPage GET /asset - 자산 현황 페이지
func (h *PageHandler) AssetPage(w http.ResponseWriter, r *http.Request) {
	data := withLoggedIn(r, map[string]interface{}{
		"Title":      "자산 현황 - 주식 시세",
		"ActiveMenu": "자산",
	})
	h.render(w, "asset.html", data)
}

// AutoTradePage GET /autotrade - 자동매매 페이지
func (h *PageHandler) AutoTradePage(w http.ResponseWriter, r *http.Request) {
	data := withLoggedIn(r, map[string]interface{}{
		"Title":      "자동매매 - 주식 시세",
		"ActiveMenu": "자동매매",
	})
	h.render(w, "autotrade.html", data)
}

// StockDetailPage GET /stock/{code} - 종목 상세 페이지
func (h *PageHandler) StockDetailPage(w http.ResponseWriter, r *http.Request) {
	code := r.PathValue("code")

	price, err := h.stockService.GetCurrentPrice(code)
	if err != nil {
		log.Printf("현재가 조회 실패 [%s]: %v", code, err)
		http.Error(w, "종목 정보를 불러올 수 없습니다.", http.StatusInternalServerError)
		return
	}

	data := withLoggedIn(r, map[string]interface{}{
		"Title":      price.Name + " - 주식 시세",
		"Stock":      price,
		"ActiveMenu": "",
	})

	h.render(w, "stock_detail.html", data)
}

// withLoggedIn 템플릿 데이터에 LoggedIn 필드 추가
func withLoggedIn(r *http.Request, data map[string]interface{}) map[string]interface{} {
	data["LoggedIn"] = middleware.IsLoggedIn(r)
	return data
}

// render 템플릿 렌더링 헬퍼
func (h *PageHandler) render(w http.ResponseWriter, name string, data interface{}) {
	tmpl, ok := h.pageTemplates[name]
	if !ok {
		http.Error(w, "페이지를 찾을 수 없습니다.", http.StatusNotFound)
		return
	}
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	if err := tmpl.ExecuteTemplate(w, "base.html", data); err != nil {
		log.Printf("템플릿 렌더링 실패 [%s]: %v", name, err)
		http.Error(w, "페이지를 표시할 수 없습니다.", http.StatusInternalServerError)
	}
}

// templateFuncs 템플릿에서 사용할 커스텀 함수
func templateFuncs() template.FuncMap {
	return template.FuncMap{
		// 가격 포맷 (천 단위 콤마)
		"formatPrice": func(n int64) string {
			return formatNumber(n)
		},
		// 등락률 부호 포함 문자열
		"formatRate": func(f float64) string {
			if f >= 0 {
				return "+" + formatFloat(f) + "%"
			}
			return formatFloat(f) + "%"
		},
		// 등락에 따른 CSS 색상 클래스
		"priceClass": func(f float64) string {
			if f > 0 {
				return "text-red-500"  // 상승: 빨강 (한국 관행)
			} else if f < 0 {
				return "text-blue-500" // 하락: 파랑 (한국 관행)
			}
			return "text-gray-500"
		},
		// 체결강도 CSS 클래스 (100 기준)
		"cntrClass": func(f float64) string {
			if f > 100 {
				return "text-red-500"
			} else if f < 100 && f > 0 {
				return "text-blue-500"
			}
			return "text-gray-400"
		},
		// 체결강도 포맷
		"formatCntr": func(f float64) string {
			return formatFloat(f)
		},
	}
}

func formatNumber(n int64) string {
	s := ""
	negative := n < 0
	if negative {
		n = -n
	}
	for i, c := range reverse(itoa(n)) {
		if i > 0 && i%3 == 0 {
			s = "," + s
		}
		s = string(c) + s
	}
	if negative {
		s = "-" + s
	}
	return s
}

func formatFloat(f float64) string {
	if f < 0 {
		f = -f
	}
	// 소수점 2자리
	result := ""
	intPart := int64(f)
	fracPart := int64((f - float64(intPart)) * 100)
	result = itoa(intPart)
	if fracPart < 10 {
		result += ".0" + itoa(fracPart)
	} else {
		result += "." + itoa(fracPart)
	}
	return result
}

func itoa(n int64) string {
	if n == 0 {
		return "0"
	}
	s := ""
	for n > 0 {
		s = string(rune('0'+n%10)) + s
		n /= 10
	}
	return s
}

func reverse(s string) string {
	r := []rune(s)
	for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
		r[i], r[j] = r[j], r[i]
	}
	return string(r)
}
