package orm

import (
	"net/http"

	"github.com/jinzhu/gorm"
	"gogs.carduccidante.edu.it/karmen/core/renderer"
)

type Office struct {
	gorm.Model

	Name  string
	Email string

	Administratives []*Administrative
}

func (d *Office) GetID() uint { return d.ID }

func (o *Office) String() string {
	return o.Name
}

func (o *Office) Create(args map[string]string, r *http.Request) (interface{}, error) {
	if r.Method == "GET" {
		return nil, nil
	} else {
		office := new(Office)
		err := renderer.Decode(office, r)
		if err != nil {
			return nil, err
		}
		office, err = CreateOffice(office)
		if err != nil {
			return nil, err
		}

		return office, nil
	}
}

func (o *Office) Read(args map[string]string, r *http.Request) (interface{}, error) {
	var office Office

	id := args["id"]

	if err := DB().Preload("Administratives").Where("id = ?", id).Find(&office).Error; err != nil {
		return nil, err
	}
	return &office, nil
}

func (o *Office) ReadAll(args map[string]string, r *http.Request) (interface{}, error) {
	var offices []*Office
	if err := DB().Preload("Administratives").Order("name").Find(&offices).Error; err != nil {
		return nil, err
	}
	return offices, nil
}

func (o *Office) Update(args map[string]string, r *http.Request) (interface{}, error) {
	if r.Method == "GET" {
		result, err := o.Read(args, r)
		if err != nil {
			return nil, err
		}

		office := result.(*Office)

		return office, nil
	} else {
		office, err := o.Read(args, r)
		if err != nil {
			return nil, err
		}
		err = renderer.Decode(office, r)
		if err != nil {
			return nil, err
		}
		_, err = SaveOffice(office)
		if err != nil {
			return nil, err
		}
		office, err = o.Read(args, r)
		if err != nil {
			return nil, err
		}

		return office.(*Office), nil
	}
}

func (o *Office) Delete(args map[string]string, r *http.Request) (interface{}, error) {
	office, err := o.Read(args, r)
	if err != nil {
		return nil, err
	}
	if err := DB().Unscoped().Delete(office.(*Office)).Error; err != nil {
		return nil, err
	}
	return office.(*Office), nil
}

func SaveOffice(office interface{}) (interface{}, error) {
	if err := DB().Omit("Administratives").Save(office).Error; err != nil {
		return nil, err
	}
	return office, nil
}

func CreateOffice(office *Office) (*Office, error) {
	if err := DB().Create(office).Error; err != nil {
		return nil, err
	}
	return office, nil
}
