class PreSalesController < ApplicationController
  before_action :set_pre_sale, only: [:show, :edit, :update, :destroy]

  # GET /pre_sales/new
  def new; end

  # POST /pre_sales
  # POST /pre_sales.json
  def create
    total_in_pre_sales = 0
    @pre_sale = PreSale.new(pre_sale_params)
    @pre_sale.user_id = current_user.id

    # Sumar los totales de los presales en caso que exista.
    PreSale.where(user_id: @pre_sale.user_id).each do |pre|
      total_in_pre_sales = total_in_pre_sales + pre.total
    end

    #precio unitario
    @pre_sale.unit_price = @pre_sale.product.get_price_sale(OpenCashRegister.find(@pre_sale.open_cash_register_id).pointsale.id)

    @pre_sale.get_totals

    total_in_pre_sales += @pre_sale.total

    respond_to do |format|
      if has_enough_stock?(@pre_sale)
        #cuando la venta es a credito checar que el credito permita esta nueva venta
        if @pre_sale.sale_type == "credit"
          debiting = @pre_sale.customer.get_debiting
          if @pre_sale.customer.sale_approved?(debiting + total_in_pre_sales)
            if @pre_sale.save
              format.js
            else
              format.json { render json: @pre_sale.errors.values, status: :unprocessable_entity }
            end
          else
            @pre_sale.errors.add(:customer_id, "El cliente ya no tiene crédito disponible.")
            format.json { render json: @pre_sale.errors.values, status: :unprocessable_entity }
          end
        elsif @pre_sale.sale_type == "cash"
          if  @pre_sale.save
            format.js
          else
            format.json { render json: @pre_sale.errors.values, status: :unprocessable_entity }
          end
        elsif @pre_sale.sale_type == "reserved"
          if  @pre_sale.save
            format.js
          else
            format.json { render json: @pre_sale.errors.values, status: :unprocessable_entity }
          end
        end
      else
        @pre_sale.errors.add(:base, "Stock insuficiente del producto #{@pre_sale.product.name}")
        format.json { render json: @pre_sale.errors.values, status: :unprocessable_entity }
        format.js
      end
    end
  end

  # PATCH/PUT /pre_sales/1
  # PATCH/PUT /pre_sales/1.json
  def update
    @pre_sale.quantity = params[:pre_sale][:quantity].to_i
    availableProduct = AvailableProduct.find_by(pointsale_id: current_user.pointsale_id, product_id: @pre_sale.product_id)

    same_product_quantity = 0
    total_in_pre_sales = 0
    PreSale.where(user_id: current_user.id, product_id: @pre_sale.product_id).where.not(id: @pre_sale.id).each do |pre|
      total_in_pre_sales += pre.total
      same_product_quantity += pre.quantity
    end

    total_quantity = same_product_quantity + @pre_sale.quantity
    respond_to do |format|
      if availableProduct.stock >= total_quantity
        @pre_sale.get_totals
        total_in_pre_sales += @pre_sale.total
        if !@pre_sale.credit?
          @pre_sale.update(pre_sale_params)
          format.json { render json: @pre_sale }
        elsif @pre_sale.customer.sale_approved?(@pre_sale.customer.get_debiting + total_in_pre_sales)
          @pre_sale.update(pre_sale_params)
          format.json { render json: @pre_sale }
        else
          @pre_sale.errors.add(:base, "El cliente ya no tiene crédito disponible")
          format.json { render json: @pre_sale.errors.values, status: :unprocessable_entity }
        end
      else
        @pre_sale.errors.add(:base, "Stock insuficiente del producto #{@pre_sale.product.name}")
        format.json { render json: @pre_sale.errors.values, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /pre_sales/1
  # DELETE /pre_sales/1.json
  def destroy
    respond_to do |format|
      if @pre_sale.destroy
        format.json { head :ok }
      end
    end
  end

  def add_pre_sale_by_barcode
    total_in_pre_sales = 0
    pointsale = OpenCashRegister.get_pointsale(params[:open_cash_register_id], "open_cash_register")
    @product = pointsale.products.find_by("barcode = ? and stock > 0", params[:barcode])

    if @product.blank?
      format.js { render action: "create" }
    else
      # ir sumando todos los presales que tiene, para ver si lo abarca el credito
      PreSale.where(user_id: current_user.id).each do |pre|
        total_in_pre_sales = total_in_pre_sales + pre.total
      end

      @pre_sale = PreSale.new
      @pre_sale.customer_id = params[:customer_id]
      @pre_sale.user_id = current_user.id
      @pre_sale.open_cash_register_id = params[:open_cash_register_id]
      @pre_sale.product_id = @product.id
      @pre_sale.sale_type = params[:sale_type]

      #precio unitario
      @pre_sale.unit_price = @pre_sale.product.get_price_sale(OpenCashRegister.find(@pre_sale.open_cash_register_id).pointsale.id)

      @pre_sale.get_totals

      total_in_pre_sales = total_in_pre_sales + @pre_sale.total

      #cuando la venta es a credito checar que el credito permita esta nueva venta
      respond_to do |format|
        if has_enough_stock?(@pre_sale)
          if @pre_sale.sale_type == "credit"
            debiting = @pre_sale.customer.get_debiting
            if @pre_sale.customer.sale_approved?(debiting + total_in_pre_sales)
              if @pre_sale.save
                format.js { render action: "create" }
              end
            else
              @pre_sale.errors.add(:customer_id, "El cliente ya no tiene crédito disponible.")
              format.json { render json: @pre_sale.errors.values, status: :unprocessable_entity }
              format.js { render action: "create" }
            end
          elsif @pre_sale.sale_type == "cash"
            if  @pre_sale.save
              format.js { render action: "create" }
            else
              format.json { render json: @pre_sale.errors.values, status: :unprocessable_entity }
            end
          elsif @pre_sale.sale_type == "reserved"
            if  @pre_sale.save
              format.js
            else
              format.json { render json: @pre_sale.errors.values, status: :unprocessable_entity }
            end
          end
        else
          @pre_sale.errors.add(:base, "Stock insuficiente del producto #{@pre_sale.product.name}")
          format.json { render json: @pre_sale.errors.values, status: :unprocessable_entity }
        end
      end
    end
  end

  def update_presale_customer
    @pre_sales = PreSale.where(user_id: current_user.id)
    @pre_sales.update_all(customer_id: params[:customer_id], sale_type: 1) if @pre_sales.present?
    respond_to do |format|
      format.json { head :ok }
    end
  end

  def update_saletype
    pre_sales = PreSale.where(user_id: current_user.id)
    type =
      case params[:type]
      when "credit" then
        0
      when "cash" then
        1
      when "reserved" then
        3
      end

    respond_to do |format|
      if pre_sales.blank?
        format.json { head :ok }
      else
        if params[:type] != "credit" || pre_sales[0].customer.sale_approved?(pre_sales[0].customer.get_debiting + pre_sales.sum(:total))
          pre_sales.update_all(sale_type: type)
          format.json { head :ok }
        else
          pre_sales[0].errors.add(:base, "El cliente ya no tiene crédito disponible")
          format.json { render json: pre_sales[0].errors.values, status: :unprocessable_entity }
        end
      end
    end
  end

  private
  # Use callbacks to share common setup or constraints between actions.
  def set_pre_sale
    @pre_sale = PreSale.find(params[:id])
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def pre_sale_params
    params.require(:pre_sale).permit(:customer_id, :user_id, :open_cash_register_id, :sale_type, :product_id, :quantity, :amount, :tax, :discount, :total, :barcode, :haggle)
  end

  def has_enough_stock?(pre_sale)
    same_product_quantity = 0
    PreSale.where(user_id: current_user.id, product_id: pre_sale.product_id).each do |pre|
      same_product_quantity += pre.quantity
    end

    availableProduct = AvailableProduct.find_by(pointsale_id: current_user.pointsale_id, product_id: pre_sale.product_id)

    if availableProduct.stock >= (same_product_quantity + pre_sale.quantity)
      return true
    else
      return false
    end
  end
end
