Mustache      = require("mustache")
i18n          = require("i18next")
fs            = require("fs")
Handlebars    = require("handlebars")
handlebarsLayouts = require("handlebars-layouts")(Handlebars)
juice         = require("juice")
charttile     = require('./charttile')
path          = require('path')

TEMPLATE_DIR      = "#{__dirname}/../email_templates"
LAYOUT_DIR        = "#{__dirname}/../layouts"
LANGUAGE_DIR      = "#{__dirname}/../language"
CSS_DIR           = "#{__dirname}/../"
DEFAULT_LAYOUT    = "teacher_email"


FIXTURES = require("./fixtures")
  

class Templater

  ###
  constructor

  Loads templates into memory
  ###
  constructor: () ->
    @templates = {}
    @translate_functions = {}
    files = fs.readdirSync TEMPLATE_DIR

    


    ## Register all Handlebars layouts
    @layouts = { } # { name: path }
    files = fs.readdirSync LAYOUT_DIR
    for file in files
      if file.indexOf('.hb') isnt -1
        layoutPath  = [LAYOUT_DIR, file].join("/")
        partial     = fs.readFileSync layoutPath, 'utf8'
        layoutName  = file.replace('.hb', '')
        @layouts[layoutName] = partial


    # Options for inlining css
    @juiceOptions = 
      applyStyleTags: false
      removeStyleTags: false
      url:  ["file://", CSS_DIR].join("")




  # Get the template if it has already been loaded to memory
  # Otherwise, load it into memory
  _getTemplate: (fileName, language) =>

    if not @templates[fileName]?
      @templates[fileName] = {}

    if fileName.indexOf(".hb") is -1
      fileNameExt = fileName + ".hb"

    if @templates[fileName][language]?
      return @templates[fileName][language]
    else
      

      templates = [
        'parentMain',
        'pipes',
        'responsiveMain',
        'studentMain',
        'teacherMain',
        'template3',
        'template3White',
        'template_CDM',
        'teacherNew'
      ]

      for templateName in templates
        Handlebars.registerPartial templateName, @layouts[templateName]

      
      # end terrible hack.

      templatePath  = [TEMPLATE_DIR, fileNameExt].join("/")
      templateRaw   = fs.readFileSync templatePath, 'utf8'
      template      = Handlebars.compile templateRaw
      @templates[fileName][language] = template
      return @templates[fileName][language]



  # render handlebars email
  fetchEmail: (fileName, templateVars, options, callback) =>

    # Only use the basename of the file for fixtures and such
    fullFilename = fileName
    fileName = path.basename(fileName)

    # Set language if not passed in
    if not options.language?
      options.language = 'en'


    # Get translate function
    @_get_translate_function options.language, (t) =>

      # Helper for translations in handlebars
      # The second param 'options' is used for passing in data to 
      # translation strings.  
      # Example usage:
      # {{ I18n "dojo-templater.emails:initial_parent_invite.would_like_to_share" link1=inviteLink  }}
      Handlebars.registerHelper 'I18n', (str, options) =>
        if options and options.hash
          options = options.hash
        else
          options = {}
        return t(str, options)


      # helper function for {{ifeq a 5}} ... {else} ... {/ifeq}
      Handlebars.registerHelper 'ifeq', (a, b, options) ->
        if(a is b)
          return options.fn(this);
        else
          return options.inverse(this);
      
      # Get the template
      try 
        template = @_getTemplate fullFilename, options.language
      catch err
        return callback err

      # Use fixtures?
      if options.useFixtures
        templateVars = FIXTURES[fileName]

       
      
      # templateVars must be defined, or handlebars will throw an error
      if not templateVars?
        templateVars = {}
      
      
      # Compile template with vars
      compiled = template(templateVars)

      
      # Inline CSS
      juice.juiceContent compiled, @juiceOptions, (err, htmlEmail) =>
        
        # make the object to return
        result = 
          html:       htmlEmail
          plain:      @_html_to_plain(htmlEmail)
          subject:    @_getSubject fileName, templateVars, t

        # callback
        callback err, result


  ###
  ###


  # Swap {{ var }} with the variable name in the template
  _insert_vars: (template_html, template_vars) =>
    output = Mustache.render(template_html, template_vars)
    return output

  
  ###
  ###


  # Get subject for a given filename
  # The subject line is in a field called '_subject' in the language
  # file for this email. Translate it here
  _getSubject: (file_name, template_vars, t) =>

    subject           = t("dojo-templater.emails:#{file_name}._subject")
    subjectTemplate   = Handlebars.compile subject
    compiled          = subjectTemplate(template_vars)


    ## Hack to catch when subject does not get translated
    ## Currently, subject works fine locally, not on staging or production
    if compiled.indexOf("dojo-templater") isnt -1
      compiled = "Welcome to ClassDojo :)"

    return compiled


  ###
  ###


  ###
  Every language needs to be inited seperately, but
  we cache the function so that we don't have to load
  the resource files every time

  ###
  _get_translate_function: (language, callback) =>
    # console.log "Initing with lang: #{language} <br/><br/>"
    if not @translate_functions[language]?
      i18n.init {
        lng: language,
        fallbackLng: 'en',
        ns: {
          namespaces: ['dojo-templater.layouts', 'dojo-templater.emails'], 
          defaultNs: 'dojo-templater.layouts'
        }, 
        resGetPath: "#{__dirname}/../language/__lng__/__ns__.json"
      }, (t) =>
        @translate_functions[language] = t
        callback(t)
    else
      callback(@translate_functions[language])



  ###
  ### 


  # Take an html string and return a plain text string
  _html_to_plain: (html) =>
    return if not html?
    str=html
    str=str.replace(/<style>([^<]*)<\/style>/, "")
    str=str.replace(/<br>/gi, "\n");
    str=str.replace(/<p.*>/gi, "\n");
    str=str.replace(/<a.*href=\"(.*?)\".*>(.*?)<\/a>/gi, " $2 (Link->$1) ");
    str=str.replace(/<(?:.|\s)*?>/g, "");

    return str

module.exports = Templater
