package handlers

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"strings"

	"furry-sos-backend/config"
)

// ======================================================
// GET VOLUNTEER CASES
// ======================================================
func GetVolunteerCases(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	w.Header().Set("Content-Type", "application/json; charset=utf-8")

	userID, err := getVolunteerUserID(r)
	if err != nil {
		json.NewEncoder(w).Encode(map[string]interface{}{
			"success": false,
			"message": "ไม่พบ User ID",
		})
		return
	}

	role, err := getUserRole(userID)
	if err != nil {
		http.Error(w, "ไม่พบข้อมูลผู้ใช้งาน", http.StatusNotFound)
		return
	}

	if role != "volunteer" {
		http.Error(w, "บัญชีนี้ไม่ใช่อาสาสมัคร", http.StatusForbidden)
		return
	}

	var workingArea string
	err = config.DB.QueryRow(`
		SELECT COALESCE(working_area, '')
		FROM volunteers
		WHERE user_id = ? AND is_approved = 1
		LIMIT 1
	`, userID).Scan(&workingArea)

	if err != nil {
		http.Error(w, "ไม่พบข้อมูลพื้นที่ของอาสาสมัคร", http.StatusNotFound)
		return
	}

	workingArea = strings.TrimSpace(workingArea)

	query := `
		SELECT report_id, case_code, animal_type, injury_type, injury_description, 
		       severity_level, location_lat, location_lng, location_address, province, 
		       image_url, status, created_at
		FROM emergency_reports
		WHERE status = 'pending' AND assigned_volunteer_id IS NULL AND TRIM(province) = ?
		ORDER BY created_at DESC
	`

	rows, err := config.DB.Query(query, workingArea)
	if err != nil {
		http.Error(w, "ไม่สามารถโหลดรายการงานได้", http.StatusInternalServerError)
		return
	}
	defer rows.Close()

	cases := make([]map[string]interface{}, 0)

	for rows.Next() {
		var (
			reportID          int
			caseCode          string
			animalType        string
			injuryType        string
			injuryDescription string
			severityLevel     string
			locationLat       float64
			locationLng       float64
			locationAddress   string
			province          string
			imageURL          string
			status            string
			createdAt         interface{}
		)

		err := rows.Scan(
			&reportID, &caseCode, &animalType, &injuryType, &injuryDescription,
			&severityLevel, &locationLat, &locationLng, &locationAddress, &province,
			&imageURL, &status, &createdAt,
		)
		if err != nil {
			continue
		}

		severityLevel = normalizeVolunteerSeverity(severityLevel)

		cases = append(cases, map[string]interface{}{
			"report_id":          reportID,
			"case_code":          caseCode,
			"animal_type":        animalType,
			"injury_type":        injuryType,
			"injury_description": injuryDescription,
			"severity_level":     severityLevel,
			"location_lat":       locationLat,
			"location_lng":       locationLng,
			"location_address":   locationAddress,
			"province":           province,
			"image_url":          imageURL,
			"status":             status,
			"created_at":         createdAt,
		})
	}

	json.NewEncoder(w).Encode(map[string]interface{}{
		"success":      true,
		"user_id":      userID,
		"working_area": workingArea,
		"count":        len(cases),
		"cases":        cases,
	})
}

// ======================================================
// GET VOLUNTEER USER ID
// ======================================================
func getVolunteerUserID(r *http.Request) (int, error) {
	userIDStr := strings.TrimSpace(r.Header.Get("X-User-ID"))
	if userIDStr == "" {
		userIDStr = strings.TrimSpace(r.URL.Query().Get("user_id"))
	}
	if userIDStr == "" {
		return 0, fmt.Errorf("missing user id")
	}

	userID, err := strconv.Atoi(userIDStr)
	if err != nil {
		return 0, err
	}
	if userID <= 0 {
		return 0, fmt.Errorf("invalid user id")
	}
	return userID, nil
}

// ======================================================
// ACCEPT VOLUNTEER CASE (แก้ไขแล้ว — ลบ tracking ซ้ำ)
// ======================================================
func AcceptVolunteerCase(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")

	if r.Method != http.MethodPost {
		w.WriteHeader(http.StatusMethodNotAllowed)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "Method not allowed"})
		return
	}

	userID, err := getVolunteerUserID(r)
	if err != nil {
		w.WriteHeader(http.StatusUnauthorized)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "ไม่พบ User ID"})
		return
	}

	role, err := getUserRole(userID)
	if err != nil || role != "volunteer" {
		w.WriteHeader(http.StatusForbidden)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "บัญชีนี้ไม่ใช่อาสาสมัคร"})
		return
	}

	var (
		volunteerID int
		workingArea string
	)

	err = config.DB.QueryRow(`
		SELECT volunteer_id, COALESCE(working_area, '')
		FROM volunteers
		WHERE user_id = ? AND is_approved = 1
		LIMIT 1
	`, userID).Scan(&volunteerID, &workingArea)

	if err != nil {
		w.WriteHeader(http.StatusNotFound)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "ไม่พบข้อมูลอาสาสมัคร"})
		return
	}

	workingArea = strings.TrimSpace(workingArea)

	var body struct {
		ReportID int `json:"report_id"`
		CaseID   int `json:"case_id"`
	}
	if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "ข้อมูลไม่ถูกต้อง"})
		return
	}

	reportID := body.ReportID
	if reportID <= 0 {
		reportID = body.CaseID
	}
	if reportID <= 0 {
		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "ไม่พบ case_id"})
		return
	}

	tx, err := config.DB.Begin()
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "เริ่ม Transaction ไม่ได้"})
		return
	}
	defer tx.Rollback()

	var (
		caseCode      string
		caseProvince  string
		reportUserID  int
		currentStatus string
	)

	err = tx.QueryRow(`
		SELECT COALESCE(case_code, ''), COALESCE(province, ''), user_id, COALESCE(status, '')
		FROM emergency_reports
		WHERE report_id = ? AND assigned_volunteer_id IS NULL
		LIMIT 1
	`, reportID).Scan(&caseCode, &caseProvince, &reportUserID, &currentStatus)

	if err != nil {
		w.WriteHeader(http.StatusConflict)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "เคสนี้ถูกรับไปแล้ว หรือไม่พบเคส"})
		return
	}

	if strings.TrimSpace(caseProvince) != workingArea {
		w.WriteHeader(http.StatusForbidden)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "เคสนี้อยู่นอกพื้นที่"})
		return
	}

	// 1. อัปเดต emergency_reports → accepted
	result, err := tx.Exec(`
		UPDATE emergency_reports
		SET assigned_volunteer_id = ?, status = 'accepted', updated_at = NOW()
		WHERE report_id = ? AND status = 'pending' AND assigned_volunteer_id IS NULL
	`, volunteerID, reportID)

	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": err.Error()})
		return
	}

	affected, _ := result.RowsAffected()
	if affected == 0 {
		w.WriteHeader(http.StatusConflict)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "เคสนี้ถูกรับไปแล้ว"})
		return
	}

	// 2. ปิด tracking เก่า (ทำครั้งเดียว)
	_, err = tx.Exec(`
		UPDATE case_tracking
		SET is_current = 0
		WHERE report_id = ? AND report_type = 'emergency' AND is_current = 1
	`, reportID)

	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		json.NewEncoder(w).Encode(map[string]interface{}{
			"success": false,
			"message": "อัปเดต tracking เก่าไม่สำเร็จ: " + err.Error(),
		})
		return
	}

	// 3. บันทึก case_assignments
	_, err = tx.Exec(`
		INSERT INTO case_assignments
		(report_id, volunteer_id, report_type, accepted_at, status, created_at, updated_at)
		VALUES (?, ?, 'emergency', NOW(), 'accepted', NOW(), NOW())
	`, reportID, volunteerID)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "บันทึก case_assignments ไม่สำเร็จ"})
		return
	}

	// 4. Insert tracking ใหม่ (ครั้งเดียว)
	_, err = tx.Exec(`
		INSERT INTO case_tracking
		(report_id, report_type, status, status_description, status_order, is_current, created_by, created_at)
		VALUES (?, 'emergency', 'accepted', 'รับเคสแล้ว', 1, 1, 'volunteer', NOW())
	`, reportID)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "บันทึก tracking ไม่สำเร็จ"})
		return
	}

	// 5. Notification
	tx.Exec(`
		INSERT INTO notifications (user_id, title, message, reference_id, is_read, created_at)
		VALUES (?, ?, ?, ?, 0, NOW())
	`, reportUserID, "มีอาสาสมัครรับเคสแล้ว", "เคส "+caseCode+" มีอาสาสมัครรับงานแล้ว", reportID)

	if err := tx.Commit(); err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "commit ไม่สำเร็จ"})
		return
	}

	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(map[string]interface{}{
		"success":      true,
		"message":      "รับเคสสำเร็จ",
		"report_id":    reportID,
		"case_code":    caseCode,
		"volunteer_id": volunteerID,
		"status":       "accepted",
	})
}

// ======================================================
// UPDATE VOLUNTEER CASE STATUS
// ======================================================
func UpdateVolunteerCaseStatus(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")

	if r.Method != http.MethodPost {
		w.WriteHeader(http.StatusMethodNotAllowed)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "Method not allowed"})
		return
	}

	userID, err := getVolunteerUserID(r)
	if err != nil {
		w.WriteHeader(http.StatusUnauthorized)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "ไม่พบ User ID"})
		return
	}

	role, err := getUserRole(userID)
	if err != nil || role != "volunteer" {
		w.WriteHeader(http.StatusForbidden)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "บัญชีนี้ไม่ใช่อาสาสมัคร"})
		return
	}

	var volunteerID int
	err = config.DB.QueryRow(`
		SELECT volunteer_id FROM volunteers
		WHERE user_id = ? AND is_approved = 1 LIMIT 1
	`, userID).Scan(&volunteerID)

	if err != nil {
		w.WriteHeader(http.StatusNotFound)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "ไม่พบข้อมูลอาสาสมัคร"})
		return
	}

	var body struct {
		CaseID int    `json:"case_id"`
		Status string `json:"status"`
	}
	if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "ข้อมูลไม่ถูกต้อง"})
		return
	}

	var statusDesc string
	var statusOrder int
	switch body.Status {
	case "accepted":
		statusDesc = "รับเคสแล้ว"
		statusOrder = 1
	case "arriving":
		statusDesc = "กำลังเดินทาง"
		statusOrder = 2
	case "arrived":
		statusDesc = "ถึงจุดเกิดเหตุ"
		statusOrder = 3
	case "in_progress":
		statusDesc = "กำลังช่วยเหลือสัตว์"
		statusOrder = 4
	case "completed":
		statusDesc = "ส่งต่อ/เสร็จสิ้น"
		statusOrder = 5
	default:
		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "สถานะไม่ถูกต้อง"})
		return
	}

	tx, err := config.DB.Begin()
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "เริ่ม Transaction ไม่ได้"})
		return
	}
	defer tx.Rollback()

	result, err := tx.Exec(`
		UPDATE emergency_reports
		SET status = ?, updated_at = NOW()
		WHERE report_id = ? AND assigned_volunteer_id = ?
	`, body.Status, body.CaseID, volunteerID)

	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": err.Error()})
		return
	}

	affected, _ := result.RowsAffected()
	if affected == 0 {
		w.WriteHeader(http.StatusForbidden)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "ไม่พบเคสนี้ หรือคุณไม่ใช่ผู้รับผิดชอบ"})
		return
	}

	tx.Exec(`
		UPDATE case_assignments
		SET status = ?, updated_at = NOW()
		WHERE report_id = ? AND volunteer_id = ?
	`, body.Status, body.CaseID, volunteerID)

	tx.Exec(`UPDATE case_tracking SET is_current = 0 WHERE report_id = ?`, body.CaseID)

	_, err = tx.Exec(`
		INSERT INTO case_tracking
		(report_id, report_type, status, status_description, status_order, is_current, created_by, created_at)
		VALUES (?, 'emergency', ?, ?, ?, 1, 'volunteer', NOW())
	`, body.CaseID, body.Status, statusDesc, statusOrder)

	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "บันทึก tracking ไม่สำเร็จ"})
		return
	}

	var reportUserID int
	var caseCode string
	tx.QueryRow("SELECT user_id, case_code FROM emergency_reports WHERE report_id = ?", body.CaseID).Scan(&reportUserID, &caseCode)

	tx.Exec(`
		INSERT INTO notifications (user_id, title, message, reference_id, is_read, created_at)
		VALUES (?, ?, ?, ?, 0, NOW())
	`, reportUserID, "อัปเดตสถานะเคส", "เคส "+caseCode+" : "+statusDesc, body.CaseID)

	if err := tx.Commit(); err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		json.NewEncoder(w).Encode(map[string]interface{}{"success": false, "message": "commit ไม่สำเร็จ"})
		return
	}

	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(map[string]interface{}{
		"success": true,
		"message": "อัปเดตสถานะสำเร็จ",
		"status":  body.Status,
	})
}

// ======================================================
// NORMALIZE SEVERITY
// ======================================================
func normalizeVolunteerSeverity(value string) string {
	value = strings.ToLower(strings.TrimSpace(value))
	switch value {
	case "critical", "emergency", "ด่วนมาก", "เร่งด่วนมาก", "วิกฤต":
		return "critical"
	case "high", "severe", "urgent", "สูง", "ด่วน", "เร่งด่วน", "รุนแรง":
		return "high"
	case "medium", "moderate", "ปานกลาง":
		return "medium"
	case "low", "normal", "ต่ำ", "ปกติ":
		return "low"
	default:
		return value
	}
}
