class PurchasesController < ApplicationController
  ##--- Abilities
  load_and_authorize_resource

  ##--- Breadcrum_rails
  add_breadcrumb I18n.t("breadcrumbs." + controller_name), :purchases_path
  add_breadcrumb "Nueva " + I18n.t("breadcrumbs." + controller_name).singularize, :new_purchase_path, only: :new
  add_breadcrumb "Detalle de la " + I18n.t("breadcrumbs." + controller_name).singularize, :purchase_path, only: :show
  add_breadcrumb "Editar " + I18n.t("breadcrumbs." + controller_name).singularize, :edit_purchase_path, only: :edit

  before_action :set_purchase, only: [:show, :edit, :update, :destroy]
  before_action :get_filters, only: [:index, :show, :edit, :new]

  # GET /purchases
  # GET /purchases.json
  def index
    @purchases =
      if current_user.usertype == "A" || current_user.usertype == "SS"
        Purchase.all.includes(:supplier, :pointsale, :warehouse, :user).order("created_at DESC")
      else
        Purchase.includes(:supplier, :user).where(pointsale_id: current_user.pointsale_id).order('created_at desc')
      end
  end

  # GET /purchases/1
  # GET /purchases/1.json
  def show; end

  # GET /purchases/new
  def new
    @disable_supplier = false
    @disable_pointsale = false
    @disable_warehouse = false
    @disable_is_in_dollars = false
    @disable_destiny = false
    @disabled_button = true
    @destiny = 'warehouse'
    @purchase = Purchase.new
    @purchase.purchase_details.new
    @pre_purchases = PrePurchase.where(user_id: current_user.id)
    unless @pre_purchases.empty?
      @purchase.supplier_id = @pre_purchases[0].supplier_id
      @purchase.pointsale_id = @pre_purchases[0].pointsale_id
      @purchase.warehouse_id = @pre_purchases[0].warehouse_id
      @destiny = @purchase.pointsale_id.present? ? 'pointsale' : 'warehouse'
      @purchase.exchange = @pre_purchases[0].exchange if @pre_purchases[0].exchange.present?
      @purchase.is_in_dollars = true if @pre_purchases[0].exchange.present?
      @disable_supplier = true
      @disable_pointsale = true
      @disable_warehouse = true
      @disable_is_in_dollars = true
      @disable_destiny = true
      @disabled_button = false
    end
    if current_user.usertype == 'G'
      @destiny = 'pointsale'
      @purchase.pointsale_id = current_user.pointsale_id
      @disable_pointsale = true
      @disable_warehouse = true
      @disable_destiny = true
    end
  end

  # POST /purchases
  # POST /purchases.json
  def create
    @purchase = Purchase.new(purchase_params)
    @purchase.user_id = current_user.id
    @purchase.status = :notpaid
    @pre_purchases = PrePurchase.where(user_id: current_user.id)

    respond_to do |format|
      message = "Compra #{@purchase.purchase_code} por $ #{@purchase.total} #{@purchase.exchange.present? ? "USD" : "MXN"} creada."
      @purchase.audit_comment = message
      if @purchase.save
        @pre_purchases.each do |pre_purchase|
          # agregar detalles de la compra
          create_purchase_details(@purchase, pre_purchase)
          pre_purchase.destroy
        end
        format.html { redirect_to purchases_url, success: message }
      else
        format.html { render :new }
        format.json { render json: @purchase.errors.values, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /purchases/1
  # DELETE /purchases/1.json
  def destroy
    respond_to do |format|
      message = "Compra #{@purchase.purchase_code} cancelada."
      @purchase.audit_comment = message
      if @purchase.update_attributes(status: :cancelled)
        # checa si hay pagos de esta compra
        CashRegistersMove.where(purchase_id: @purchase.id).each do |move|
          new_cash_move = move.dup
          new_cash_move.move_type = :ingreso
          new_cash_move.save
        end
        @purchase.purchase_details.each do |detail|
          destroy_purchase_details(@purchase, detail)
        end
        format.html { redirect_to purchases_url, warning: message }
        format.json { head :no_content }
      else
        format.html { render :edit }
        format.json { render json: @purchase.errors, status: :unprocessable_entity }
      end
    end
  end

  def find_purchases_by_date
    start_date = DateTime.parse(params[:begin_date])
    end_date = DateTime.parse(params[:end_date])
    @purchases =
      if current_user.usertype == "A" || current_user.usertype == "SS"
        Purchase.includes(:supplier, :pointsale, :warehouse, :user).where(purchase_date: start_date..end_date).order('purchase_date desc')
      else
        Purchase.includes(:supplier, :user).where(pointsale_id: current_user.pointsale_id, created_at: start_date..end_date).order('purchase_date desc')
      end
    respond_to do |format|
      format.js
    end
  end

  private

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

  def get_filters
    @current_page =
      if params[:current_page].blank?
        1
      else
        params[:current_page]
      end
    @filter = params[:filter]
  end

  def create_purchase_details(purchase, pre_purchase)
    detail = PurchaseDetail.new(product_id: pre_purchase.product_id, quantity: pre_purchase.quantity, amount: pre_purchase.total, price: pre_purchase.price_base, tax: pre_purchase.tax)
    purchase.purchase_details << detail
    # actualizar stock del producto cuando es para punto de venta
    if purchase.pointsale_id.present?
      stock_product = AvailableProduct.find_by(product_id: detail.product_id, pointsale_id: purchase.pointsale_id)
      if stock_product.nil?
        stock_product = AvailableProduct.create(product_id: detail.product_id, pointsale_id: purchase.pointsale_id, stock: detail.quantity)
      else
        stock_product = 0 if stock_product.stock.blank?
        stock_product.stock += detail.quantity
      end
    else
      # actualizar stock del producto cuando es para almacen
      stock_product = WarehouseStock.find_by(product_id: detail.product_id, warehouse_id: purchase.warehouse_id)
      if stock_product.nil?
        stock_product = WarehouseStock.create(product_id: detail.product_id, warehouse_id: purchase.warehouse_id, stock: detail.quantity)
      else
        stock_product = 0 if stock_product.stock.blank?
        stock_product.stock += detail.quantity
      end
    end
    stock_product.save

    # guardar en bitacora de inventario
    InventoriesMove.create(product_id: detail.product_id, purchase_id: purchase.id, quantity: detail.quantity, move_type: "incoming", reason: "purchase")
  end

  def destroy_purchase_details(purchase, purchase_detail)
    purchase_detail.update_attributes(status: :inactive)
    # busca y actualiza el stock de productos
    stock_product =
      if purchase.pointsale.present?
        AvailableProduct.find_by(product_id: purchase_detail.product_id, pointsale_id: purchase.pointsale_id)
      else
        WarehouseStock.find_by(product_id: purchase_detail.product_id, warehouse_id: purchase.warehouse_id)
      end
    # restarle al stock del producto
    stock = stock_product.stock - purchase_detail.quantity
    stock_product.update_attributes(stock: stock)

    # guardar en bitacora de inventario
    InventoriesMove.create(product_id: purchase_detail.product_id, purchase_id: purchase.id, quantity: purchase_detail.quantity, move_type: "outgoing", reason: "purchase_cancel")
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def purchase_params
    params.require(:purchase).permit(:supplier_id, :pointsale_id, :warehouse_id, :purchase_code, :amount, :tax, :total, :observations, :purchase_date, :is_in_dollars, :exchange)
  end
end
