class TransfersController < ApplicationController
  ##--- Abilities
  load_and_authorize_resource

  ##--- Breadcrum_rails
  add_breadcrumb I18n.t("breadcrumbs." + controller_name), :transfers_path
  add_breadcrumb "Nuevo traspaso", :new_transfer_path, only: :new
  add_breadcrumb "Detalle del traspaso", :transfer_path, only: :show
  add_breadcrumb "Editar traspaso", :edit_transfer_path, only: :edit
  add_breadcrumb "Verificar traspaso", :verify_transfer_path, only: :verify_transfer

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

  # GET /transfers
  # GET /transfers.json
  def index
    if current_user.usertype == 'A'
      @transfers = Transfer.all.includes(:user, :received_by).order('id DESC, transfer_date DESC')
    elsif current_user.usertype == 'G' || current_user.usertype == 'C'
      @received = Transfer.includes(:user, :received_by).where(destiny_id: current_user.pointsale_id, destiny_is_pointsale: 1).order('id DESC, transfer_date DESC')
      @sent = Transfer.includes(:user, :received_by).where(origin_id: current_user.pointsale_id, origin_is_pointsale: 1).order('id DESC, transfer_date DESC')
    elsif current_user.usertype == 'S'
      @received = Transfer.includes(:user, :received_by).where(destiny_id: current_user.warehouse_id, destiny_is_pointsale: 0).order('id DESC, transfer_date DESC')
      @sent = Transfer.includes(:user, :received_by).where(origin_id: current_user.warehouse_id, origin_is_pointsale: 0).order('id DESC, transfer_date DESC')
    end
  end

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

  # GET /transfers/new
  # rubocop:disable Style/ZeroLengthPredicate
  def new
    @transfer = Transfer.new
    @destiny_pointsales = Pointsale.activos.ignore_current(current_user.pointsale_id)
    @pre_transfers = PreTransfer.where(user_id: current_user.id)
    @disable_origin = false
    @disable_destiny = false
    @disabled_button = true
    if @pre_transfers.size > 0
      @origin_id = @pre_transfers[0].origin_is_pointsale == 1 ? "P-#{@pre_transfers[0].origin_id}" : "W-#{@pre_transfers[0].origin_id}"
      @destiny_id = @pre_transfers[0].destiny_is_pointsale == 1 ? "P-#{@pre_transfers[0].destiny_id}" : "W-#{@pre_transfers[0].destiny_id}"
      @disable_origin = true
      @disable_destiny = true
      @disabled_button = false
    end
    if current_user.usertype == "G" || current_user.usertype == "C"
      @origin_id = "P-#{current_user.pointsale_id}"
      @disable_origin = true
    elsif current_user.usertype == "S"
      @origin_id = "W-#{current_user.warehouse_id}"
      @disable_origin = true
    end
  end
  # rubocop:enble Style/ZeroLengthPredicate

  # GET /transfers/1/edit
  def edit; end

  # POST /transfers
  # POST /transfers.json
  def create
    @transfer = Transfer.new(transfer_params)
    pre_transfers = PreTransfer.where(user_id: current_user.id)
    @transfer.user_id = current_user.id
    @transfer.status = :pending
    @transfer.origin_is_pointsale = params[:transfer][:origin_id].first == 'P' ? 1 : 0
    @transfer.destiny_is_pointsale = params[:transfer][:destiny_id].first == 'P' ? 1 : 0
    @transfer.origin_id = params[:transfer][:origin_id][2, params[:transfer][:origin_id].length]
    @transfer.destiny_id = params[:transfer][:destiny_id][2, params[:transfer][:destiny_id].length]

    respond_to do |format|
      @transfer.audit_comment = "Traspaso de #{@transfer.origin_is_pointsale? ? Pointsale.find(@transfer.origin_id).name : Warehouse.find(@transfer.origin_id).name} a #{@transfer.destiny_is_pointsale? ? Pointsale.find(@transfer.destiny_id).name : Warehouse.find(@transfer.destiny_id).name} creado."
      if @transfer.save
        pre_transfers.each do |pre|
          detail = TransferDetail.new
          detail.transfer_id = @transfer.id
          detail.product_id = pre.product_id
          detail.quantity = pre.quantity
          detail.adjustment = pre.quantity
          detail.status = "pending"
          @transfer.transfer_details << detail
          pre.destroy
        end

        message = "Traspaso creado al " + (@transfer.destiny_is_pointsale == 1 ? "punto de venta #{Pointsale.find(@transfer.destiny_id).name}" : "almacén #{Warehouse.find(@transfer.destiny_id).name}")
        format.html { redirect_to transfers_path, success: message }
        format.json { render :show, status: :created, location: @transfer }
      else
        format.html { render :new }
        format.json { render json: @transfer.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /transfers/1
  # PATCH/PUT /transfers/1.json
  def update
    respond_to do |format|
      if @transfer.update(transfer_params)
        format.html { redirect_to @transfer, notice: 'Transfer was successfully updated.' }
        format.json { render :show, status: :ok, location: @transfer }
      else
        format.html { render :edit }
        format.json { render json: @transfer.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /transfers/1
  # DELETE /transfers/1.json
  def destroy
    @transfer.audit_comment = "Traspaso de #{@transfer.origin_is_pointsale? ? Pointsale.find(@transfer.origin_id).name : Warehouse.find(@transfer.origin_id).name} a #{@transfer.destiny_is_pointsale? ? Pointsale.find(@transfer.destiny_id).name : Warehouse.find(@transfer.destiny_id).name} eliminado."
    @transfer.destroy
    respond_to do |format|
      format.html { redirect_to transfers_url, notice: 'Transfer was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  def verify_transfer
    @transfer = Transfer.find(params[:transfer_id])
  end

  # para guardar la cantidad recibida por producto en el traspaso
  def detail_adjustment
    respond_to do |format|
      @transfer = Transfer.find(params[:transfer_id])
      @transfer.transfer_details.each do |detail|
        # rubocop:disable Style/Next
        if detail.id == params[:detail_id].to_i
          detail.adjustment = params[:transfer_details][:adjustment].to_i
          if detail.adjustment > detail.quantity
            detail.has_looses = 0
            detail.has_surplus = 1
          elsif detail.adjustment < detail.quantity
            detail.has_looses = 1
            detail.has_surplus = 0
          end

          if detail.save
            format.json { head :ok }
          end
        end
        # rubocop:enable Style/Next
      end
    end
  end

  # rubocop:disable Metrics/BlockLength
  def accept_transfer
    respond_to do |format|
      @transfer = Transfer.find(params[:transfer_id])
      @transfer.observations = params[:transfer][:observations]
      @transfer.received_by_id = current_user.id
      @transfer.status = :received
      @transfer.reception_date = Date.today
      @transfer.audit_comment = "Se dio entrada a traspaso de #{@transfer.origin_is_pointsale? ? Pointsale.find(@transfer.origin_id).name : Warehouse.find(@transfer.origin_id).name} a #{@transfer.destiny_is_pointsale? ? Pointsale.find(@transfer.destiny_id).name : Warehouse.find(@transfer.destiny_id).name}"
      @transfer.save
      @transfer.transfer_details.each do |detail|
        if @transfer.destiny_is_pointsale == 1
          stock_product = AvailableProduct.find_by(product_id: detail.product_id, pointsale_id: @transfer.destiny_id)
          if stock_product.present?
            stock_product.stock = 0 if stock_product.stock.blank?
            stock_product.stock += detail.adjustment
          else
            stock_product = AvailableProduct.new
            stock_product.product_id = detail.product_id
            stock_product.pointsale_id = @transfer.destiny_id
            stock_product.stock = detail.adjustment
          end
        else
          # actualizar stock del producto cuando es para almacen
          stock_product = WarehouseStock.find_by(product_id: detail.product_id, warehouse_id: @transfer.destiny_id)
          if stock_product.present?
            stock_product.stock = 0 if stock_product.stock.blank?
            stock_product.stock += detail.adjustment
          else
            stock_product = WarehouseStock.new
            stock_product.product_id = detail.product_id
            stock_product.warehouse_id = @transfer.destiny_id
            stock_product.stock = detail.adjustment
          end
        end
        stock_product.save

        # guardar en bitacora de inventario
        move = InventoriesMove.new
        move.product_id = detail.product_id
        move.quantity = detail.adjustment
        move.transfer_id = @transfer.id
        move.move_type = "incoming"
        move.reason = "transfer"
        move.save
      end
      format.js { flash[:success] = "Traspaso realizado correctamente." }
    end
  end
  # rubocop:enable Metrics/BlockLength

  # rubocop:disable Style/ConditionalAssignment
  def print_receipt
    respond_to do |format|
      @transfer = Transfer.find(params[:transfer_id])
      origin = @transfer.origin_is_pointsale == 1 ? Pointsale.find(@transfer.origin_id).name : Warehouse.find(@transfer.origin_id).name
      destiny = @transfer.destiny_is_pointsale == 1 ? Pointsale.find(@transfer.destiny_id).name : Warehouse.find(@transfer.destiny_id).name
      with_looses = @transfer.transfer_details.where(has_looses: 1).count
      with_surplus = @transfer.transfer_details.where(has_surplus: 1).count
      if with_looses > 0 && with_surplus.zero?
        reception_status = 'CON PERDIDAS'
      elsif with_surplus > 0 && with_looses.zero?
        reception_status = 'CON EXCEDENTE'
      elsif with_surplus > 0 && with_looses > 0
        reception_status = 'CON INCONSISTENCIAS'
      else
        reception_status = 'TRASPASO COMPLETO'
      end

      format.pdf do
        render pdf: "traspaso_#{@transfer.id}", template: "transfers/receipt.pdf.erb", layout: 'receipt.html.erb', locals: { transfer: @transfer, reception_status: reception_status, origin: origin, destiny: destiny }, show_as_html: params.key?('debug'), page_width: '80mm', page_height: '300mm'
      end
    end
  end
  # rubocop:enable Style/ConditionalAssignment

  private

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

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

  # Never trust parameters from the scary internet, only allow the white list through.
  def transfer_params
    params.require(:transfer).permit(:origin_id, :destiny_id, :transfer_date, :user_id, :status, :received_by_id, :observations, transfer_details_attributes: [:transfer_id, :product_id, :quantity, :status, :adjustment, :reception_date])
  end
end
