package domain

import (
	"crypto/md5"
	"path"
	"path/filepath"
	"strings"
)

type Path struct {
	Language            Language
	baseFileName        string
	contentBaseName     string
	dir                 string
	ext                 string
	filename            string
	logicalName         string
	path                string
	translationBaseName string
	uniqueId            string
}

func NewPath(p string) Path {
	out := Path{
		Language:            LanguageUnd,
		baseFileName:        "",
		contentBaseName:     "",
		dir:                 filepath.Dir(p),
		ext:                 strings.TrimPrefix(filepath.Ext(p), "."),
		filename:            p,
		logicalName:         filepath.Base(p),
		path:                "",
		translationBaseName: "",
		uniqueId:            "",
	}
	out.baseFileName = strings.TrimSuffix(out.logicalName, filepath.Ext(out.logicalName))

	if out.dir[len(out.dir)-1] != '/' {
		out.dir += string(filepath.Separator)
	}

	parts := strings.Split(out.baseFileName, ".")
	out.Language = NewLanguage(parts[len(parts)-1])
	out.translationBaseName = strings.Join(parts[:len(parts)-1], ".")

	if len(parts) == 1 {
		out.translationBaseName = parts[0]
		out.contentBaseName = filepath.Base(out.dir)
	} else {
		out.contentBaseName = out.translationBaseName
	}

	switch out.translationBaseName {
	case "_index", "index":
		out.contentBaseName = filepath.Base(out.dir)
	}

	out.path = path.Join(out.Language.code, out.dir, out.contentBaseName)

	hash := md5.New()
	_, _ = hash.Write([]byte(out.path))
	out.uniqueId = string(hash.Sum(nil))

	return out
}

// BaseFileName returns file name without extention:
//
//	/news/a.en.md => a.en
//	/news/b/index.en.md => index.en
//	/news/_index.en.md => _index.en
//	/news/b/photo.jpg => photo
func (p Path) BaseFileName() string {
	return p.baseFileName
}

// ContentBaseName returns file or folder name based of index location:
//
//	/news/a.en.md => a
//	/news/b/index.en.md => b
//	/news/_index.en.md => news
//	/news/b/photo.jpg => b
func (p Path) ContentBaseName() string {
	return p.contentBaseName
}

// Dir returns directory path:
//
//	/news/a.en.md => news/
//	/news/b/index.en.md => news/b/
//	/news/_index.en.md => news/
//	/news/b/photo.jpg => news/b/
func (p Path) Dir() string {
	return p.dir
}

// Ext returns file extention:
//
//	/news/b/index.en.md => md
//	/news/b/photo.jpg => jpg
func (p Path) Ext() string {
	return p.ext
}

// Filename returns the file path relative to $HOME_CONTENT_DIR.
func (p Path) Filename() string {
	return p.filename
}

// LogicalName returns file name in directory:
//
//	/news/a.en.md => a.en.md
//	/news/b/index.en.md => index.en.md
//	/news/_index.en.md => _index.en.md
//	/news/b/photo.jpg => photo.jpg
func (p Path) LogicalName() string {
	return p.logicalName
}

// Path returns the relative URL path to the file.
func (p Path) Path() string {
	return p.path
}

// TranslationBaseName returns file name without language code and extention:
//
//	/news/a.en.md => a
//	/news/b/index.en.md => index
//	/news/_index.en.md => _index
//	/news/b/photo.jpg => photo
func (p Path) TranslationBaseName() string {
	return p.translationBaseName
}

func (p Path) UniqueID() string {
	return p.uniqueId
}

func (p Path) GoString() string {
	return "domain.Path(" + p.path + ")"
}
