#encoding: UTF-8
# ESTE CONTROLADOR SÓLO ES ACCESIBLE POR ENTRENADORES
class PlansController < ApplicationController
  include ApplicationHelper
  include VolumeHelper

  before_action :user_is_employee?, except: :update_users
  before_action :set_plan, only: [:pdf, :mail, :sms, :show, :new_meal, :add_program_meal, :new_routine, :edit, :update, :destroy, :print, :note, :chat]
  before_action :set_user, only: [:new]
  layout "admin"
  
  def index
    @user = current_user
    @plans = @user.plans
    @today = Time.zone.now.to_date
  end

  def show
    @user = @plan.user
    @messages = current_user.messages.where(emisor_id: @user.id).or(@user.messages.where(emisor_id: current_user.id)).order(created_at: :asc)
    @message = Message.new(user_id: @user.safe_url)
    @section = "diet"
    if params[:section]
      @section = "routine" if params[:section] == "routine"
    end
    respond_to do |format|
      format.html
      format.pdf do
        render pdf: @plan.pdf_name, layout: 'pdf.html'
      end
    end
  end

  def update_users
    User.all.each do |user|
			if user.plans.any?
				today = Time.zone.now.to_date
				finish = user.plans.order(finish: :asc).last.finish
        status = finish > today ? 'active' : 'inactive'
        if user.last_plan != finish && user.status != status
          user.last_plan = finish
          user.coach = user.plans.last.trainer
          user.status = status
          user.save!
        end
			else
        user.update(last_plan: nil, status: 'ghost') if user.status != 'ghost'
			end
		end
    render layout: false
  end

  def pdf
    render :layout => "pdf"
  end

  def print
    @section = "diet"
    @section = params[:section] if params[:section]
    render :layout => "print"
  end
  
  def sms
  end

  def mail
    @user = @plan.user
    PlanMailer.show(user: @user.id).deliver_now
  end

  def meal_substitute
    @portion = Portion.find(params[:portion_id])
    @meal_portion = MealPortion.find(params[:meal_portion_id])
    @plan = @meal_portion.meal.plan
    @meal = @meal_portion.meal
    # reseteamos substitutos para facilitar implementación en dom
    if params[:data]
      params[:data].each do |key, value| # Item contiene info de substituto: {id, quantity, removed}, @ver: ../addSubstitute.js
        substitute = @meal_portion.substitutes.where(portion_id: value[:id]).first
        if value[:removed].to_s == "true"
          substitute.destroy
        else
          substitute.update(quantity: value[:quantity]) if substitute # actualizamos la cantidad del substituto
        end
      end
    end
    @sub = @meal_portion.substitutes.create(portion_id: params[:portion_id], quantity: @portion.quantity)
  end

  def note
    observations = @plan.trainer_observations
    if observations.blank?
      observations = "#{Time.zone.now.to_date} ~ #{params[:note]}"
    else
      observations += " | #{Time.zone.now.to_date} ~ #{params[:note]}"
    end
    @plan.update(trainer_observations: observations)
  end

  def chat
    @message = Message.create({
      emisor_id: current_user.id,
      user_id: @user.id,
      message: params[:message],
      status: "new"
    })
  end

  def new
    today = Time.zone.now.to_date
    @last = @user.plans.order(created_at: :asc).last #debe ser igual a la última fecha de finalización
    @plan = Plan.new({
      init: today, 
      finish: today + 4.weeks, # 35 días #Acá van sólo 4 semanas, es una semana extra de cortesía para tiempo adicional para el plan
      trainer_id: 8,
      progress: @last ? @last.progress + 1 : 0,
      user_id: @user.id,
      macros_protein: @last ? @last.macros_protein : 0,
      macros_carbs: @last ? @last.macros_carbs : 0,
      macros_fats: @last ? @last.macros_fats : 0,
      groups: @last ? @last.groups : "",
      objective: @last ? @last.objective : "",
      cardio_sessions: @last ? @last.cardio_sessions : "",
      cardio_schedule: @last ? @last.cardio_schedule : "",
      cardio_time: @last ? @last.cardio_time : "",
      steps: @last ? @last.steps : "",
    }) 
    set_diet_routine(@last)
  end

  def update_diet_program
    @plan = Plan.find(params[:id])
    @plan.update(current_diet: params[:diet_id])
    @plan.create_diet
    render :layout => false
  end
  
  def update_routine_program
    @plan = Plan.find(params[:id])
    @plan.update(current_routine: params[:routine_id])
    @plan.create_routine
    render :layout => false
  end

  def create
    @plan = Plan.new(plan_params)
    # FIX: Actualizar con nuevos entrenadores
    @plan.user.update(coach_id: @plan.trainer_id)
    # @plan.update(supplements: @plan.previous_plan.supplements)
    if @plan.save
      @plan.user.update( last_plan: @plan.finish )
      if current_user.role == "receptionist"
        flash[:notice] = "Los datos del paciente 'Inbody/Circunferencias' fueron registrados con éxito."
        redirect_to "/recepcion"
      else
        flash[:notice] = "Plan creado con éxito."
        redirect_to edit_plan_path(@plan)
      end
    else
      render :new
    end
  end

  def edit
    @user = @plan.user
    @routines = Program.where(tipo: "routine").order(:number)
    @diets = Program.where(tipo: "diet").order(:number)
    @meals = Program.where(tipo: "meal").order(:number)
    @plans = @user.plans.where.not(finish: nil).order(init: :desc)
    @messages = current_user.messages.where(emisor_id: @user.id).or(@user.messages.where(emisor_id: current_user.id)).order(created_at: :asc)
    @message = Message.new(user_id: @user.safe_url)
    set_medical_history
  end

  def new_portion
    @meal = Meal.find(params[:meal_id])
    @plan = @meal.plan
    @portion = Portion.find(params[:id])
    @meal_portion = @meal.meal_portions.where(portion_id: @portion.id, quantity: @portion.quantity.to_i).first_or_create!
    @meal_portion.update(number: @meal.meal_portions.count)
    render :layout => false
  end

  def new_workout
    @routine = Routine.find(params[:routine_id])
    if params[:data]
      params[:data].each do |key, value| # Item contiene info de substituto: {id, quantity, removed}, @ver: ../addSubstitute.js
        rw = @routine.routine_workouts.find(value[:id])
        if value[:removed].to_s == "true"
          rw.destroy if rw
        else
          rw.update(workout_id: value[:workout], series: value[:series],  repetitions: value[:reps], group_by_series: value[:group], charge: value[:charge], number: value[:number], notes: value[:note]) if rw
        end
      end
    end
    @plan = @routine.plan
    @workout = Workout.where(category: params[:category]).first
    @rw = @routine.routine_workouts.create(workout_id: @workout.id, number: @routine.routine_workouts.count + 1)
    render :layout => false
  end

  def new_meal
    @plan.update(plan_params)
    if params[:uuid]
      add_program(params[:uuid])
    else
      @meal = @plan.meals.create(number: @plan.meals.count+1)
    end
    render :layout => false
  end

  def new_routine
    @plan.update(plan_params)
    @routine = @plan.routines.create(number:@plan.routines.count+1)
  end
  
  def update
    @plan.update(plan_params)
  end

  def destroy
    @user = @plan.user
    @plan.routines.each { |r| r.routine_workouts.delete_all }
    @plan.routines.delete_all
    @plan.meals.each { |m| m.meal_portions.delete_all }
    @plan.meals.delete_all
    @plan.destroy
    respond_to do |format|
      format.html { redirect_to "/pacientes/#{@user.safe_url}" }
      format.json { head :no_content }
    end
  end

  private

    def add_program(_id)
      @program = Plan.find(_id)
      @program.meals.each do |m|
        meal = m.dup
        meal.update(plan_id: @plan.id, number: @plan.meals.count+1)
        m.meal_portions.each do |mp|
          meal_portion = mp.dup
          meal_portion.update(meal_id: meal.id)
          mp.substitutes.each do |sbt|
            substitute = sbt.dup 
            substitute.update(equalable_id: meal_portion.id)
          end
        end
      end
    end

    def set_user
      @user = User.find(params[:id])
      set_medical_history
      if !data_complete?(@user)
        redirect_to "/pacientes/#{@user.id}/edit"
      end
    end

    def set_diet_routine(_last)
      if _last
        @plan.current_routine = "clone"
        @plan.current_diet = "clone"
      else
        rutina = Program.find(36) #de cero
        @plan.current_routine = rutina.plan.id if rutina #de cero
        diet = Program.find(@user.sex == "male" ? 10 : 9) # selección de dieta, hombre o mujer, esos son los ids, no se consultan por otros atributos porque Rick los actualiza cada cierto tiempo
        @plan.current_diet = diet.plan.id if diet
      end
    end

    def set_medical_history
      @medical_history = @user.medical_history
      # defaults
      @medical_history = MedicalHistory.create(user: @user, ) if !@medical_history
    end

    def set_plan
      @plan = Plan.find(params[:id])
      @user = @plan.user
      @messages = Message.where(emisor_id: [@user.id, current_user.id]).order(created_at: :asc)
      @message = Message.new(user_id: @user.safe_url)
    end

    def plan_params
      params.require(:plan).permit(:plicometria, :factor_activity, :ped, :mlag, :objective, :back, :side, :front, :rer_level, :groups, :user_id, :msg_1, :msg_2, :msg_3, :gluteus, :arm_left, :arm_right, :chest, :waist, :thight_left, :thight_right, :calf_left, :calf_right, :bci, :bcd, :progress,
      :trainer_observations, :adjust, :subscription_id, :current_diet, :current_routine, :charge, :macros_protein, :macros_carbs, :macros_fats, :cardio, :trainer_id, :init, :finish, :kg, :corporal_fat, :tmb, :supplements, :vme, :rer, :steps, :cardio_sessions, :cardio_schedule, :cardio_time, :medicine,
        meals_attributes:
          [:_destroy, :id, :title, :number, :body,
            meal_portions_attributes: [:_destroy, :id, :quantity, :meal_id, :portion_id, :number,
              substitutes_attributes: [:_destroy, :id, :portion_id, :quantity]
            ]
          ],
        routines_attributes:
          [:_destroy, :id, :title, :instructions, :description, :number,
            routine_workouts_attributes: 
              [:id, :_destroy, :routine_id, :category, :category, :highlight, :workout_id, :series, :notes, :repetitions, :workout_series, :number, :group_by_series, :charge]
          ]
        )
    end

end