package handlers

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strconv"
	"time"

	"tankstopp/internal/models"

	"github.com/gorilla/mux"
)

// APIGetFuelStopsHandler returns fuel stops as JSON
func (h *Handler) APIGetFuelStopsHandler(w http.ResponseWriter, r *http.Request) {
	userID, _ := h.getCurrentUser(r)
	if userID == 0 {
		h.writeJSONError(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	// Parse query parameters for filtering (not used in simplified implementation)
	_ = r.URL.Query().Get("vehicle_id")
	_ = r.URL.Query().Get("fuel_type")
	_ = r.URL.Query().Get("date_from")
	_ = r.URL.Query().Get("date_to")
	limitStr := r.URL.Query().Get("limit")
	offsetStr := r.URL.Query().Get("offset")

	// Parse limit and offset
	limit := 50 // default limit
	offset := 0 // default offset

	if limitStr != "" {
		if l, err := strconv.Atoi(limitStr); err == nil && l > 0 && l <= 1000 {
			limit = l
		}
	}

	if offsetStr != "" {
		if o, err := strconv.Atoi(offsetStr); err == nil && o >= 0 {
			offset = o
		}
	}

	// Get fuel stops (simplified - using existing method)
	stops, err := h.db.GetFuelStops(userID)
	if err != nil {
		log.Printf("Error getting fuel stops: %v", err)
		h.writeJSONError(w, "Failed to retrieve fuel stops", http.StatusInternalServerError)
		return
	}

	// Apply basic pagination
	totalCount := len(stops)
	end := offset + limit
	if end > len(stops) {
		end = len(stops)
	}
	if offset < len(stops) {
		stops = stops[offset:end]
	} else {
		stops = []models.FuelStop{}
	}

	// Prepare response
	response := struct {
		Data       []models.FuelStop `json:"data"`
		Total      int               `json:"total"`
		Limit      int               `json:"limit"`
		Offset     int               `json:"offset"`
		HasMore    bool              `json:"has_more"`
		Pagination struct {
			CurrentPage int `json:"current_page"`
			TotalPages  int `json:"total_pages"`
			PerPage     int `json:"per_page"`
		} `json:"pagination"`
	}{
		Data:    stops,
		Total:   totalCount,
		Limit:   limit,
		Offset:  offset,
		HasMore: offset+len(stops) < totalCount,
	}

	// Calculate pagination
	response.Pagination.PerPage = limit
	response.Pagination.CurrentPage = (offset / limit) + 1
	response.Pagination.TotalPages = (totalCount + limit - 1) / limit

	h.writeJSONResponse(w, response, http.StatusOK)
}

// APICreateFuelStopHandler creates a new fuel stop via JSON API
func (h *Handler) APICreateFuelStopHandler(w http.ResponseWriter, r *http.Request) {
	userID, _ := h.getCurrentUser(r)
	if userID == 0 {
		h.writeJSONError(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	// Parse JSON request body
	var request struct {
		VehicleID   uint    `json:"vehicle_id"`
		Date        string  `json:"date"`
		StationName string  `json:"station_name"`
		Location    string  `json:"location"`
		FuelType    string  `json:"fuel_type"`
		Liters      float64 `json:"liters"`
		PricePerL   float64 `json:"price_per_l"`
		TotalPrice  float64 `json:"total_price"`
		Currency    string  `json:"currency"`
		Odometer    int     `json:"odometer"`
		TripLength  float64 `json:"trip_length"`
		Notes       string  `json:"notes"`
	}

	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		h.writeJSONError(w, "Invalid JSON format", http.StatusBadRequest)
		return
	}

	// Validate required fields
	if err := h.validateAPIFuelStopRequest(&request); err != nil {
		h.writeJSONError(w, err.Error(), http.StatusBadRequest)
		return
	}

	// Parse date
	date, err := time.Parse("2006-01-02", request.Date)
	if err != nil {
		h.writeJSONError(w, "Invalid date format. Use YYYY-MM-DD", http.StatusBadRequest)
		return
	}

	// Get user's default currency if not provided
	if request.Currency == "" {
		user, err := h.db.GetUserByID(userID)
		if err != nil {
			log.Printf("Error getting user: %v", err)
			h.writeJSONError(w, "Failed to retrieve user information", http.StatusInternalServerError)
			return
		}
		request.Currency = user.BaseCurrency
	}

	// Create fuel stop model
	fuelStop := &models.FuelStop{
		UserID:      userID,
		VehicleID:   request.VehicleID,
		Date:        date,
		StationName: request.StationName,
		Location:    request.Location,
		FuelType:    request.FuelType,
		Liters:      request.Liters,
		PricePerL:   request.PricePerL,
		TotalPrice:  request.TotalPrice,
		Currency:    request.Currency,
		Odometer:    request.Odometer,
		TripLength:  request.TripLength,
		Notes:       request.Notes,
	}

	// Use station name as location if location is empty
	if fuelStop.Location == "" {
		fuelStop.Location = fuelStop.StationName
	}

	// Save to database
	err = h.db.CreateFuelStopWithValidation(fuelStop)
	if err != nil {
		log.Printf("Error creating fuel stop: %v", err)
		h.writeJSONError(w, "Failed to create fuel stop", http.StatusInternalServerError)
		return
	}

	// Return created fuel stop
	h.writeJSONResponse(w, map[string]interface{}{
		"message": "Fuel stop created successfully",
		"data":    fuelStop,
	}, http.StatusCreated)
}

// APIGetFuelStopStatsHandler returns fuel stop statistics as JSON
func (h *Handler) APIGetFuelStopStatsHandler(w http.ResponseWriter, r *http.Request) {
	userID, _ := h.getCurrentUser(r)
	if userID == 0 {
		h.writeJSONError(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	// Parse query parameters (not used in simplified implementation)
	_ = r.URL.Query().Get("date_from")
	_ = r.URL.Query().Get("date_to")
	groupBy := r.URL.Query().Get("group_by") // month, year, vehicle

	// Get basic statistics
	stats, err := h.db.GetFuelStopStats(userID)
	if err != nil {
		log.Printf("Error getting fuel stop stats: %v", err)
		h.writeJSONError(w, "Failed to retrieve statistics", http.StatusInternalServerError)
		return
	}

	// Prepare response structure
	response := struct {
		Basic     *models.FuelStopStats `json:"basic"`
		Daily     []DailyStats          `json:"daily,omitempty"`
		Monthly   []MonthlyStats        `json:"monthly,omitempty"`
		ByVehicle []VehicleStats        `json:"by_vehicle,omitempty"`
		Summary   StatsSummary          `json:"summary"`
	}{
		Basic: stats,
	}

	// Additional statistics would require more complex database queries
	// For now, we'll just return basic stats
	_ = groupBy // Acknowledge the parameter

	// Calculate summary statistics
	response.Summary = h.calculateStatsSummary(stats)

	h.writeJSONResponse(w, response, http.StatusOK)
}

// Helper structs for statistics
type DailyStats struct {
	Date        string  `json:"date"`
	TotalStops  int     `json:"total_stops"`
	TotalCost   float64 `json:"total_cost"`
	TotalLiters float64 `json:"total_liters"`
}

type MonthlyStats struct {
	Month       string  `json:"month"`
	Year        int     `json:"year"`
	TotalStops  int     `json:"total_stops"`
	TotalCost   float64 `json:"total_cost"`
	TotalLiters float64 `json:"total_liters"`
	AvgPrice    float64 `json:"avg_price"`
}

type VehicleStats struct {
	VehicleID   uint    `json:"vehicle_id"`
	VehicleName string  `json:"vehicle_name"`
	TotalStops  int     `json:"total_stops"`
	TotalCost   float64 `json:"total_cost"`
	TotalLiters float64 `json:"total_liters"`
	AvgPrice    float64 `json:"avg_price"`
	LastFillUp  string  `json:"last_fillup"`
}

type StatsSummary struct {
	CostPerKm       float64 `json:"cost_per_km"`
	FuelEfficiency  float64 `json:"fuel_efficiency"`
	MonthlyAverage  float64 `json:"monthly_average"`
	WeeklyAverage   float64 `json:"weekly_average"`
	MostUsedStation string  `json:"most_used_station"`
	PreferredFuel   string  `json:"preferred_fuel"`
}

// validateAPIFuelStopRequest validates the JSON request for creating fuel stops
func (h *Handler) validateAPIFuelStopRequest(req *struct {
	VehicleID   uint    `json:"vehicle_id"`
	Date        string  `json:"date"`
	StationName string  `json:"station_name"`
	Location    string  `json:"location"`
	FuelType    string  `json:"fuel_type"`
	Liters      float64 `json:"liters"`
	PricePerL   float64 `json:"price_per_l"`
	TotalPrice  float64 `json:"total_price"`
	Currency    string  `json:"currency"`
	Odometer    int     `json:"odometer"`
	TripLength  float64 `json:"trip_length"`
	Notes       string  `json:"notes"`
}) error {
	if req.VehicleID == 0 {
		return fmt.Errorf("vehicle_id is required")
	}

	if req.Date == "" {
		return fmt.Errorf("date is required")
	}

	if req.StationName == "" && req.Location == "" {
		return fmt.Errorf("station_name or location is required")
	}

	if req.FuelType == "" {
		return fmt.Errorf("fuel_type is required")
	}

	if req.Liters <= 0 {
		return fmt.Errorf("liters must be greater than 0")
	}

	if req.PricePerL <= 0 {
		return fmt.Errorf("price_per_l must be greater than 0")
	}

	if req.TotalPrice <= 0 {
		return fmt.Errorf("total_price must be greater than 0")
	}

	if req.Odometer < 0 {
		return fmt.Errorf("odometer cannot be negative")
	}

	if req.TripLength < 0 {
		return fmt.Errorf("trip_length cannot be negative")
	}

	if len(req.Notes) > 500 {
		return fmt.Errorf("notes cannot be longer than 500 characters")
	}

	return nil
}

// APIGetVehicleHandler returns vehicle information as JSON
func (h *Handler) APIGetVehicleHandler(w http.ResponseWriter, r *http.Request) {
	userID, _ := h.getCurrentUser(r)
	if userID == 0 {
		h.writeJSONError(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	// Get vehicle ID from URL path
	vars := mux.Vars(r)
	vehicleIDStr := vars["id"]
	vehicleID, err := strconv.ParseUint(vehicleIDStr, 10, 32)
	if err != nil {
		h.writeJSONError(w, "Invalid vehicle ID", http.StatusBadRequest)
		return
	}

	// Get vehicle from database
	vehicle, err := h.db.GetVehicleByID(uint(vehicleID), userID)
	if err != nil {
		log.Printf("Error getting vehicle: %v", err)
		h.writeJSONError(w, "Failed to retrieve vehicle", http.StatusInternalServerError)
		return
	}

	if vehicle == nil {
		h.writeJSONError(w, "Vehicle not found", http.StatusNotFound)
		return
	}

	// Return vehicle information
	h.writeJSONResponse(w, vehicle, http.StatusOK)
}

// calculateStatsSummary calculates additional summary statistics
func (h *Handler) calculateStatsSummary(stats *models.FuelStopStats) StatsSummary {
	summary := StatsSummary{}

	if stats.TotalStops > 0 {
		// Calculate monthly average (assuming data spans multiple months)
		monthlyAvg := stats.TotalSpent / 12 // This is a simplified calculation
		summary.MonthlyAverage = monthlyAvg

		// Calculate weekly average
		summary.WeeklyAverage = monthlyAvg / 4.33 // Average weeks per month

		// Calculate fuel efficiency (simplified)
		summary.FuelEfficiency = stats.AverageConsumption

		// These would require additional database queries in a real implementation
		summary.MostUsedStation = "N/A"
		summary.PreferredFuel = "N/A"
	}

	return summary
}

// writeJSONResponse writes a JSON response with the given status code
func (h *Handler) writeJSONResponse(w http.ResponseWriter, data interface{}, statusCode int) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(statusCode)

	if err := json.NewEncoder(w).Encode(data); err != nil {
		log.Printf("Error encoding JSON response: %v", err)
		http.Error(w, "Internal server error", http.StatusInternalServerError)
	}
}

// writeJSONError writes a JSON error response
func (h *Handler) writeJSONError(w http.ResponseWriter, message string, statusCode int) {
	errorResponse := struct {
		Error   string `json:"error"`
		Message string `json:"message"`
		Code    int    `json:"code"`
	}{
		Error:   http.StatusText(statusCode),
		Message: message,
		Code:    statusCode,
	}

	h.writeJSONResponse(w, errorResponse, statusCode)
}
