<template>
<Page @loaded="onPageLoad" @unloaded="onPageUnload">
  <ActionBar flat="true">
    <GridLayout rows="48" columns="auto, *, auto">
      <MDButton variant="text" row="0" col="0" class="bx" :text="icon.back" automationText="Back" @tap="$navigateBack()" />
      <FlexboxLayout row="0" col="2" alignItems="center">
        <MDButton v-if="!filterTrylater" variant="text" class="bx" :text="recipe.tried ? icon.trylaterLine : icon.trylater" @tap="toggleTrylater" />
        <MDButton v-else variant="text" class="bx" :text="icon.check" @tap="recipeTried" />
        <MDButton variant="text" class="bx" :text="recipe.isFavorite ? icon.heart : icon.heartLine" @tap="toggleFavourite" />
        <MDButton variant="text" class="bx" :text="recipe.inCart ? icon.cart : icon.emptyCart" @tap="toggleCart" />
        <MDButton variant="text" v-if="!busy" class="bx" :text="icon.edit" @tap="editRecipe" />
        <MDActivityIndicator v-else :busy="busy" />
      </FlexboxLayout>
    </GridLayout>
  </ActionBar>
  <AbsoluteLayout>
    <Tabs width="100%" height="100%" :selectedIndex="selectedTabIndex" @selectedIndexChange="selectedIndexChange" class="viewRecipe">
      <TabStrip :androidElevation="viewIsScrolled ? 4 : 0">
        <TabStripItem>
          <Label :text="'ovw' | L"></Label>
        </TabStripItem>
        <TabStripItem>
          <Label :text="'ings' | L"></Label>
        </TabStripItem>
        <TabStripItem>
          <Label :text="'Instructions' | L"></Label>
        </TabStripItem>
        <TabStripItem>
          <Label :text="'nos' | L"></Label>
        </TabStripItem>
        <TabStripItem>
          <Label :text="'cmbs' | L"></Label>
        </TabStripItem>
      </TabStrip>
      <TabContentItem>
        <ScrollView @scroll="onScroll" @loaded="overviewLoaded">
          <StackLayout>
            <StackLayout width="100%" :height="screenWidth" verticalAlignment="center" class="imageHolder">
              <Image v-if="recipe.imageSrc" :src="recipe.imageSrc" stretch="aspectFill" width="100%" :height="screenWidth" />
              <Label v-else horizontalAlignment="center" class="bx" fontSize="160" :text="icon.image" />
            </StackLayout>
            <StackLayout margin="16 4 80">
              <Label class="category" :text="`${$options.filters.L(recipe.cuisine)} • ${$options.filters.L(recipe.category)}`" />
              <Label class="title orkm" :text="recipe.title" textWrap="true" />
              <FlexboxLayout class="ratingContainer">
                <Label class="rating bx" v-for="n in 5" :key="n" :text="recipe.rating < n ?icon.starLine:icon.star" @tap="setRating(n)" @longPress="setRating(n)" />
              </FlexboxLayout>
              <Label class="attr" :text="`${$options.filters.L('Difficulty level')}: ${$options.filters.L(recipe.difficulty)}`" textWrap="true" />
              <Label class="attr" :text="`${$options.filters.L('Preparation time')}: ${formattedTime(recipe.prepTime)}`" textWrap="true" />
              <Label class="attr" :text="`${$options.filters.L('Cooking time')}: ${formattedTime(recipe.cookTime)}`" textWrap="true" />
              <FlexboxLayout v-if="recipe.tags.length" class="tagsContainer" flexWrap="wrap">
                <Label class="tagsTitle" :text="`${$options.filters.L('ts')}: `" />
                <Label v-for="(tag, index) in recipe.tags" :key="index" v-if="tag" :text="tag" class="tag" textWrap="false" />
              </FlexboxLayout>
              <GridLayout rows="auto, auto" columns="*, *" class="overviewContainer">
                <GridLayout class="overviewItem" row="0" col="0" rows="auto, auto" columns="*">
                  <MDRipple rowSpan="2" @tap="selectedTabIndex = 1" />
                  <Label row="0" class="bx" :text="icon.item" />
                  <Label row="1" class="itemCount" :text="
                        `${recipe.ingredients.length} ${
                          recipe.ingredients.length == 1
                            ? $options.filters.L('ing')
                            : $options.filters.L('ings')
                        }`
                      " textWrap="true" />
                </GridLayout>
                <GridLayout class="overviewItem" row="0" col="1" rows="auto, auto" columns="*">
                  <MDRipple rowSpan="2" @tap="selectedTabIndex = 2" />
                  <Label row="0" class="bx" :text="icon.step" />
                  <Label row="1" class="itemCount" :text="
                        `${recipe.instructions.length} ${
                          recipe.instructions.length == 1
                          ? $options.filters.L('Instruction')
                          : $options.filters.L('Instructions')
                        }`
                      " textWrap="true" />
                </GridLayout>
                <GridLayout class="overviewItem" row="1" col="0" rows="auto, auto" columns="*">
                  <MDRipple rowSpan="2" @tap="selectedTabIndex = 3" />
                  <Label row="0" class="bx" :text="icon.note" />
                  <Label row="1" class="itemCount" :text="
                        `${recipe.notes.length} ${
                          recipe.notes.length == 1
                          ? $options.filters.L('no')
                          : $options.filters.L('nos')
                        }`
                      " textWrap="true" />
                </GridLayout>
                <GridLayout class="overviewItem" row="1" col="1" rows="auto, auto" columns="*">
                  <MDRipple rowSpan="2" @tap="selectedTabIndex = 4" />
                  <Label row="0" class="bx" :text="icon.outline" />
                  <Label row="1" class="itemCount" :text="
                  `${recipe.combinations.length} ${
                    recipe.combinations.length == 1
                    ? $options.filters.L('cmb')
                    : $options.filters.L('cmbs')
                  }`
                  " textWrap="true" />
                </GridLayout>
              </GridLayout>
              <Label class="attr small" :text="`${$options.filters.L('Last updated')}: ${formattedDate(recipe.lastModified)}`" textWrap="true" />
              <Label class="attr small" :text="`${$options.filters.L('Created')}: ${formattedDate(recipe.created)}`" textWrap="true" />
            </StackLayout>
          </StackLayout>
        </ScrollView>
      </TabContentItem>
      <TabContentItem>
        <ScrollView @scroll="onScroll">
          <GridLayout v-if="!recipe.ingredients.length" rows="*, auto, *, 88" columns="*" class="emptyStateContainer">
            <StackLayout col="0" row="1" class="emptyState">
              <Label class="bx icon" :text="icon.item" textWrap="true" />
              <Label class="title orkm" :text="'pAIng' | L" textWrap="true" />
            </StackLayout>
          </GridLayout>
          <StackLayout v-else padding="16 16 72">
            <AbsoluteLayout class="inputField">
              <TextField width="50%" v-model="yieldMultiplier" keyboardType="number" />
              <Label top="0" class="fieldLabel" :text="`${$options.filters.L('req')} ${$options.filters.L(recipe.yield.unit)}`" />
            </AbsoluteLayout>
            <Label padding="16 0 8" class="title orkm" :text="
                    `${$options.filters.L('ings')} (${positiveYieldMultiplier} ${$options.filters.L(recipe.yield.unit)})`
                  " textWrap="true" />
            <check-box v-for="(item, index) in recipe.ingredients" :key="index" class="ingredient" style="font-family: 'Orkney-Regular'" checkPadding="16" @checkedChange="checkChange" :text="
                    `${
                      roundedQuantity(item.quantity)
                        ? roundedQuantity(item.quantity) + ' '
                        : ''
                    }${roundedQuantity(item.quantity) ? $options.filters.L(item.unit) + ' ' : ''}${
                      item.item
                    }`
                  " />
          </StackLayout>
        </ScrollView>
      </TabContentItem>
      <TabContentItem>
        <ScrollView @scroll="onScroll">
          <GridLayout v-if="!recipe.instructions.length" rows="*, auto, *, 88" columns="*" class="emptyStateContainer">
            <StackLayout col="0" row="1" class="emptyState">
              <Label class="bx icon" :text="icon.step" textWrap="true" />
              <Label class="title orkm" :text="'pAIns' | L" textWrap="true" />
            </StackLayout>
          </GridLayout>
          <StackLayout v-else padding="20 16 62">
            <GridLayout columns="auto ,*" v-for="(instruction, index) in recipe.instructions" :key="index">
              <Label col="0" colSpan="2" class="instruction" :class="{
                    noBorder: index === recipe.instructions.length - 1,
                  }" :text="instruction" textWrap="true" />
              <Label class="count orkm" col="0" :text="index + 1" />
            </GridLayout>
          </StackLayout>
        </ScrollView>
      </TabContentItem>
      <TabContentItem>
        <ScrollView @scroll="onScroll">
          <GridLayout v-if="!recipe.notes.length" rows="*, auto, *, 88" columns="*" class="emptyStateContainer">
            <StackLayout col="0" row="1" class="emptyState">
              <Label class="bx icon" :text="icon.note" textWrap="true" />
              <Label class="title orkm" :text="'pANo' | L" textWrap="true" />
            </StackLayout>
          </GridLayout>
          <StackLayout v-else padding="20 16 62" @loaded="createNotes">
          </StackLayout>
        </ScrollView>
      </TabContentItem>
      <TabContentItem>
        <ScrollView @scroll="onScroll">
          <GridLayout v-if="!recipe.combinations.length" rows="*, auto, *, 88" columns="*" class="emptyStateContainer">
            <StackLayout col="0" row="1" class="emptyState">
              <Label class="bx icon" :text="icon.outline" textWrap="true" />
              <Label class="title orkm" :text="'pACmb' | L" textWrap="true" />
            </StackLayout>
          </GridLayout>
          <StackLayout v-else padding="8 0 80">
            <GridLayout columns="*" v-for="(combination, index) in recipe.combinations" :key="index" androidElevation="1" class="combination">
              <MDRipple @tap="viewCombination(combination)" />
              <Label verticalAlignment="center" class="combinationTitle" :text="getCombinationTitle(combination)" textWrap="true" />
            </GridLayout>
          </StackLayout>
        </ScrollView>
      </TabContentItem>

    </Tabs>
    <GridLayout id="btnFabContainer" rows="*, auto" columns="*, auto">
      <transition name="dolly" appear>
        <MDFloatingActionButton row="1" col="1" src="res://share" @tap="shareHandler" v-if="showFab" />
      </transition>
    </GridLayout>
  </AbsoluteLayout>
</Page>
</template>

<script>
import {
  Application,
  Color,
  ImageSource,
  Screen,
  Utils,
  Span,
  FormattedString,
  Label,
  GridLayout,
  ItemSpec,
  Observable,
}
from "@nativescript/core"
import {
  Feedback,
  FeedbackType,
  FeedbackPosition
}
from "nativescript-feedback"
import * as Toast from "nativescript-toast"
import * as SocialShare from "@nativescript/social-share"
import {
  localize
}
from "@nativescript/localize"
const intl = require( "nativescript-intl" );
import {
  mapActions,
  mapState
}
from "vuex"
import EditRecipe from "./EditRecipe.vue"
import ViewRecipe from "./ViewRecipe.vue"
import ShareChooser from "./modal/ShareChooser.vue"
let feedback = new Feedback()
export default {
  props: [ "filterTrylater", "recipeID" ],
  data() {
    return {
      busy: false,
      yieldMultiplier: 1,
      recipe: null,
      showFab: false,
      selectedTabIndex: 0,
      currentRecipeID: this.recipeID,
      viewIsScrolled: false,
      isScrolled: [ false, false, false, false, false, false ],
      hideActionBar: false,
      overviewTab: null,
      checks: [],
    }
  },
  computed: {
    ...mapState( [ "icon", "recipes" ] ),
    screenWidth() {
      return Screen.mainScreen.widthDIPs
    },
    positiveYieldMultiplier() {
      return Math.abs( this.yieldMultiplier ) > 0 ? Math.abs( parseFloat( this.yieldMultiplier ) ) : 1
    },
    isLightMode() {
      return Application.systemAppearance() === "light"
    },
  },
  methods: {
    ...mapActions( [ "toggleStateAction", "setCurrentComponentAction", "overwriteRecipeAction", "setRecipeAsTriedAction", "setRatingAction", "toggleCartAction" ] ),
    onPageLoad( args ) {
      const page = args.object;
      page.bindingContext = new Observable();
      this.busy = false
      setTimeout( ( e ) => {
        this.setCurrentComponentAction( "ViewRecipe" )
      }, 500 )
      this.showFab = true
      this.yieldMultiplier = this.recipe.yield.quantity
      this.keepScreenOn( true )
      this.syncCombinations()
    },
    onPageUnload() {
      feedback.hide()
      this.keepScreenOn( false )
    },
    overviewLoaded( args ) {
      this.overviewTab = args
    },
    // HELPERS
    niceDates( time ) {
      let lastTried = new Date( time ).getTime()
      let now = new Date().getTime()
      let midnight = new Date().setHours( 0, 0, 0, 0 )
      let diff = ( now - lastTried ) / 1000
      let dayDiff = Math.ceil( diff / 86400 )
      if ( isNaN( dayDiff ) || dayDiff < 0 ) return ""

      function duration( value ) {
        return localize( value )
      }
      return (
        ( diff < 86400 && lastTried > midnight && duration( "today" ) ) || ( dayDiff == 1 && "yesterday" ) || ( dayDiff < 7 && dayDiff + " " + duration( "dAgo" ) ) || ( dayDiff < 31 && Math.round( dayDiff / 7 ) + " " + duration(
          "wAgo" ) ) || ( dayDiff < 366 && Math.round( dayDiff / 30 ) + " " + duration( "mAgo" ) ) || ( dayDiff > 365 && duration( "ltAgo" ) ) )
    },
    selectedIndexChange( args ) {
      this.selectedTabIndex = args.object.selectedIndex
      this.viewIsScrolled = this.isScrolled[ this.selectedTabIndex ]
    },
    showLastTried() {
      feedback.show( {
        title: `${localize('triedInfo')} ${this.niceDates(
          this.recipe.lastTried
        )}`,
        titleColor: new Color( `${this.isLightMode ? "#f1f3f5" : "#212529"}` ),
        backgroundColor: new Color( "#ff5200" ),
      } )
    },
    roundedQuantity( quantity ) {
      return Math.abs( Math.round(
        ( quantity / this.recipe.yield.quantity ) * this.positiveYieldMultiplier * 100 ) / 100 )
    },
    keepScreenOn( boolean ) {
      let activity = Application.android.foregroundActivity || Application.android.startActivity
      let window = activity.getWindow()
      if ( boolean ) window.addFlags( android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON )
      else window.clearFlags( android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON )
    },
    formattedTime( time ) {
      let t = time.split( ":" )
      let h = parseInt( t[ 0 ] )
      let m = parseInt( t[ 1 ] )
      let hr = localize( 'hr' )
      let min = localize( 'min' )
      return h ? ( m ? `${h} ${hr} ${m} ${min}` : `${h} ${hr}` ) : `${m} ${min}`
    },
    formattedDate( date ) {
      let d = new Date( date )
      var dateFormat = new intl.DateTimeFormat( null, {
        'year': 'numeric',
        'month': 'long',
        'day': 'numeric',
        'hour': 'numeric',
        'minute': 'numeric',
      } ).format( d );
      return `${dateFormat}`
    },
    isValidURL( string ) {
      let pattern = new RegExp( "^https?|^www", "ig" )
      return pattern.test( string )
    },
    getCombinationTitle( id ) {
      return this.recipes.filter( ( e ) => e.id === id )[ 0 ].title
    },
    syncCombinations() {
      let combinationForOtherRecipes = this.recipes.filter(
        ( e ) => e.combinations.indexOf( this.currentRecipeID ) >= 0 || this.recipe.combinations.includes( e.id ) ).map( ( e ) => e.id )
      this.recipe.combinations = combinationForOtherRecipes
      this.overwriteRecipeAction( {
        id: this.currentRecipeID,
        recipe: this.recipe,
      } )
    },
    checkChange( args, index ) {
      let check = args.object
      this.checks[ index ] = !this.checks[ index ]
    },
    // NAVIGATION HANDLERS
    onScroll( args ) {
      this.viewIsScrolled = this.isScrolled[ this.selectedTabIndex ] = args.scrollY > 8 ? true : false
    },
    editRecipe() {
      this.showFab = false
      this.busy = true
      this.$navigateTo( EditRecipe, {
        props: {
          navigationFromView: true,
          filterTrylater: this.filterTrylater,
          recipeID: this.currentRecipeID,
        },
        backstackVisible: false,
      } )
    },
    viewCombination( combination ) {
      this.recipe = this.recipes.filter( ( e ) => e.id === combination )[ 0 ]
      this.currentRecipeID = combination
      this.syncCombinations()
      this.selectedTabIndex = 0
      this.overviewTab.object.scrollToVerticalOffset( 0, true )
      setTimeout(
        ( e ) => this.recipe.tried && this.recipe.lastTried && this.showLastTried(), 500 )
    },
    // SHARE ACTION
    shareHandler() {
      if ( this.recipe.imageSrc ) {
        this.$showModal( ShareChooser, {
          props: {
            title: "shr",
            helpIcon: 'share',
          },
        } ).then( ( result ) => {
          switch ( result ) {
            case "photo":
              ImageSource.fromFile( this.recipe.imageSrc ).then( ( res ) => {
                SocialShare.shareImage( res, "Share recipe photo using" )
              } )
              break
            case "recipe":
              this.shareRecipe()
              break
            default:
              break
          }
        } )
      } else {
        this.shareRecipe()
      }
    },
    shareRecipe() {
      let overview = `${
        this.recipe.title
      }\n\n${localize( "Cuisine" )}: ${localize( this.recipe.cuisine)}\n${localize( "Category" )}: ${localize( this.recipe.category)}\n${localize( "ts" )}: ${this.recipe.tags.join(", ")}\n${localize( "stars" )}: ${this.recipe.rating}\n${localize( "Difficulty level" )}: ${localize( this.recipe.difficulty)}\n${localize("Preparation time")}: ${this.formattedTime(
        this.recipe.prepTime
      )}\n${localize( "Cooking time" )}: ${this.formattedTime(this.recipe.cookTime)}\n`
      let shareContent = overview
      if ( this.recipe.ingredients.length ) {
        let ingredients = `\n\n${localize( "ings" )} (${
          this.yieldMultiplier
        } ${localize( this.recipe.yield.unit )}):\n\n`
        this.recipe.ingredients.forEach( ( e ) => {
          ingredients += `- ${
            e.quantity
              ? this.roundedQuantity(e.quantity) + " " + this.$options.filters.L(e.unit) + " "
              : ""
          }${e.item}\n`
        } )
        shareContent += ingredients
      }
      if ( this.recipe.instructions.length ) {
        let instructions = `\n\n${localize( "Instructions" )}:\n\n`
        this.recipe.instructions.forEach( ( e, i ) => {
          instructions += `${i + 1}. ${e}\n\n`
        } )
        shareContent += instructions
      }
      if ( this.recipe.notes.length ) {
        let notes = `\n${localize( "nos" )}:\n\n`
        this.recipe.notes.forEach( ( e, i ) => {
          notes += `${i + 1}. ${e}\n\n`
        } )
        shareContent += notes
      }
      if ( this.recipe.combinations.length ) {
        let combinations = `\n${localize( "cmbs" )}:\n\n`
        this.recipe.combinations.forEach( ( e, i ) => {
          combinations += `${i + 1}. ${this.getCombinationTitle(e)}\n\n`
        } )
        shareContent += combinations
      }
      let sharenote = '\n' + localize( "appCrd" )
      shareContent += sharenote
      SocialShare.shareText( shareContent, "Share recipe using" )
    },
    // DATA HANDLERS
    toggle( key, setDate ) {
      this.toggleStateAction( {
        id: this.currentRecipeID,
        recipe: this.recipe,
        key,
        setDate,
      } )
    },
    toggleFavourite() {
      this.recipe.isFavorite ? Toast.makeText( localize( "unfavd" ) ).show() : Toast.makeText( localize( "favd" ) ).show()
      this.toggle( "isFavorite" )
    },
    toggleTrylater() {
      this.recipe.tried ? Toast.makeText( localize( "aTry" ) ).show() : Toast.makeText( localize( "rmTry" ) ).show()
      this.toggle( "tried" )
    },
    recipeTried() {
      this.setRecipeAsTriedAction( {
        id: this.currentRecipeID,
        recipe: this.recipe,
      } )
      this.$navigateBack()
    },
    setRating( rating ) {
      if ( rating !== this.recipe.rating ) {

        this.setRatingAction( {
          id: this.currentRecipeID,
          recipe: this.recipe,
          rating,
        } )
      }
    },
    // SHOPPINGLIST
    toggleCart() {
      if ( !this.recipe.inCart ) {

      } else {

      }
      this.toggleCartAction( {
        id: this.currentRecipeID,
        recipe: this.recipe,
      } )
    },
    // NOTES
    createNote( note, i ) {
      const vm = this
      let regex = /(https?:\/\/[^\s]+)/g
      const grid = new GridLayout()
      const firstCol = new ItemSpec( 1, "auto" )
      const secondCol = new ItemSpec( 1, "star" )
      const label1 = new Label()
      const label2 = new Label()
      label1.class = "note"
      label1.textWrap = true
      label2.class = "noteCount orkm"
      label2.text = i + 1
      let formattedString = new FormattedString()
      let textArray = note.split( regex )

      function createSpan( text, isUrl ) {
        let span = new Span()
        span.text = text
        span.fontSize = 14
        if ( isUrl ) {
          span.textDecoration = "underline"
          span.color = "#ff5200"
          span.on( "linkTap", () => Utils.openUrl( text ) )
        }
        formattedString.spans.push( span )
      }
      textArray.forEach( ( text ) => {
        createSpan( text, regex.test( text ) )
      } )
      label1.formattedText = formattedString
      grid.addChild( label1 )
      grid.addChild( label2 )
      GridLayout.setColumn( label1, 0 )
      GridLayout.setColumn( label2, 0 )
      GridLayout.setColumnSpan( label1, 2 )
      grid.addColumn( firstCol )
      grid.addColumn( secondCol )
      return grid
    },
    createNotes( args ) {
      const stack = args.object
      if ( !stack.getChildrenCount() ) {
        this.recipe.notes.forEach( ( note, i ) => {
          stack.addChild( this.createNote( note, i ) )
        } )
      }
    },
  },
  created() {
    this.recipe = this.recipes.filter( ( e ) => e.id === this.currentRecipeID )[ 0 ]
    this.checks = this.recipe.ingredients.map( e => true )
  },
  mounted() {
    this.showFab = true
    setTimeout(
      ( e ) => this.recipe.tried && this.recipe.lastTried && this.showLastTried(), 500 )
  },
}
</script>
