package handlers

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strings"
	"time"

	"crm-go/internal/storage"
	"crm-go/models"
)

type TrialPeriodHandler struct {
	storage         storage.TrialPeriodStorage
	customerStorage storage.CustomerStorage
	feishuWebhook   string
}

func NewTrialPeriodHandler(storage storage.TrialPeriodStorage, customerStorage storage.CustomerStorage, feishuWebhook string) *TrialPeriodHandler {
	return &TrialPeriodHandler{
		storage:         storage,
		customerStorage: customerStorage,
		feishuWebhook:   feishuWebhook,
	}
}

// GetTrialPeriodsByCustomer returns all trial periods for a specific customer
func (h *TrialPeriodHandler) GetTrialPeriodsByCustomer(w http.ResponseWriter, r *http.Request) {
	customerID := r.URL.Query().Get("customerId")
	if customerID == "" {
		http.Error(w, "Customer ID is required", http.StatusBadRequest)
		return
	}

	trialPeriods, err := h.storage.GetTrialPeriodsByCustomerID(customerID)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"trialPeriods": trialPeriods,
	})
}

// GetAllTrialPeriods returns all trial periods
func (h *TrialPeriodHandler) GetAllTrialPeriods(w http.ResponseWriter, r *http.Request) {
	trialPeriods, err := h.storage.GetAllTrialPeriods()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"trialPeriods": trialPeriods,
	})
}

// CreateTrialPeriod creates a new trial period
func (h *TrialPeriodHandler) CreateTrialPeriod(w http.ResponseWriter, r *http.Request) {
	var req models.CreateTrialPeriodRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "Invalid request body", http.StatusBadRequest)
		return
	}

	// Parse start and end times
	startTime, err := time.Parse(time.RFC3339, req.StartTime)
	if err != nil {
		http.Error(w, "Invalid start time format", http.StatusBadRequest)
		return
	}

	endTime, err := time.Parse(time.RFC3339, req.EndTime)
	if err != nil {
		http.Error(w, "Invalid end time format", http.StatusBadRequest)
		return
	}

	trialPeriod := models.TrialPeriod{
		CustomerName: req.CustomerName,
		Source:       req.Source,
		StartTime:    startTime,
		EndTime:      endTime,
		IsTrial:      req.IsTrial,
		CreatedAt:    time.Now(),
	}

	createdPeriod, err := h.storage.CreateTrialPeriod(trialPeriod)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Send Feishu notification
	if h.feishuWebhook != "" {
		go h.sendTrialNotification(req.CustomerName, startTime, endTime)
	}

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusCreated)
	json.NewEncoder(w).Encode(createdPeriod)
}

// UpdateTrialPeriod updates an existing trial period
func (h *TrialPeriodHandler) UpdateTrialPeriod(w http.ResponseWriter, r *http.Request) {
	urlPath := r.URL.Path
	pathParts := strings.Split(urlPath, "/")

	if len(pathParts) < 4 {
		http.Error(w, "Invalid URL format", http.StatusBadRequest)
		return
	}

	id := pathParts[3]
	if idx := strings.Index(id, "?"); idx != -1 {
		id = id[:idx]
	}

	var req models.UpdateTrialPeriodRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "Invalid request body", http.StatusBadRequest)
		return
	}

	// Get existing trial period for notification
	existingPeriod, err := h.storage.GetTrialPeriodByID(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if err := h.storage.UpdateTrialPeriod(id, req); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Send Feishu notification if updated
	if existingPeriod != nil && h.feishuWebhook != "" {
		var startTime, endTime time.Time
		if req.StartTime != nil {
			startTime, _ = time.Parse(time.RFC3339, *req.StartTime)
		} else {
			startTime = existingPeriod.StartTime
		}
		if req.EndTime != nil {
			endTime, _ = time.Parse(time.RFC3339, *req.EndTime)
		} else {
			endTime = existingPeriod.EndTime
		}
		go h.sendTrialNotification(existingPeriod.CustomerName, startTime, endTime)
	}

	w.WriteHeader(http.StatusOK)
}

// DeleteTrialPeriod deletes a trial period
func (h *TrialPeriodHandler) DeleteTrialPeriod(w http.ResponseWriter, r *http.Request) {
	urlPath := r.URL.Path
	pathParts := strings.Split(urlPath, "/")

	if len(pathParts) < 4 {
		http.Error(w, "Invalid URL format", http.StatusBadRequest)
		return
	}

	id := pathParts[3]
	if idx := strings.Index(id, "?"); idx != -1 {
		id = id[:idx]
	}

	if err := h.storage.DeleteTrialPeriod(id); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusOK)
}

// sendTrialNotification sends a rich Feishu card notification
func (h *TrialPeriodHandler) sendTrialNotification(customerName string, startTime, endTime time.Time) {
	if h.feishuWebhook == "" {
		return
	}

	// Calculate days until expiry
	now := time.Now()
	today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
	endDateOnly := time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, endTime.Location())
	daysUntilExpiry := int(endDateOnly.Sub(today).Hours() / 24)

	// Only send notification if expiring within 3 days
	if daysUntilExpiry < 0 || daysUntilExpiry > 3 {
		return
	}

	// customerName is already passed as parameter, no need to lookup
	// Just use it directly for notification

	// Determine urgency level and message based on days until expiry
	var title, urgencyLevel, urgencyColor, expiryText string
	switch daysUntilExpiry {
	case 0:
		title = "🔴 试用今日到期提醒"
		urgencyLevel = "紧急"
		urgencyColor = "red"
		expiryText = "今天"
	case 1:
		title = "🟠 试用明日到期提醒"
		urgencyLevel = "重要"
		urgencyColor = "orange"
		expiryText = "明天"
	case 2:
		title = "🟡 试用即将到期提醒"
		urgencyLevel = "提醒"
		urgencyColor = "blue"
		expiryText = "2天后"
	case 3:
		title = "🔵 试用即将到期提醒"
		urgencyLevel = "提醒"
		urgencyColor = "blue"
		expiryText = "3天后"
	default:
		title = "📅 试用到期提醒"
		urgencyLevel = "提醒"
		urgencyColor = "blue"
		expiryText = fmt.Sprintf("%d天后", daysUntilExpiry)
	}

	// Format trial period
	trialPeriod := fmt.Sprintf("%d/%d/%d %02d:%02d～%d/%d/%d %02d:%02d",
		startTime.Year(), startTime.Month(), startTime.Day(), startTime.Hour(), startTime.Minute(),
		endTime.Year(), endTime.Month(), endTime.Day(), endTime.Hour(), endTime.Minute())

	// Create rich card message
	message := map[string]interface{}{
		"msg_type": "interactive",
		"card": map[string]interface{}{
			"header": map[string]interface{}{
				"title": map[string]interface{}{
					"tag":     "plain_text",
					"content": title,
				},
				"template": urgencyColor,
			},
			"elements": []interface{}{
				map[string]interface{}{
					"tag": "div",
					"fields": []interface{}{
						map[string]interface{}{
							"is_short": true,
							"text": map[string]interface{}{
								"tag":     "lark_md",
								"content": fmt.Sprintf("**客户名称**\n%s", customerName),
							},
						},
						map[string]interface{}{
							"is_short": true,
							"text": map[string]interface{}{
								"tag":     "lark_md",
								"content": fmt.Sprintf("**紧急程度**\n%s", urgencyLevel),
							},
						},
					},
				},
				map[string]interface{}{
					"tag": "div",
					"fields": []interface{}{
						map[string]interface{}{
							"is_short": false,
							"text": map[string]interface{}{
								"tag":     "lark_md",
								"content": fmt.Sprintf("**试用时间**\n%s", trialPeriod),
							},
						},
					},
				},
				map[string]interface{}{
					"tag": "div",
					"text": map[string]interface{}{
						"tag":     "lark_md",
						"content": fmt.Sprintf("⏰ 该客户的试用期将于 **%s** 到期，请及时跟进！", expiryText),
					},
				},
				map[string]interface{}{
					"tag": "hr",
				},
				map[string]interface{}{
					"tag": "note",
					"elements": []interface{}{
						map[string]interface{}{
							"tag":     "plain_text",
							"content": fmt.Sprintf("发送时间：%s", time.Now().Format("2006-01-02 15:04:05")),
						},
					},
				},
			},
		},
	}

	jsonData, err := json.Marshal(message)
	if err != nil {
		log.Printf("Failed to marshal Feishu message: %v", err)
		return
	}

	resp, err := http.Post(h.feishuWebhook, "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		log.Printf("Failed to send Feishu notification: %v", err)
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		log.Printf("Feishu API returned status: %d", resp.StatusCode)
		return
	}

	log.Printf("Sent trial notification for customer: %s (expires in %d days)", customerName, daysUntilExpiry)
}

// GetTrialCustomerList returns a list of unique customer names from trial_periods
// This is the data source for dropdown lists in 每周进度 and 客户跟进
func (h *TrialPeriodHandler) GetTrialCustomerList(w http.ResponseWriter, r *http.Request) {
	// Get all trial periods
	trialPeriods, err := h.storage.GetAllTrialPeriods()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Get unique customer names from trial periods
	seenNames := make(map[string]bool)
	var customerNames []string

	for _, period := range trialPeriods {
		if period.CustomerName != "" && !seenNames[period.CustomerName] {
			customerNames = append(customerNames, period.CustomerName)
			seenNames[period.CustomerName] = true
		}
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"customerNames": customerNames,
	})
}
