package main

import (
	"database/sql"
	"fmt"
	"html/template"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	_ "github.com/denisenkom/go-mssqldb"
	"github.com/gorilla/sessions"
)

var store = sessions.NewCookieStore([]byte("ehongmd-secret-key-2025"))

type Employee struct {
	EMP_ID    string
	US_NAME   string
	BARCODE   string
	US_PASSWD string
	TNAME     string
	FNAME     string
	LNAME     string
	NICK      string
}

type Province struct {
	PR_CODE string
	PR_NAME string
}

type Status struct {
	RAP_ID         string
	RAP_NAMESTATUS string
}

type Location struct {
	RAP_ID         int
	RAP_IDNAME     string
	RAP_NAME       string
	RAP_PRICE      float64
	PR_CODE        string
	PR_NAME        string
	RAP_STATUS     string
	RAP_NAMESTATUS string
}

type LocationRF struct {
	RF_ID      int
	RAP_IDNAME string
	RAP_NAME   string
	RF_M       string
	RF_Y       string
	RF_IMG     string
	RAP_ID     int
	RAP_PRICE  float64
	RF_PRICE   string
	RF_NOTE    string
	RF_NOTE_P  string
}

type ReportRow struct {
	No       int
	Location Location
	Note     string
	Payments [12]string
}

func main() {
	// 1. กำหนดค่าการเชื่อมต่อ (Connection String)
	connStr := "server=192.168.10.61;user id=pond;password=Ehongmd2025;port=1433;database=CONFIG;encrypt=disable"

	// 2. เปิดการเชื่อมต่อ Database
	db, err := sql.Open("sqlserver", connStr)
	if err != nil {
		log.Fatal("Error opening database: ", err)
	}
	defer db.Close()

	// 3. ตรวจสอบว่าเชื่อมต่อได้จริงหรือไม่ (Ping)
	err = db.Ping()
	if err != nil {
		log.Fatal("Cannot connect to database: ", err)
	}
	fmt.Println("Successfully connected to SQL Server!")

	// 4. จัดการ Routing สำหรับ Web Server
	// Serve static files with logging
	staticHandler := func(prefix, dir string) http.Handler {
		return http.StripPrefix(prefix, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			log.Printf("Static request: %s -> %s%s", r.URL.Path, dir, r.URL.Path)
			http.FileServer(http.Dir(dir)).ServeHTTP(w, r)
		}))
	}

	http.Handle("/assets/", staticHandler("/assets/", "ehongmd/assets/"))
	http.Handle("/images/", staticHandler("/images/", "ehongmd/images/"))
	http.Handle("/css/", staticHandler("/css/", "ehongmd/css/"))
	http.Handle("/js/", staticHandler("/js/", "ehongmd/js/"))

	// Login Handler
	http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			http.Redirect(w, r, "/ehongmd/index.html", http.StatusSeeOther)
			return
		}

		user := r.FormValue("USER")
		pass := r.FormValue("PASS")

		log.Printf("Login attempt for user: %s", user)

		var emp Employee
		err := db.QueryRow(`
			SELECT EMP_ID, US_NAME, BARCODE, US_PASSWD, TNAME, FNAME, LNAME, NICK 
			FROM EHONGDB.dbo.EMPLOYEE 
			WHERE EM_STATUS = 'NM' 
			AND (US_NAME = @p1 OR BARCODE = @p2) 
			AND US_PASSWD = @p3
		`, user, user, pass).Scan(&emp.EMP_ID, &emp.US_NAME, &emp.BARCODE, &emp.US_PASSWD, &emp.TNAME, &emp.FNAME, &emp.LNAME, &emp.NICK)

		if err != nil {
			if err == sql.ErrNoRows {
				log.Printf("Login failed for user: %s (Invalid credentials)", user)
				http.Redirect(w, r, "/ehongmd/index.html?error=invalid", http.StatusSeeOther)
			} else {
				log.Printf("Database error during login: %v", err)
				http.Error(w, "Database error", http.StatusInternalServerError)
			}
			return
		}

		log.Printf("Login successful for: %s (%s %s)", emp.US_NAME, emp.FNAME, emp.LNAME)

		// Create session
		session, _ := store.Get(r, "ehong-session")
		session.Values["user_id"] = emp.EMP_ID
		session.Values["user_name"] = emp.US_NAME
		session.Values["full_name"] = emp.FNAME + " " + emp.LNAME
		session.Save(r, w)

		// Redirect to main
		http.Redirect(w, r, "/ehongmd/main", http.StatusSeeOther)
	})

	// Logout Handler
	http.HandleFunc("/logout", func(w http.ResponseWriter, r *http.Request) {
		session, _ := store.Get(r, "ehong-session")
		session.Options.MaxAge = -1
		session.Save(r, w)
		http.Redirect(w, r, "/ehongmd/index.html", http.StatusSeeOther)
	})

	// Save Location Handler
	http.HandleFunc("/save_location_rap", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_2", http.StatusSeeOther)
			return
		}

		rapName := r.FormValue("locationName")
		rapPrice := r.FormValue("rentalPrice")
		prCode := r.FormValue("province")
		rapStatus := r.FormValue("status")

		now := time.Now()
		// ปี 26 (ถ้าปีปัจจุบันคือ 2026, เอาสองตัวท้าย)
		yearStr := fmt.Sprintf("%02d", now.Year()%100)
		monthStr := fmt.Sprintf("%02d", now.Month())
		prefix := "L" + yearStr + monthStr

		var maxId sql.NullString
		err := db.QueryRow("SELECT MAX(RAP_IDNAME) FROM CONFIG.dbo.LOCATION_RAP WHERE RAP_IDNAME LIKE @p1", prefix+"%").Scan(&maxId)

		seq := 0
		if err == nil && maxId.Valid && len(maxId.String) >= 8 {
			lastSeqStr := maxId.String[5:]
			if lastSeq, err := strconv.Atoi(lastSeqStr); err == nil {
				seq = lastSeq
			}
		}
		seq++
		newId := fmt.Sprintf("%s%03d", prefix, seq)

		var maxRapId sql.NullInt64
		err = db.QueryRow("SELECT MAX(RAP_ID) FROM CONFIG.dbo.LOCATION_RAP").Scan(&maxRapId)
		rapId := 1
		if err == nil && maxRapId.Valid {
			rapId = int(maxRapId.Int64) + 1
		}

		_, err = db.Exec(`
			INSERT INTO CONFIG.dbo.LOCATION_RAP (RAP_ID, RAP_IDNAME, RAP_NAME, RAP_PRICE, PR_CODE, RAP_STATUS)
			VALUES (@p1, @p2, @p3, @p4, @p5, @p6)
		`, rapId, newId, rapName, rapPrice, prCode, rapStatus)

		if err != nil {
			log.Printf("Error saving location: %v", err)
			http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_2?error=1", http.StatusSeeOther)
			return
		}

		http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_2?success=1", http.StatusSeeOther)
	})

	// Save Location RF Handler
	http.HandleFunc("/save_location_rf", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_3", http.StatusSeeOther)
			return
		}

		if err := r.ParseMultipartForm(10 << 20); err != nil {
			log.Printf("Error parsing multipart form: %v", err)
			http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_3?error=form", http.StatusSeeOther)
			return
		}

		rapIdName := r.FormValue("rapIdName")
		rfM := r.FormValue("rfM")
		rfY := r.FormValue("rfY")
		payAmount := r.FormValue("payAmount")
		rfNote := r.FormValue("rfNote")

		file, handler, err := r.FormFile("rfImg")
		var fileName string
		if err == nil {
			defer file.Close()

			uploadDir := "ehongmd/images/slips"
			os.MkdirAll(uploadDir, os.ModePerm)

			ext := filepath.Ext(handler.Filename)
			timestamp := time.Now().Format("20060102150405")
			fileName = fmt.Sprintf("slip_%s_%s_%s_%s%s", rapIdName, rfY, rfM, timestamp, ext)

			filePath := filepath.Join(uploadDir, fileName)
			out, err := os.Create(filePath)
			if err == nil {
				defer out.Close()
				io.Copy(out, file)
			} else {
				log.Printf("Error saving file: %v", err)
			}
		}

		_, err = db.Exec(`
			INSERT INTO CONFIG.dbo.LOCATION_RF (RAP_IDNAME, RF_M, RF_Y, RF_IMG, RF_PRICE, RF_NOTE)
			VALUES (@p1, @p2, @p3, @p4, @p5, @p6)
		`, rapIdName, rfM, rfY, fileName, payAmount, rfNote)

		if err != nil {
			log.Printf("Error saving location_rf: %v", err)
			http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_3?error=save", http.StatusSeeOther)
			return
		}

		http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_3?success=save", http.StatusSeeOther)
	})

	// Delete Location RF Handler
	http.HandleFunc("/delete_location_rf", func(w http.ResponseWriter, r *http.Request) {
		rfId := r.URL.Query().Get("id")
		if rfId != "" {
			var imgName sql.NullString
			err := db.QueryRow("SELECT RF_IMG FROM CONFIG.dbo.LOCATION_RF WHERE RF_ID=@p1", rfId).Scan(&imgName)
			if err == nil && imgName.Valid && imgName.String != "" {
				filePath := filepath.Join("ehongmd/images/slips", imgName.String)
				os.Remove(filePath)
			}

			_, err = db.Exec("DELETE FROM CONFIG.dbo.LOCATION_RF WHERE RF_ID=@p1", rfId)
			if err != nil {
				log.Printf("Error deleting location_rf: %v", err)
				http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_3?error=delete", http.StatusSeeOther)
				return
			}
			http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_3?success=delete", http.StatusSeeOther)
		} else {
			http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_3", http.StatusSeeOther)
		}
	})

	// Update Location RF Handler
	http.HandleFunc("/update_location_rf", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_3", http.StatusSeeOther)
			return
		}

		if err := r.ParseMultipartForm(10 << 20); err != nil {
			log.Printf("Error parsing multipart form: %v", err)
			http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_3?error=form", http.StatusSeeOther)
			return
		}

		rfId := r.FormValue("rfId")
		rapIdName := r.FormValue("rapIdName")
		rfM := r.FormValue("rfM")
		rfY := r.FormValue("rfY")
		payAmount := r.FormValue("payAmount")
		rfNoteP := r.FormValue("rfNoteP")

		// Handle file upload
		file, handler, err := r.FormFile("rfImg")
		var fileName string
		var hasNewImg bool = false

		if err == nil {
			defer file.Close()
			hasNewImg = true

			uploadDir := "ehongmd/images/slips"
			os.MkdirAll(uploadDir, os.ModePerm)

			ext := filepath.Ext(handler.Filename)
			timestamp := time.Now().Format("20060102150405")
			fileName = fmt.Sprintf("slip_%s_%s_%s_%s%s", rapIdName, rfY, rfM, timestamp, ext)

			filePath := filepath.Join(uploadDir, fileName)
			out, err := os.Create(filePath)
			if err == nil {
				defer out.Close()
				io.Copy(out, file)
			} else {
				log.Printf("Error saving file: %v", err)
				hasNewImg = false
			}
		}

		if hasNewImg {
			// If there was an old image, delete it
			var oldImg sql.NullString
			err = db.QueryRow("SELECT RF_IMG FROM CONFIG.dbo.LOCATION_RF WHERE RF_ID=@p1", rfId).Scan(&oldImg)
			if err == nil && oldImg.Valid && oldImg.String != "" {
				oldPath := filepath.Join("ehongmd/images/slips", oldImg.String)
				os.Remove(oldPath)
			}

			_, err = db.Exec(`
				UPDATE CONFIG.dbo.LOCATION_RF 
				SET RAP_IDNAME=@p1, RF_M=@p2, RF_Y=@p3, RF_IMG=@p4, RF_PRICE=@p5, RF_NOTE_P=@p6 
				WHERE RF_ID=@p7
			`, rapIdName, rfM, rfY, fileName, payAmount, rfNoteP, rfId)
		} else {
			_, err = db.Exec(`
				UPDATE CONFIG.dbo.LOCATION_RF 
				SET RAP_IDNAME=@p1, RF_M=@p2, RF_Y=@p3, RF_PRICE=@p4, RF_NOTE_P=@p5 
				WHERE RF_ID=@p6
			`, rapIdName, rfM, rfY, payAmount, rfNoteP, rfId)
		}

		if err != nil {
			log.Printf("Error updating location_rf: %v", err)
			http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_3?error=update", http.StatusSeeOther)
			return
		}

		http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_3?success=update", http.StatusSeeOther)
	})

	// Update Location Handler
	http.HandleFunc("/update_location_rap", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_2", http.StatusSeeOther)
			return
		}

		rapId := r.FormValue("rapId")
		rapName := r.FormValue("locationName")
		rapPrice := r.FormValue("rentalPrice")
		prCode := r.FormValue("province")
		rapStatus := r.FormValue("status")

		_, err := db.Exec(`
			UPDATE CONFIG.dbo.LOCATION_RAP 
			SET RAP_NAME=@p1, RAP_PRICE=@p2, PR_CODE=@p3, RAP_STATUS=@p4 
			WHERE RAP_ID=@p5
		`, rapName, rapPrice, prCode, rapStatus, rapId)

		if err != nil {
			log.Printf("Error updating location: %v", err)
			http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_2?error=update", http.StatusSeeOther)
			return
		}

		http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_2?success=update", http.StatusSeeOther)
	})

	// Delete Location Handler
	http.HandleFunc("/delete_location_rap", func(w http.ResponseWriter, r *http.Request) {
		rapId := r.URL.Query().Get("id")
		if rapId != "" {
			_, err := db.Exec("DELETE FROM CONFIG.dbo.LOCATION_RAP WHERE RAP_ID=@p1", rapId)
			if err != nil {
				log.Printf("Error deleting location: %v", err)
				http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_2?error=delete", http.StatusSeeOther)
				return
			}
			http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_2?success=delete", http.StatusSeeOther)
		} else {
			http.Redirect(w, r, "/ehongmd/ehongmd/main_1/index_2", http.StatusSeeOther)
		}
	})

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		path := r.URL.Path

		// Check session for backend pages
		if strings.HasPrefix(path, "/ehongmd/") &&
			!strings.HasSuffix(path, "index.html") &&
			!strings.Contains(path, "/css/") &&
			!strings.Contains(path, "/js/") &&
			!strings.Contains(path, "/images/") {

			session, _ := store.Get(r, "ehong-session")
			if auth, ok := session.Values["user_id"].(string); !ok || auth == "" {
				log.Printf("Unauthorized access attempt to: %s", path)
				http.Redirect(w, r, "/ehongmd/index.html", http.StatusSeeOther)
				return
			}
		}

		if path == "/" {
			http.ServeFile(w, r, "ehongmd/index.html")
			return
		}

		// Remove leading slash for local file path
		cleanPath := strings.TrimPrefix(path, "/")

		// Determine the base name without extension for matching
		basePath := strings.TrimSuffix(cleanPath, ".html")
		basePath = strings.TrimSuffix(basePath, "/") // Trim trailing slash
		if basePath == "" {
			basePath = "index"
		}

		// If path has no extension or is .html, try processing as template
		ext := filepath.Ext(cleanPath)
		if ext == "" || ext == ".html" || strings.HasSuffix(cleanPath, "/") {
			htmlFile := basePath + ".html"
			if _, err := os.Stat(htmlFile); err == nil {
				// Prepare template data
				type UserInfo struct {
					UserID   string
					UserName string
					FullName string
				}

				session, _ := store.Get(r, "ehong-session")
				var user UserInfo
				if uid, ok := session.Values["user_id"].(string); ok {
					user.UserID = uid
					user.UserName = session.Values["user_name"].(string)
					user.FullName = session.Values["full_name"].(string)
				}

				templateData := make(map[string]interface{})
				// Prepare Thai Date
				thaiMonths := []string{
					"มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน",
					"กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม",
				}
				now := time.Now()
				thaiYear := now.Year() + 543
				thaiMonth := thaiMonths[now.Month()-1]
				templateData["CurrentDate"] = fmt.Sprintf("%d %s %d", now.Day(), thaiMonth, thaiYear)

				templateData["User"] = user
				templateData["CurrentYear"] = now.Year()
				templateData["CurrentPage"] = filepath.Base(basePath)
				templateData["FullPage"] = basePath

				if strings.Contains(basePath, "main_1") {
					templateData["MenuArea"] = "main_1"
				}

				if basePath == "ehongmd/ehongmd/main_1/index" {
					yearStr := r.URL.Query().Get("year")
					prCodeFilter := r.URL.Query().Get("province")
					statusFilter := r.URL.Query().Get("status")
					
					if yearStr == "" {
						yearStr = strconv.Itoa(now.Year()) // use current year
					}
					templateData["SelectedYear"] = yearStr
					templateData["SelectedProvince"] = prCodeFilter
					templateData["SelectedStatus"] = statusFilter

					// Fetch Provinces
					provRows, err := db.Query("SELECT PR_CODE, PR_NAME FROM EHONGDB.dbo.PROV ORDER BY PR_NAME")
					if err == nil {
						var provinces []Province
						for provRows.Next() {
							var p Province
							if err := provRows.Scan(&p.PR_CODE, &p.PR_NAME); err == nil {
								provinces = append(provinces, p)
							}
						}
						provRows.Close()
						templateData["Provinces"] = provinces
					}

					// Fetch Statuses
					statusRows, err := db.Query("SELECT RAP_ID, RAP_NAMESTATUS FROM CONFIG.dbo.RAP_STATUS ORDER BY RAP_ID")
					if err == nil {
						var statuses []Status
						for statusRows.Next() {
							var s Status
							if err := statusRows.Scan(&s.RAP_ID, &s.RAP_NAMESTATUS); err == nil {
								statuses = append(statuses, s)
							}
						}
						statusRows.Close()
						templateData["Statuses"] = statuses
					}

					// Build the pivot data
					query := `
						SELECT l.RAP_ID, l.RAP_IDNAME, l.RAP_NAME, l.RAP_PRICE, l.PR_CODE, p.PR_NAME, l.RAP_STATUS, s.RAP_NAMESTATUS
						FROM CONFIG.dbo.LOCATION_RAP l
						LEFT JOIN EHONGDB.dbo.PROV p ON l.PR_CODE = p.PR_CODE
						LEFT JOIN CONFIG.dbo.RAP_STATUS s ON l.RAP_STATUS = s.RAP_ID
						WHERE 1=1
					`
					var args []interface{}
					paramID := 1
					
					if prCodeFilter != "" {
						query += fmt.Sprintf(" AND l.PR_CODE = @p%d", paramID)
						args = append(args, prCodeFilter)
						paramID++
					}
					if statusFilter != "" {
						query += fmt.Sprintf(" AND l.RAP_STATUS = @p%d", paramID)
						args = append(args, statusFilter)
						paramID++
					}
					
					query += " ORDER BY l.RAP_ID ASC"

					locRows, err := db.Query(query, args...)
					
					var reportRows []ReportRow
					if err == nil {
						no := 1
						for locRows.Next() {
							var loc Location
							var prName sql.NullString
							var rapNameStatus sql.NullString
							var prCode sql.NullString
							var rapStatus sql.NullString
							if err := locRows.Scan(&loc.RAP_ID, &loc.RAP_IDNAME, &loc.RAP_NAME, &loc.RAP_PRICE, &prCode, &prName, &rapStatus, &rapNameStatus); err == nil {
								loc.PR_CODE = prCode.String
								loc.PR_NAME = prName.String
								loc.RAP_STATUS = rapStatus.String
								loc.RAP_NAMESTATUS = rapNameStatus.String
								
								note := ""
								if loc.RAP_STATUS == "0" {
									note = "ว่าง"
								}

								reportRows = append(reportRows, ReportRow{
									No:       no,
									Location: loc,
									Note:     note,
								})
								no++
							}
						}
						locRows.Close()

						// Fetch payments
						rfRows, err := db.Query(`
							SELECT RAP_IDNAME, RF_M, COALESCE(RF_PRICE, '0') 
							FROM CONFIG.dbo.LOCATION_RF 
							WHERE RF_Y = @p1
						`, yearStr)
						
						if err == nil {
							for rfRows.Next() {
								var rapIdName string
								var rfM string
								var rfPrice string
								if err := rfRows.Scan(&rapIdName, &rfM, &rfPrice); err == nil {
									monthInt, _ := strconv.Atoi(rfM)
									if monthInt >= 1 && monthInt <= 12 {
										for i := range reportRows {
											if reportRows[i].Location.RAP_IDNAME == rapIdName {
												priceFloat, err := strconv.ParseFloat(rfPrice, 64)
												if err == nil {
													existingStr := reportRows[i].Payments[monthInt-1]
													existingFloat, _ := strconv.ParseFloat(existingStr, 64)
													newSum := existingFloat + priceFloat

													if newSum == float64(int64(newSum)) {
														reportRows[i].Payments[monthInt-1] = fmt.Sprintf("%.0f", newSum)
													} else {
														reportRows[i].Payments[monthInt-1] = fmt.Sprintf("%.2f", newSum)
													}
												} else if reportRows[i].Payments[monthInt-1] == "" {
													reportRows[i].Payments[monthInt-1] = rfPrice
												}
												break
											}
										}
									}
								}
							}
							rfRows.Close()
						}
						templateData["ReportRows"] = reportRows
					} else {
						log.Println("Error fetching locations for index report:", err)
					}
				}

				if basePath == "ehongmd/ehongmd/main_1/index_2" {
					rows, err := db.Query("SELECT PR_CODE, PR_NAME FROM EHONGDB.dbo.PROV ORDER BY PR_NAME")
					if err == nil {
						var provinces []Province
						for rows.Next() {
							var p Province
							if err := rows.Scan(&p.PR_CODE, &p.PR_NAME); err == nil {
								provinces = append(provinces, p)
							}
						}
						rows.Close()
						templateData["Provinces"] = provinces
					} else {
						log.Println("Error fetching provinces:", err)
					}

					statusRows, err := db.Query("SELECT RAP_ID, RAP_NAMESTATUS FROM CONFIG.dbo.RAP_STATUS ORDER BY RAP_ID")
					if err == nil {
						var statuses []Status
						for statusRows.Next() {
							var s Status
							if err := statusRows.Scan(&s.RAP_ID, &s.RAP_NAMESTATUS); err == nil {
								statuses = append(statuses, s)
							}
						}
						statusRows.Close()
						templateData["Statuses"] = statuses
					} else {
						log.Println("Error fetching statuses:", err)
					}

					locRows, err := db.Query(`
						SELECT l.RAP_ID, l.RAP_IDNAME, l.RAP_NAME, l.RAP_PRICE, l.PR_CODE, p.PR_NAME, l.RAP_STATUS, s.RAP_NAMESTATUS
						FROM CONFIG.dbo.LOCATION_RAP l
						LEFT JOIN EHONGDB.dbo.PROV p ON l.PR_CODE = p.PR_CODE
						LEFT JOIN CONFIG.dbo.RAP_STATUS s ON l.RAP_STATUS = s.RAP_ID
						ORDER BY l.RAP_ID DESC
					`)
					if err == nil {
						var locations []Location
						for locRows.Next() {
							var loc Location
							var prName sql.NullString
							var rapNameStatus sql.NullString
							var prCode sql.NullString
							var rapStatus sql.NullString
							if err := locRows.Scan(&loc.RAP_ID, &loc.RAP_IDNAME, &loc.RAP_NAME, &loc.RAP_PRICE, &prCode, &prName, &rapStatus, &rapNameStatus); err == nil {
								loc.PR_CODE = prCode.String
								loc.PR_NAME = prName.String
								loc.RAP_STATUS = rapStatus.String
								loc.RAP_NAMESTATUS = rapNameStatus.String
								locations = append(locations, loc)
							}
						}
						locRows.Close()
						templateData["Locations"] = locations
					} else {
						log.Println("Error fetching locations:", err)
					}
				}

				if basePath == "ehongmd/ehongmd/main_1/index_3" {
					locRows, err := db.Query(`
						SELECT l.RAP_ID, l.RAP_IDNAME, l.RAP_NAME, l.RAP_PRICE, l.PR_CODE, p.PR_NAME, l.RAP_STATUS, s.RAP_NAMESTATUS
						FROM CONFIG.dbo.LOCATION_RAP l
						LEFT JOIN EHONGDB.dbo.PROV p ON l.PR_CODE = p.PR_CODE
						LEFT JOIN CONFIG.dbo.RAP_STATUS s ON l.RAP_STATUS = s.RAP_ID
						ORDER BY l.RAP_NAME
					`)
					if err == nil {
						var locations []Location
						for locRows.Next() {
							var loc Location
							var prName sql.NullString
							var rapNameStatus sql.NullString
							var prCode sql.NullString
							var rapStatus sql.NullString
							if err := locRows.Scan(&loc.RAP_ID, &loc.RAP_IDNAME, &loc.RAP_NAME, &loc.RAP_PRICE, &prCode, &prName, &rapStatus, &rapNameStatus); err == nil {
								loc.PR_CODE = prCode.String
								loc.PR_NAME = prName.String
								loc.RAP_STATUS = rapStatus.String
								loc.RAP_NAMESTATUS = rapNameStatus.String
								locations = append(locations, loc)
							}
						}
						locRows.Close()
						templateData["Locations"] = locations
					} else {
						log.Println("Error fetching locations for index_3:", err)
					}

					rfRows, err := db.Query(`
						SELECT rf.RF_ID, rf.RAP_IDNAME, l.RAP_NAME, rf.RF_M, rf.RF_Y, rf.RF_IMG, COALESCE(l.RAP_ID, 0), COALESCE(l.RAP_PRICE, 0), ISNULL(rf.RF_PRICE, ''), ISNULL(rf.RF_NOTE, ''), ISNULL(rf.RF_NOTE_P, '')
						FROM CONFIG.dbo.LOCATION_RF rf
						LEFT JOIN CONFIG.dbo.LOCATION_RAP l ON rf.RAP_IDNAME = l.RAP_IDNAME
						ORDER BY rf.RF_ID DESC
					`)
					if err == nil {
						var rfPayments []LocationRF
						for rfRows.Next() {
							var rf LocationRF
							var rapName sql.NullString
							if err := rfRows.Scan(&rf.RF_ID, &rf.RAP_IDNAME, &rapName, &rf.RF_M, &rf.RF_Y, &rf.RF_IMG, &rf.RAP_ID, &rf.RAP_PRICE, &rf.RF_PRICE, &rf.RF_NOTE, &rf.RF_NOTE_P); err == nil {
								rf.RAP_NAME = rapName.String
								rfPayments = append(rfPayments, rf)
							}
						}
						rfRows.Close()
						templateData["RFPayments"] = rfPayments
					} else {
						log.Println("Error fetching LOCATION_RF for index_3:", err)
					}
				}

				// Use Go Template to include navbar, footer, etc.
				tmplFiles := []string{
					htmlFile,
					// "templates/navbar.html",
					// "templates/footer.html",
					// "templates/head_links.html",
					"ehongmd/templates/backend_head.html",
					"ehongmd/templates/backend_header.html",
					"ehongmd/templates/backend_menu.html",
					"ehongmd/templates/backend_footer.html",
					"ehongmd/templates/backend_js.html",
				}
				tmpl, err := template.ParseFiles(tmplFiles...)
				if err != nil {
					log.Println("Error parsing templates:", err)
					http.Error(w, err.Error(), http.StatusInternalServerError)
					return
				}
				err = tmpl.Execute(w, templateData)
				if err != nil {
					log.Println("Error executing template:", err)
				}
				return
			}
		}

		// Fallback to ServeFile for assets or specific extensions
		fPath := "." + r.URL.Path
		if _, err := os.Stat(fPath); os.IsNotExist(err) {
			fPath = "ehongmd" + r.URL.Path
		}
		log.Printf("Serving file: %s -> %s", r.URL.Path, fPath)
		http.ServeFile(w, r, fPath)
	})

	// 5. กำหนด Port และรัน Server
	fmt.Println("✅ Server running at http://localhost:9211")
	log.Fatal(http.ListenAndServe(":9211", nil))
}
