package actions

import (
	"github.com/arschles/go-in-5-minutes/episode24/models"
	"github.com/gobuffalo/buffalo"
	"github.com/gobuffalo/pop"
	"github.com/pkg/errors"
)

// This file is generated by Buffalo. It offers a basic structure for
// adding, editing and deleting a page. If your model is more
// complex or you need more than the basic implementation you need to
// edit this file.

// Following naming logic is implemented in Buffalo:
// Model: Singular (Gifm)
// DB Table: Plural (gifms)
// Resource: Plural (Gifms)
// Path: Plural (/gifms)
// View Template Folder: Plural (/templates/gifms/)

// GifmsResource is the resource for the Gifm model
type GifmsResource struct {
	buffalo.Resource
}

// List gets all Gifms. This function is mapped to the path
// GET /gifms
func (v GifmsResource) List(c buffalo.Context) error {
	// Get the DB connection from the context
	tx, ok := c.Value("tx").(*pop.Connection)
	if !ok {
		return errors.WithStack(errors.New("no transaction found"))
	}

	gifms := &models.Gifms{}

	// Paginate results. Params "page" and "per_page" control pagination.
	// Default values are "page=1" and "per_page=20".
	q := tx.PaginateFromParams(c.Params())

	// Retrieve all Gifms from the DB
	if err := q.All(gifms); err != nil {
		return errors.WithStack(err)
	}

	// Add the paginator to the context so it can be used in the template.
	c.Set("pagination", q.Paginator)

	return c.Render(200, r.Auto(c, gifms))
}

// Show gets the data for one Gifm. This function is mapped to
// the path GET /gifms/{gifm_id}
func (v GifmsResource) Show(c buffalo.Context) error {
	// Get the DB connection from the context
	tx, ok := c.Value("tx").(*pop.Connection)
	if !ok {
		return errors.WithStack(errors.New("no transaction found"))
	}

	// Allocate an empty Gifm
	gifm := &models.Gifm{}

	// To find the Gifm the parameter gifm_id is used.
	if err := tx.Find(gifm, c.Param("gifm_id")); err != nil {
		return c.Error(404, err)
	}

	return c.Render(200, r.Auto(c, gifm))
}

// New renders the form for creating a new Gifm.
// This function is mapped to the path GET /gifms/new
func (v GifmsResource) New(c buffalo.Context) error {
	return c.Render(200, r.Auto(c, &models.Gifm{}))
}

// Create adds a Gifm to the DB. This function is mapped to the
// path POST /gifms
func (v GifmsResource) Create(c buffalo.Context) error {
	// Allocate an empty Gifm
	gifm := &models.Gifm{}

	// Bind gifm to the html form elements
	if err := c.Bind(gifm); err != nil {
		return errors.WithStack(err)
	}

	// Get the DB connection from the context
	tx, ok := c.Value("tx").(*pop.Connection)
	if !ok {
		return errors.WithStack(errors.New("no transaction found"))
	}

	// Validate the data from the html form
	verrs, err := tx.ValidateAndCreate(gifm)
	if err != nil {
		return errors.WithStack(err)
	}

	if verrs.HasAny() {
		// Make the errors available inside the html template
		c.Set("errors", verrs)

		// Render again the new.html template that the user can
		// correct the input.
		return c.Render(422, r.Auto(c, gifm))
	}

	// If there are no errors set a success message
	c.Flash().Add("success", "Gifm was created successfully")

	// and redirect to the gifms index page
	return c.Render(201, r.Auto(c, gifm))
}

// Edit renders a edit form for a Gifm. This function is
// mapped to the path GET /gifms/{gifm_id}/edit
func (v GifmsResource) Edit(c buffalo.Context) error {
	// Get the DB connection from the context
	tx, ok := c.Value("tx").(*pop.Connection)
	if !ok {
		return errors.WithStack(errors.New("no transaction found"))
	}

	// Allocate an empty Gifm
	gifm := &models.Gifm{}

	if err := tx.Find(gifm, c.Param("gifm_id")); err != nil {
		return c.Error(404, err)
	}

	return c.Render(200, r.Auto(c, gifm))
}

// Update changes a Gifm in the DB. This function is mapped to
// the path PUT /gifms/{gifm_id}
func (v GifmsResource) Update(c buffalo.Context) error {
	// Get the DB connection from the context
	tx, ok := c.Value("tx").(*pop.Connection)
	if !ok {
		return errors.WithStack(errors.New("no transaction found"))
	}

	// Allocate an empty Gifm
	gifm := &models.Gifm{}

	if err := tx.Find(gifm, c.Param("gifm_id")); err != nil {
		return c.Error(404, err)
	}

	// Bind Gifm to the html form elements
	if err := c.Bind(gifm); err != nil {
		return errors.WithStack(err)
	}

	verrs, err := tx.ValidateAndUpdate(gifm)
	if err != nil {
		return errors.WithStack(err)
	}

	if verrs.HasAny() {
		// Make the errors available inside the html template
		c.Set("errors", verrs)

		// Render again the edit.html template that the user can
		// correct the input.
		return c.Render(422, r.Auto(c, gifm))
	}

	// If there are no errors set a success message
	c.Flash().Add("success", "Gifm was updated successfully")

	// and redirect to the gifms index page
	return c.Render(200, r.Auto(c, gifm))
}

// Destroy deletes a Gifm from the DB. This function is mapped
// to the path DELETE /gifms/{gifm_id}
func (v GifmsResource) Destroy(c buffalo.Context) error {
	// Get the DB connection from the context
	tx, ok := c.Value("tx").(*pop.Connection)
	if !ok {
		return errors.WithStack(errors.New("no transaction found"))
	}

	// Allocate an empty Gifm
	gifm := &models.Gifm{}

	// To find the Gifm the parameter gifm_id is used.
	if err := tx.Find(gifm, c.Param("gifm_id")); err != nil {
		return c.Error(404, err)
	}

	if err := tx.Destroy(gifm); err != nil {
		return errors.WithStack(err)
	}

	// If there are no errors set a flash message
	c.Flash().Add("success", "Gifm was destroyed successfully")

	// Redirect to the gifms index page
	return c.Render(200, r.Auto(c, gifm))
}
