const path = require('path')
const slugify = require('slugify')
const merge = require('lodash.merge')
const nunjucks = require('nunjucks')
const assign = require('assign-deep')

const Media = require('./../factories/media.js')
const parseMarkdownFile = require('./../parsers/markdown.js')

/**
 *  Page - building from markdown file 
 *
 *
 *  @author Björn Hase <me@herr-hase.wtf>
 *  @license http://opensource.org/licenses/MIT The MIT License
 *  @link https://gitea.node001.net/HerrHase/siteomat-webpack-plugin.git
 *
 */

class Page {

    /**
     *
     *
     *  @param {object} file
     *  @param {string} parent
     *  @param {string} fileString
     *  @param {object} [blocks=null]
     *
     */
    constructor(file, parent, fileString, blocks = {}) {

        // parse file
        const result = parseMarkdownFile(fileString)

        // fields merge by default values
        this._fields = merge({
            view: 'page.njk',
            extensions: 'html',
            meta: {
                robots: 'index'
            },
            hidden: false
        }, result.fields)

        // adding filename for html as pathname and relative path in structure
        this._filename = this._resolveFilename(file)
        this._slug = this._resolveSlug(this._filename)
        this._dirPath = this._resolvePath(parent)
        this._permalink = this._dirPath 

        if (this._slug) {
            this._permalink = this._dirPath + '/' + this._slug
        }

        this._filename += '.' + this._fields.extensions

        this._content = result.content
        this._blocks = blocks

        // check for fields and resolve media
        if (this._fields) {
            this._fields = this._resolveMedia(this._fields, this._dirPath)
        }

        // check for fields and resolve media
        if (this._blocks) {
            for (const key of Object.keys(this._blocks)) {
                if (Array.isArray(this._blocks[key])) {
                    this._blocks[key].forEach((fields, index) => {
                        this._blocks[key][index] = this._resolveMedia(fields, this._dirPath + '/_blocks')
                    })
                } else {
                    this._blocks[key] = this._resolveMedia(this._blocks[key], this._dirPath + '/_blocks')
                }
            }
        }
    }

    /**
     *  create Page Object
     *
     *
     *  @return {object}
     *
     */
    get() {
        return assign({
            'content'   : this._content,
            'blocks'    : this._blocks,
            'dirPath'   : this._dirPath,
            'path'      : this._dirPath + '/' + this._filename,
            'permalink' : this._permalink,
            'filename'  : this._filename
        }, this._fields)
    }

    /**
     *
     *
     */
    _resolveMedia(fields, dirPath) {
        for (const key of Object.keys(fields)) {
            if (key === 'src') {
                fields[key] = this._resolveMediaSrc(fields[key], dirPath) 
            }

            if (toString.call(fields[key]) === '[object Object]') {
                fields[key] = this._resolveMedia(fields[key], dirPath)
            }
        }

        return fields
    }

    _resolveMediaSrc(field, dirPath) {
        const media = new Media(dirPath)

        if (typeof field === 'string' || field instanceof String) {
            field = media.resolve(field)
        }

        if (typeof field === 'object' || field instanceof Object) {
            field = media.resolve(field.src, field.sizes)
        }

        return field
    }

    /**
     *
     *
     */
    _resolveSlug(filename) {
        
        let slug = filename
        
        if (slug === 'index') {
            slug = ''
        }

        return slug
    }

    /**
     *  create html-filename = filename
     *
     *  @param  {string} file
     *  @return {string}
     *
     */
    _resolveFilename(file) {

        let filename = file.name

        if (filename === 'index.md') {
            filename = 'index'
        } else {
            if (path.extname(filename) === '.md') {
                filename = filename.replace('.md', '')
            }

            filename = slugify(filename)
        }

        return filename
    }

    /**
     *  pathname = parent
     *
     *  @param  {string} parent
     *  @return {string}
     *
     */
    _resolvePath(parent, slug) {
        let path = parent

        if (parent === '/') {
            path = ''
        }

        return path
    }
}

module.exports = Page
