module Model.Translations
  ( translationsDecoder
  , Translations
  , Translation
  , getMessage
  , getParamMessage
  ) where

import Maybe exposing (withDefault)
import Json.Decode as Json exposing ((:=))
import String

type alias Translations = List Translation

translationsDecoder : Json.Decoder Translations
translationsDecoder = Json.list translationDecoder

type alias Translation =
  { key : String
  , message : List MessagePart
  }

getTranslation : String -> Translations -> Maybe (List MessagePart)
getTranslation key translations =
  translations
    |> List.filter (\translation -> translation.key == key)
    |> List.head
    |> Maybe.map .message

translationDecoder : Json.Decoder Translation
translationDecoder =
  Json.object2 Translation
    ("key" := Json.string)
    ("message" := Json.list partDecoder)

type MessagePart =
  Order Int
  | Str String

partDecoder : Json.Decoder MessagePart
partDecoder =
  ("tag" := Json.string) `Json.andThen` partDecoderWithTag

partDecoderWithTag : String -> Json.Decoder MessagePart
partDecoderWithTag tag =
  case tag of
    "Order" -> Json.object1 Order ("contents" := Json.int)
    _ -> Json.object1 Str ("contents" := Json.string)

-----

getMessage : String -> Translations -> String
getMessage = getParamMessage []

getParamMessage : List String -> String -> Translations -> String
getParamMessage values key translations =
  getTranslation key translations
    |> Maybe.map (\parts -> String.concat (List.map (replacePart values) parts))
    |> withDefault key

replacePart : List String -> MessagePart -> String
replacePart values part =
  case part of
    Str str -> str
    Order n ->
      values
        |> List.drop (n - 1)
        |> List.head
        |> withDefault ("{" ++ (toString n) ++ "}")