class CashRegistersMovesController < ApplicationController
  before_action :set_cash_registers_move, only: [:show, :edit, :update, :destroy]

  # GET /cash_registers_moves/new
  def new
    @cash_registers_move = CashRegistersMove.new

    if params[:sale].present?
      @sale = Sale.find(params[:sale])
      @credito = Credit.where(customer_id: @sale.customer_id, status: "0").sum(:rest)
      @cash_registers_move.open_cash_register_id = @sale.open_cash_register_id
    elsif params[:products_return].present?
      @products_return = ProductsReturn.find(params[:products_return])
    end

    @cash_id = PaymentMethod.find_by(isCash: 1).id

    if @sale.present?
      if @sale.saletype == 'reserved'
        if @sale.parcial?
          # esto quiere decir que la venta ya tiene un anticipo, se debe mostrar modal
          # para abonar al apartado o liquidarlo
          @payments = CashRegistersMove.where(sale_id: @sale.id, status: 1)
          render 'liquidate_reserved_sale'
        else
          # registrar apartado
          @min_quantity_reserve = ((@pos_config.reserve_sale_percent / 100) * @sale.total).round
          @cash_registers_move.quantity = @min_quantity_reserve
          render 'new_sale_reserve'
        end
      else
        # Nueva venta
        render 'new'
      end
    elsif @products_return.present?
      @open_cash_register_id = session[:open_cash_register_id]
      render 'products_return_payment'
    end
  end

  # POST /cash_registers_moves
  # POST /cash_registers_moves.json
  # rubocop:disable Metrics/BlockLength
  def create
    @cash_registers_move = CashRegistersMove.new(cash_registers_move_params)
    @sale = Sale.find(params[:cash_registers_move][:sale_id]) if params[:cash_registers_move][:sale_id].present?
    @purchase = Purchase.find(params[:cash_registers_move][:purchase_id]) if params[:cash_registers_move][:purchase_id].present?
    credit = Credit.find_by_sale_id(@sale.id) if params[:cash_registers_move][:sale_id].present?
    @products_return = ProductsReturn.find(params[:cash_registers_move][:products_return_id]) if params[:cash_registers_move][:products_return_id].present?

    respond_to do |format|
      if @sale.present?
        # calcular cambio cuando aplica.
        @cash_registers_move.calculate_quantities

        @cash_registers_move.move_type = :ingreso

        if @sale.cash?
          @sale.update_attributes(status: :paid)
          @cash_registers_move.concept = :sale
        elsif @sale.reserved?
          @cash_registers_move.status = :inactive
          @cash_registers_move.choose_concept_when_reserved
          @cash_registers_move.open_cash_register_id = session[:open_cash_register_id]
        end

        if credit.present?
          save_when_is_credit(credit)
          @cash_registers_move.open_cash_register_id = session[:open_cash_register_id]
        end

        message = "movimiento de efectivo por venta con folio #{@cash_registers_move.sale.sale_code}"
        @cash_registers_move.audit_comment = message
        if @cash_registers_move.save
          format.js { flash[:success] = message }
        else
          format.js
          format.json { render json: @cash_registers_move.errors, status: :unprocessable_entity }
        end
      elsif @purchase.present?
        @cash_registers_move.move_type = :egreso
        @cash_registers_move.concept = :purchase
        @cash_registers_move.status = :inactive

        message = "movimiento de efectivo por compra con folio #{@cash_registers_move.purchase.purchase_code}"
        @cash_registers_move.audit_comment = message

        if @cash_registers_move.save
          format.html { redirect_to purchases_path, success: 'Movimiento de efectivo realizado correctamente.' }
        else
          format.html { render :new }
          format.json { render json: @cash_registers_move.errors, status: :unprocessable_entity }
        end
      elsif @products_return.present?
        # calcular cambio cuando aplica.
        @cash_registers_move.calculate_quantities
        @cash_registers_move.move_type = :ingreso
        @cash_registers_move.concept = :products_return
        @cash_registers_move.sale_id = @cash_registers_move.products_return.sale_id
        @cash_registers_move.status = :inactive

        message = "movimiento de efectivo por devolución con folio #{@cash_registers_move.products_return.return_code}"
        @cash_registers_move.audit_comment = message
        if @cash_registers_move.save
          format.js { flash[:success] = message }
        else
          format.js
          format.json { render json: @cash_registers_move.errors, status: :unprocessable_entity }
        end
      end
    end
  end
  # rubocop:enable Metrics/BlockLength

  # DELETE /cash_registers_moves/1
  # DELETE /cash_registers_moves/1.json
  def destroy
    @cash_registers_move.destroy
    respond_to do |format|
      format.json { head :no_content }
      format.js { head :ok }
    end
  end

  def confirm_payments
    respond_to do |format|
      @sale = Sale.find(params[:sale_id]) if params[:sale_id].present?
      @products_return = ProductsReturn.find(params[:products_return_id]) if params[:products_return_id].present?

      if @sale.present?
        if CashRegistersMove.where(sale_id: @sale.id).update_all(status: 1)
          @sale.update_attributes(status: :paid)
          message = "Venta registrada correctamente."
        end
      elsif @products_return.present?
        CashRegistersMove.where(products_return_id: @products_return.id).update_all(status: 1)
        message = "Devolución registrada correctamente."
      end

      format.js { flash[:success] = message }
    end
  end

  # funcion que se manda llamar cuando se clickea en 'Abonar' al crear apartado
  def confirm_reserve
    respond_to do |format|
      @sale = Sale.find(params[:sale_id])
      if CashRegistersMove.where(sale_id: @sale.id).update_all(status: 1)
        @sale.update_attributes(status: :parcial)
        format.js { flash[:success] = "Apartado agregado al cliente #{@sale.customer.nick_name} correctamente." }
      end
    end
  end

  def add_payments_to_reserve
    respond_to do |format|
      @sale = Sale.find(params[:sale_id])
      @new_moves_array = Array.new
      @new_moves = CashRegistersMove.where(sale_id: @sale.id, status: 0)
      @new_moves.each do |move|
        @new_moves_array << move.id
      end
      if @new_moves.update_all(status: 1)
        # if @sale.reserve_debt == 0
        if @sale.reserve_debt <= 0
          @sale.update_attributes(status: :paid)
        end
        format.js { flash[:success] = "Abono al apartado #{@sale.sale_code} agregado correctamente." }
      end
    end
  end

  # rubocop:disable Metrics/BlockLength
  def delete_credit_payment
    respond_to do |format|
      payment = CreditPayment.find(params[:credit_payment_id])
      cashmoves = CashRegistersMove.where(credit_payment_id: payment.id)

      openregister = OpenCashRegister.find_by(id: cashmoves.first.open_cash_register_id)
      if openregister.open?
        payment.update_attributes(status: :cancelled)
        credit = Credit.find(params[:credit])
        sale = Sale.find(credit.sale_id)
        sum = payment.quantity + credit.rest
        if credit.total < sum
          credit.update_attributes(rest: credit.total)
          sale.update_attributes(status: :notpaid)
        else
          credit.update_attributes(rest: sum)
          if sale.total == credit.rest
            sale.update_attributes(status: :notpaid)
          end
        end
        cashmoves.each do |move|
          new_cash_move = move.dup
          new_cash_move.move_type = :egreso
          new_cash_move.save
        end
        format.html { redirect_to customer_sales_path(customer_id: payment.customer_id), notice: "Movimiento de efectivo realizado correctamente." }
        format.js { flash[:success] = "Movimiento de efectivo realizado correctamente." }
      else
        format.html { redirect_to customer_sales_path(customer_id: payment.customer_id), notice: "No se pudo realizar el movimiento." }
        format.js { flash[:success] = "NO se pudo realizar el movimiento." }
      end
    end
  end
  # rubocop:enable Metrics/BlockLength

  def add_quick_payment
    # type 1 es abono a credito, 2 es abono a apartado
    @type = params[:type].to_i
    if @type == 1
      debtors_ids = Credit.debtors
      @customers = Customer.find(debtors_ids.map { |m| m[0] })
    else
      @sales = Pointsale.find(current_user.pointsale_id).sales.where(saletype: 2, status: 3).select(:customer_id).distinct
      # rubocop:disable Style/SymbolProc
      @customers = Customer.find(@sales.map { |m| m.customer_id })
      # rubocop:enable Style/SymbolProc
    end
  end

  def create_quick_debt_payment
    @customer = Customer.find(params[:customer_id])
    @sale = @customer.sales.where('saletype = 0 and status != 1 and status != 2').order('date_sale DESC').last
    redirect_to new_cash_registers_move_path(sale: @sale, customer: @customer)
  end

  private

  # Use callbacks to share common setup or constraints between actions.
  def set_cash_registers_move
    @cash_registers_move = CashRegistersMove.find(params[:id])
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def cash_registers_move_params
    params.require(:cash_registers_move).permit(:payment_method_id, :quantity, :open_cash_register_id, :sale_id, :cardnumber, :ticket, :received, :change, :products_return_id)
  end

  def save_when_is_credit(credit)
    abono = @cash_registers_move.quantity
    abono_this_credit = abono >= credit.rest ? credit.rest : abono

    # por si abonan dinero de mas, checar cuanto debe de ser de esta venta, y separarlo.
    # @cash_registers_move.quantity = abono_this_credit
    @credit_payment = CreditPayment.new
    @credit_payment.credit_id = credit.id
    @credit_payment.customer_id = credit.customer_id
    @credit_payment.pointsale_id = credit.pointsale_id
    @credit_payment.status = :active
    @credit_payment.date_payment = Date.today
    @credit_payment.user_id = current_user.id
    # @credit_payment.quantity = abono_this_credit
    @credit_payment.quantity = abono_this_credit

    if @credit_payment.save
      @cash_registers_move.credit_payment_id = @credit_payment.id
      @cash_registers_move.concept = :credit_payment

      if abono >= credit.rest # si se paga mas del adeudo de este credito
        abono -= credit.rest

        credit.update_attributes(rest: 0)
        @sale.update_attributes(status: :paid)

        # rubocop:disable Style/WhileUntilDo
        while abono > 0 do
          nextcredit = Credit.where("customer_id = #{credit.customer_id} and rest > 0").order("sale_id ASC")
          # rubocop:disable Metrics/BlockNesting
          if nextcredit.first.present?
            if abono <= nextcredit.first.rest
              next_credit_payment = CreditPayment.create(customer_id: credit.customer_id, credit_id: nextcredit.first.id, pointsale_id: credit.pointsale_id, quantity: abono, status: 0, date_payment: Date.today, user_id: current_user.id)
              # next_credit_abono = @cash_registers_move.dup
              # next_credit_abono.quantity = abono
              # next_credit_abono.credit_payment_id = next_credit_payment.id
              # next_credit_abono.save
              nextcredit.first.update_attributes(rest: nextcredit.first.rest - abono)
              sale = Sale.find_by_id(nextcredit.first.sale_id)
              sale.update_attributes(status: :parcial)
              abono -= nextcredit.first.rest
            else
              abono -= nextcredit.first.rest
              nextcredit.first.update_attributes(rest: 0)
              sale = Sale.find_by_id(nextcredit.sale_id)
              sale.update_attributes(status: :paid)
            end
          else
            abono = 0 # si ya no hay deuda
          end
          # rubocop:enable Metrics/BlockNesting
        end
        # rubocop:enable Style/WhileUntilDo
      else
        @cash_registers_move.quantity = abono
        abono = credit.rest - abono
        credit.update_attributes(rest: abono)
        @sale.update_attributes(status: :parcial)
      end
    end
  end
end
