package device

import (
	"errors"
	"fmt"
	"log"
	"net/http"
	"strconv"
	"strings"

	"github.com/jinzhu/gorm"
	"gitlab.com/pactual1/backend/models"
	"gitlab.com/pactual1/backend/shared"
)


func GetDevicesForContract(contractID uint64) ([]models.Device , int, error) {

	// Create a slice to hold the devices
	var devices []models.Device
	// Fetch the contract from the database
	var contract models.Contract
	if err := shared.GetDb().Where("id = ?", contractID).First(&contract).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			log.Printf("GetDevicesByContract Error: No contract found: %v", err)
			return devices,  http.StatusNotFound ,err
		} else {
			log.Printf("GetDevicesByContract Error: Database error: %v", err)
			return devices, http.StatusInternalServerError, err
		}
	}
	log.Printf("This is the device IDS ID: %v", contract.DeviceIDs)


	// Convert the integer array to a comma-separated string
	idStrings := []string{}
	for _, id := range contract.DeviceIDs {
		idStrings = append(idStrings, strconv.FormatInt(id, 10))
	}
	idStr := strings.Join(idStrings, ",")

	// Construct the SQL query manually
	sqlQuery := fmt.Sprintf("SELECT * FROM devices WHERE id IN (%s)", idStr)

	// Fetch devices from the database based on DeviceIDs in the contract
	// Execute the query
	if err := shared.GetDb().Raw(sqlQuery).Scan(&devices).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			log.Printf("GetDevicesByContract Error: No devices found: %v", err)
			return devices, http.StatusNotFound, err
		} else {
			log.Printf("GetDevicesByContract Error: Database error: %v", err)
			return devices,  http.StatusInternalServerError, err
		}
	}
	return  devices , http.StatusOK, nil
}

func GetDeviceInfoForContract (deviceID uint64, contract models.Contract) (models.GeoJSONFeatureCollection , int, error) {

	var deviceInfos []models.DeviceInfo

    // Create a GeoJSON feature collection
    var featureCollection models.GeoJSONFeatureCollection
    featureCollection.Type = "FeatureCollection"
    featureCollection.Features = []models.GeoJSONFeature{}


    // Modify your query to include filtering based on the contract's creation date
    query := shared.GetDb().Where("device_id = ?", deviceID).Where("created_at >= ? AND created_at <= ?", contract.StartTime,contract.EndTime)

    if err := query.Find(&deviceInfos).Error; err != nil {
        if errors.Is(err, gorm.ErrRecordNotFound) {
            log.Printf("GetDeviceData Error: No device info found: %v", err)
			return featureCollection, http.StatusNotFound, err
        } else {
            log.Printf("GetDeviceData Error: Database error: %v", err)
			return featureCollection, http.StatusNotFound, err
        }
    }


    // Loop through each deviceInfo to create GeoJSON features
    for _, info := range deviceInfos {
        info.RawJSON = ""
        feature := models.GeoJSONFeature{
            Type: "Feature",
            DeviceInfo: &info,
            Geometry: models.GeoJSONGeometry{
                Type:        "Point",
                Coordinates: []float64{info.Lon, info.Lat},
            },
            Properties: map[string]interface{}{},
        }
        featureCollection.Features = append(featureCollection.Features, feature)
    }

	return featureCollection , 0, nil


}