package filemanager

import (
	"bytes"
	"encoding/json"
	"html/template"
	"net/http"
	"strconv"
	"strings"
)

// functions contains the non-standard functions that are available
// to use on the HTML templates.
var functions = template.FuncMap{
	"CSS": func(s string) template.CSS {
		return template.CSS(s)
	},
	"Marshal": func(v interface{}) template.JS {
		a, _ := json.Marshal(v)
		return template.JS(a)
	},
}

// page contains the information needed to fill a page template.
type page struct {
	User      *User  `json:"-"`
	BaseURL   string `json:"-"`
	WebDavURL string `json:"-"`
	Kind      string `json:"kind"`
	Data      *file  `json:"data"`
}

/*
// breadcrumbItem contains the Name and the URL of a breadcrumb piece.
type breadcrumbItem struct {
	Name string
	URL  string
}

// BreadcrumbMap returns p.Path where every element is a map
// of URLs and path segment names.
func (p page) BreadcrumbMap() []breadcrumbItem {
	// TODO: when it is preview alongside with listing!!!!!!!!!!
	result := []breadcrumbItem{}

	if len(p.Path) == 0 {
		return result
	}

	// skip trailing slash
	lpath := p.Path
	if lpath[len(lpath)-1] == '/' {
		lpath = lpath[:len(lpath)-1]
	}

	parts := strings.Split(lpath, "/")
	for i, part := range parts {
		if i == len(parts)-1 {
			continue
		}

		if i == 0 && part == "" {
			result = append([]breadcrumbItem{{
				Name: "/",
				URL:  "/",
			}}, result...)
			continue
		}

		result = append([]breadcrumbItem{{
			Name: part,
			URL:  strings.Join(parts[:i+1], "/") + "/",
		}}, result...)
	}

	return result
}

// PreviousLink returns the URL of the previous folder.
func (p page) PreviousLink() string {
	path := strings.TrimSuffix(p.Path, "/")
	path = strings.TrimPrefix(path, "/")
	path = p.BaseURL + "/" + path
	path = path[0 : len(path)-len(p.Name)]

	if len(path) < len(p.BaseURL+"/") {
		return ""
	}

	return path
} */

func (p page) Render(c *requestContext, w http.ResponseWriter, r *http.Request) (int, error) {
	if strings.Contains(r.Header.Get("Accept"), "application/json") {
		marsh, err := json.MarshalIndent(p, "", "    ")
		if err != nil {
			return http.StatusInternalServerError, err
		}

		w.Header().Set("Content-Type", "application/json; charset=utf-8")
		if _, err := w.Write(marsh); err != nil {
			return http.StatusInternalServerError, err
		}

		return 0, nil
	}

	var tpl *template.Template

	// Get the template from the assets
	file, err := c.fm.templates.String("index.html")

	// Check if there is some error. If so, the template doesn't exist
	if err != nil {
		return http.StatusInternalServerError, err
	}

	tpl, err = template.New("index").Funcs(functions).Parse(file)
	if err != nil {
		return http.StatusInternalServerError, err
	}

	buf := &bytes.Buffer{}
	err = tpl.Execute(buf, p)
	if err != nil {
		return http.StatusInternalServerError, err
	}

	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	_, err = buf.WriteTo(w)

	if err != nil {
		return http.StatusInternalServerError, err
	}

	return 0, nil
}

// htmlError prints the error page
func htmlError(w http.ResponseWriter, code int, err error) (int, error) {
	tpl := errTemplate
	tpl = strings.Replace(tpl, "TITLE", strconv.Itoa(code)+" "+http.StatusText(code), -1)
	tpl = strings.Replace(tpl, "CODE", err.Error(), -1)

	_, err = w.Write([]byte(tpl))

	if err != nil {
		return http.StatusInternalServerError, err
	}
	return 0, nil
}

const errTemplate = `<!DOCTYPE html>
<html>
<head>
    <title>TITLE</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta charset="utf-8">
    <style>
    html {
        background-color: #2196f3;
        color: #fff;
        font-family: sans-serif;
    }
    code {
        background-color: rgba(0,0,0,0.1);
        border-radius: 5px;
        padding: 1em;
        display: block;
        box-sizing: border-box;
    }
    .center {
        max-width: 40em;
        margin: 2em auto 0;
    }
    a {
        text-decoration: none;
        color: #eee;
        font-weight: bold;
    }
	p {
		line-height: 1.3;
	}
    </style>
</head>

<body>
    <div class="center">
        <h1>TITLE</h1>

        <p>Try reloading the page or hitting the back button. If this error persists, it seems that you may have found a bug! Please create an issue at <a href="https://github.com/hacdias/caddy-filemanager/issues">hacdias/caddy-filemanager</a> repository on GitHub with the code below.</p>

        <code>CODE</code>
    </div>
</html>`