package download

import (
	"app/shelfly/internal/models"
	"app/shelfly/query"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"
	"github.com/gorilla/mux"
	"gorm.io/gorm"
)

func CreateSavePath(db *gorm.DB) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")

		var pathDownload models.PathDownload
		// Décoder les données de la requête

		if err := json.NewDecoder(r.Body).Decode(&pathDownload); err != nil {
			http.Error(w, `{"error": "Invalid JSON format"}`, http.StatusBadRequest)
			return
		}

		q := query.Use(db)
		if err := q.PathDownload.Create(&pathDownload); err != nil {
			http.Error(w, `{"error": "Failed to create path"}`, http.StatusInternalServerError)
			return
		}

		// Retourner un élément HTML dynamique pour HTMX

		        // Récupérer tous les chemins
		var paths []models.PathDownload
				if err := db.Find(&paths).Error; err != nil {
					http.Error(w, `{"error": "Failed to retrieve paths"}`, http.StatusInternalServerError)
					return
				}
				
		
				// Construire les lignes HTML
		var response strings.Builder
        for _, path := range paths {
			log.Println(path)
			response.WriteString(fmt.Sprintf(`
						<div class="column">

							<form>

			<div id="path-%d" class="path-update grid is-col-min-1">
				<input class="input is-primary cell" name="id" disabled value="%d"></input>
				<input class="input is-primary fff cell" name="path" value="%s" disabled></span>
				<input class="input is-primary fff cell" name="pathName" value="%s" disabled></span>
				<button class="button is-primary type="button" is-dark" id="btn-path-edit-%d" hx-trigger="click" hx-target="#path-%d" hx-swap="outerHTML" onclick="enableAllInputPath(%d)">Edit</button>
				<button class="button is-danger" type="button" id="btn-path-annuler-%d"  onclick="disableAllInputPath(%d)" style="display:none" >Annuler</button>
				<button class="button is-primary is-dark" id="btn-path-valider-%d" hx-put="/api/pathDownload/update/%d" hx-trigger="click[checkGlobalState()]" hx-target="#path-%d" hx-swap="outerHTML" hx-ext="json-enc" style="display:none">Valider</button>
                <button class="button is-danger" hx-delete="/api/pathDownload/delete/%d" hx-trigger="click" hx-target="#path-%d" hx-swap="outerHTML" hx-confirm="Are you sure?" hx-swap="outerHTML swap:1s">Delete</button>
			</div>
							</form></div>

		`, path.ID, path.ID, path.Path, path.PathName,path.ID,path.ID,path.ID,path.ID ,path.ID,path.ID,path.ID,path.ID, path.ID,path.ID))

        }
		w.WriteHeader(http.StatusOK)
		fmt.Fprint(w, response.String())
	}
}

func ReadAllSavePath(db *gorm.DB) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "text/html")

        // Récupérer tous les chemins
        var paths []models.PathDownload
        if err := db.Find(&paths).Error; err != nil {
            http.Error(w, `{"error": "Failed to retrieve paths"}`, http.StatusInternalServerError)
            return
        }

        // Construire les lignes HTML
        var response strings.Builder
        for _, path := range paths {
			response.WriteString(fmt.Sprintf(`
			<div class="column">
						<form>

			<div id="path-%d" class="path-update grid is-col-min-1">
				<input class="input is-primary cell" name="id" disabled value="%d"></input>
				<input class="input is-primary fff cell" name="path" value="%s" disabled></span>
				<input class="input is-primary fff cell" name="pathName" value="%s" disabled></span>
				<button class="button is-primary is-dark" id="btn-path-edit-%d" hx-trigger="click" hx-target="#path-%d" hx-swap="outerHTML" onclick="enableAllInputPath(%d)">Edit</button>
				<button class="button is-danger" type="button" id="btn-path-annuler-%d"  onclick="disableAllInputPath(%d)" style="display:none" >Annuler</button>
				<button class="button is-primary hx-trigger="click[checkGlobalState()]" type="button" is-dark" id="btn-path-valider-%d" hx-put="/api/pathDownload/update/%d" hx-target="#path-%d" hx-swap="outerHTML" hx-ext="json-enc" style="display:none">Valider</button>
                <button class="button is-danger" hx-delete="/api/pathDownload/delete/%d" hx-trigger="click" hx-target="#path-%d" hx-swap="outerHTML" hx-confirm="Are you sure?" hx-swap="outerHTML swap:1s">Delete</button>
			</div>
							</form></div>

		`, path.ID, path.ID, path.Path, path.PathName,path.ID,path.ID,path.ID,path.ID, path.ID,path.ID,path.ID,path.ID, path.ID,path.ID))


        }

        // Retourner les lignes HTML
        w.WriteHeader(http.StatusOK)
        fmt.Fprint(w, response.String())
    }
}

func UpdateSavePath(db *gorm.DB) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")

		// Récupérer l'ID depuis les paramètres de l'URL
		id := mux.Vars(r)["id"]

		var pathDownload models.PathDownload
		log.Println(pathDownload);
		// Décoder les données de la requête
		if err := json.NewDecoder(r.Body).Decode(&pathDownload); err != nil {
			http.Error(w, `{"error": "Invalid JSON format"}`, http.StatusBadRequest)
			return
		}

		// Vérifier si la ressource existe
		var existingPath models.PathDownload
		if err := db.First(&existingPath, "id = ?", id).Error; err != nil {
			if err == gorm.ErrRecordNotFound {
				http.Error(w, `{"error": "Path not found"}`, http.StatusNotFound)
				return
			}
			http.Error(w, `{"error": "Failed to retrieve path"}`, http.StatusInternalServerError)
			return
		}

		// Mettre à jour les champs souhaités
		existingPath.Path = pathDownload.Path
		existingPath.PathName = pathDownload.PathName

		if err := db.Save(&existingPath).Error; err != nil {
			http.Error(w, `{"error": "Failed to update path"}`, http.StatusInternalServerError)
			return
		}
		response := fmt.Sprintf(`

						<form>

			<div id="path-%d" class="path-update grid is-col-min-1">
				<input class="input is-primary cell" name="id" disabled value="%d"></input>
				<input class="input is-primary fff cell" name="path" value="%s" disabled></span>
				<input class="input is-primary fff cell" name="pathName" value="%s" disabled></span>
				<button class="button is-primary is-dark" id="btn-path-edit-%d" hx-trigger="click" hx-target="#path-%d" hx-swap="outerHTML" onclick="enableAllInputPath(%d)">Edit</button>
				<button class="button is-danger" type="button" id="btn-path-annuler-%d"  onclick="disableAllInputPath(%d)" style="display:none" >Annuler</button>
				<button class="button is-primary type="button" is-dark" id="btn-path-valider-%d" hx-put="/api/pathDownload/update/%d" hx-trigger="click[checkGlobalState()]" hx-target="#path-%d" hx-swap="outerHTML" hx-ext="json-enc" style="display:none">Valider</button>
                <button class="button is-danger" hx-delete="/api/pathDownload/delete/%d" hx-trigger="click" hx-target="#path-%d" hx-swap="outerHTML" hx-confirm="Are you sure?" hx-swap="outerHTML swap:1s">Delete</button>
			</div>
							</form>
	`, existingPath.ID, existingPath.ID, existingPath.Path, existingPath.PathName, existingPath.ID, existingPath.ID, existingPath.ID, existingPath.ID, existingPath.ID, existingPath.ID, existingPath.ID, existingPath.ID, existingPath.ID, existingPath.ID)

		w.WriteHeader(http.StatusOK)
		fmt.Fprint(w, response)
		// // Retourner le nouvel élément HTML
		// var paths []models.PathDownload
		// 		if err := db.Find(&paths).Error; err != nil {
		// 			http.Error(w, `{"error": "Failed to retrieve paths"}`, http.StatusInternalServerError)
		// 			return
		// 		}
				
		
		// 		// Construire les lignes HTML
		// var response strings.Builder
        // for _, path := range paths {
		// 	log.Println(path)
		// 	response.WriteString(fmt.Sprintf(`
		// 					<form>

		// 	<div id="path-%d" class="path-update grid is-col-min-1">
		// 		<input class="input is-primary cell" name="id" disabled value="%d"></input>
		// 		<input class="input is-primary fff cell" name="path" value="%s" disabled></span>
		// 		<input class="input is-primary fff cell" name="pathName" value="%s" disabled></span>
		// 		<button class="button is-primary is-dark" type="button" id="btn-path-edit-%d" hx-trigger="click" hx-target="#path-%d" hx-swap="outerHTML" onclick="enableAllInputPath(%d)">Edit</button>
		// 		<button class="button is-danger" id="btn-path-annuler-%d" type="button"  onclick="disableAllInputPath(%d)" style="display:none" >Annuler</button>
		// 		<button class="button is-primary is-dark" id="btn-path-valider-%d" hx-put="/api/pathDownload/update/%d" hx-trigger="click" hx-target="#path-%d" hx-swap="outerHTML" hx-ext="json-enc" style="display:none">Valider</button>
        //         <button class="button is-danger" hx-delete="/api/pathDownload/delete/%d" hx-trigger="click" hx-target="#path-%d" hx-swap="outerHTML">Delete</button>
		// 	</div>
		// 					</form>

		// `, path.ID, path.ID, path.Path, path.PathName,path.ID,path.ID,path.ID, path.ID,path.ID ,path.ID,path.ID,path.ID, path.ID,path.ID))

        // }
		w.WriteHeader(http.StatusOK)
		//fmt.Fprint(w, response.String())
	
	}
}

func DeleteSavePath(db *gorm.DB) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")

		// Récupérer l'ID depuis les paramètres de l'URL
		id := mux.Vars(r)["id"]

		// Vérifier si la ressource existe
		var pathDownload models.PathDownload
		if err := db.First(&pathDownload, "id = ?", id).Error; err != nil {
			if err == gorm.ErrRecordNotFound {
				http.Error(w, `{"error": "Path not found"}`, http.StatusNotFound)
				return
			}
			http.Error(w, `{"error": "Failed to retrieve path"}`, http.StatusInternalServerError)
			return
		}

		// Supprimer la ressource
		if err := db.Delete(&pathDownload).Error; err != nil {
			http.Error(w, `{"error": "Failed to delete path"}`, http.StatusInternalServerError)
			return
		}

		// Répondre avec succès
		w.WriteHeader(http.StatusOK)
		fmt.Fprintf(w, ` <div class="notification is-primary" id="notificationPath" style="display:block">
      <button class="delete" type="button" onclick="hide('notificationPath')"></button>
       Delete ok
    </div>`)
	}
}
func IsPathValid(path string) error {
	if path == "" {
		return errors.New("path is empty")
	}

	info, err := os.Stat(path)
	if os.IsNotExist(err) {
		return errors.New("path does not exist")
	}
	if err != nil {
		return errors.New("unable to access path: " + err.Error())
	}

	if !info.IsDir() && !info.Mode().IsRegular() {
		return errors.New("path is neither a file nor a directory")
	}

	return nil // Path is valid
}

// PathValidationHandler handles HTTP requests to validate a path
func PathValidationHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
		return
	}

	var requestBody struct {
		Path string `json:"path"`
	}

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

	err := IsPathValid(requestBody.Path)
	response := map[string]string{
		"path":  requestBody.Path,
		"status": "valid",
	}

	if err != nil {
		response["status"] = "invalid"
		response["error"] = err.Error()
		w.WriteHeader(http.StatusBadRequest)
	}

	w.Header().Set("Content-Type", "application/json")
	if err := json.NewEncoder(w).Encode(response); err != nil {
		http.Error(w, "Failed to encode response", http.StatusInternalServerError)
	}
}
