package handlercrudhelper

import (
	"net/http"
	"reflect"

	hk "github.com/karincake/hongkue"
)

func RegCrud(r *http.ServeMux, path string, mwAndRouter ...any) {
	sLength := len(mwAndRouter)

	mwCandidates := mwAndRouter[:sLength-1]
	mwList := []hk.HandlerMw{}
	for i := range mwCandidates {
		// have to do it manually, since casting directly results unexpected result
		myType := reflect.TypeOf(mwCandidates[i])
		if myType.String() != "func(http.Handler) http.Handler" {
			panic("non middleware included as middleware")
		}
		mwList = append(mwList, mwCandidates[i].(func(http.Handler) http.Handler))

		// if g, okHandler := mwCandidates[i].(func(http.Handler) http.Handler); !okHandler {
		// 	panic("non middleware included")
		// } else {
		// 	mwList = append(mwList, g)
		// }
	}

	c, ok := mwAndRouter[sLength-1].(CrudBase)
	if !ok {
		panic("non CrudBase used in the last paramter")
	}

	hk.GroupRoutes(path, r, mwList, hk.MapHandlerFunc{
		"POST /":       c.Create,
		"GET /":        c.GetList,
		"GET /{id}":    c.GetDetail,
		"PATCH /{id}":  c.Update,
		"DELETE /{id}": c.Delete,
	})
}

func RegCrudByCode(r *http.ServeMux, path string, mwAndRouter ...any) {
	sLength := len(mwAndRouter)

	mwCandidates := mwAndRouter[:sLength-1]
	mwList := []hk.HandlerMw{}
	for i := range mwCandidates {
		// have to do it manually, since casting directly results unexpected result
		myType := reflect.TypeOf(mwCandidates[i])
		if myType.String() != "func(http.Handler) http.Handler" {
			panic("non middleware included as middleware")
		}
		mwList = append(mwList, mwCandidates[i].(func(http.Handler) http.Handler))

		// if g, okHandler := mwCandidates[i].(func(http.Handler) http.Handler); !okHandler {
		// 	panic("non middleware included")
		// } else {
		// 	mwList = append(mwList, g)
		// }
	}

	c, ok := mwAndRouter[sLength-1].(CrudBase)
	if !ok {
		panic("non CrudBase used in the last paramter")
	}

	hk.GroupRoutes(path, r, mwList, hk.MapHandlerFunc{
		"POST /":         c.Create,
		"GET /":          c.GetList,
		"GET /{code}":    c.GetDetail,
		"PATCH /{code}":  c.Update,
		"DELETE /{code}": c.Delete,
	})
}

func SyncCrud(r *http.ServeMux, path string, mwAndRouter ...any) {
	sLength := len(mwAndRouter)

	mwCandidates := mwAndRouter[:sLength-1]
	mwList := []hk.HandlerMw{}
	for i := range mwCandidates {
		// have to do it manually, since casting directly results unexpected result
		myType := reflect.TypeOf(mwCandidates[i])
		if myType.String() != "func(http.Handler) http.Handler" {
			panic("non middleware included as middleware")
		}
		mwList = append(mwList, mwCandidates[i].(func(http.Handler) http.Handler))

		// if g, okHandler := mwCandidates[i].(func(http.Handler) http.Handler); !okHandler {
		// 	panic("non middleware included")
		// } else {
		// 	mwList = append(mwList, g)
		// }
	}

	c, ok := mwAndRouter[sLength-1].(SyncCrudBase)
	if !ok {
		panic("non CrudBase used in the last paramter")
	}

	hk.GroupRoutes(path, r, mwList, hk.MapHandlerFunc{
		"POST /":       c.Create,
		"POST /log":    c.CreateLog,
		"PATCH /{id}":  c.Update,
		"DELETE /{id}": c.Delete,
	})
}
