class BoardShippingBoxesController < AdminBaseController
  before_action :set_shipping_box, only: [:show, :inner_scan, :add_product, :remove_product, :edit, :update, :destroy, :shipping, :deliver]

  # GET /shipping_boxes
  # GET /shipping_boxes.json
  def index
    if not current_user.allowed?(:view_shipping_boxes)
      redirect_to "/admin", alert: "你没有权限进入此页面!" and return
    end


    @week_device_tested_stats = DataOverview.where(item: "device_daily_test_stats").order("created_at DESC").page(params[:page]).per(7)

    if current_user.role&.name&.start_with?("工厂")
      @q = ShippingBox.includes(:client).where(supplier: current_user.company).ransack(params[:q])
    else
      @q = ShippingBox.includes(:client).ransack(params[:q])
    end

    @q.sorts = "id DESC" if @q.sorts.empty?
    @shipping_boxes = @q.result.page(params[:page])
  end

  # GET /shipping_boxes/1
  # GET /shipping_boxes/1.json
  def show
    @shipping_box_item = ShippingBoxItem.new(shipping_box_id: @shipping_box.id)
    @shipping_box_items = @shipping_box.shipping_box_items
  end

  # 装箱
  # POST /shipping_boxes/1/add_product
  def add_product
    if params[:qrcode].blank?
      @error_message = "无效输入!"
      return
    end

    @product_sn = params[:qrcode].strip
    @board_product = Hardware.where(sn: @product_sn).first
    @shipping_box_item = ShippingBoxItem.where(status: 'initial').where(product_sn: @product_sn).first

    if !@shipping_box.initial_status?
      @error_message = @error_message + "<br/>箱子不是待发货状态!"
      return
    end

    if @board_product.nil?
      @error_message = "产品 (SN: #{@product_sn}) 没有测试!"
      return
    end

    if @shipping_box_item.present?
      @error_message = "此产品 (SN: #{@shipping_box_item.product_sn}) 已经在#{@shipping_box_item.shipping_box_id}箱中了!"
      return
    end

    @product = Product.where(sn: @product_sn).first
    if @product.blank?
      @product = Product.new(sn: @product_sn)
      @product.materiel_id = @shipping_box.materiel&.id
      @product.location = "Shanghai Factory"
      @product.lot_no = @shipping_box.lot_no
      @product.status = 'initial'
    else
      if @product.status == 'sent' || @product.status == 'tofix' || @product.status == 'dead'
        @error_message = "此产品 (SN: #{@shipping_box_item.product_sn}) 状态是#{product.status_name}，不能发货!"
        return
      elsif @product.status == 'fixed' && @product.location == 'Shanghai Novotech'
        @error_message = "此产品 (SN: #{@shipping_box_item.product_sn}) 在新技修复, 不能发货!"
        return
      end
    end

    @shipping_box_item = ShippingBoxItem.new(shipping_box_id: @shipping_box.id, product_sn: @product_sn, lot_no: @shipping_box.lot_no)
    @shipping_box_item.created_by = current_user.true_name
    @shipping_box_item.product = @product
    @shipping_box_item.status = 'initial'
    @shipping_box_item.location = "Shanghai Factory"
    if @product.status == 'refund'
      @shipping_box_item.remark = "退货产品重发货"
    end

    ShippingBoxItem.transaction do
      @shipping_box_item.save!
      @product.save!
    end
    redirect_to board_shipping_box_path(@shipping_box), notice: "产品已装箱" and return
  rescue ActiveRecord::RecordInvalid
    @errors = @shipping_box.errors.full_messages + @product.errors.full_messages + @shipping_box_item.errors.full_messages
    redirect_to board_shipping_box_path(@shipping_box), warning: "#{@errors.join(";")}"
  end

  # DELETE /shipping_boxes/1/remove_product
  def remove_product
    if !@shipping_box.initial_status?
      @error_message = "箱子不是未发货状态，无法操作"
      return
    end
    @shipping_box_item = ShippingBoxItem.where(shipping_box_id: @shipping_box.id, id: params[:box_item_id]).first
    if @shipping_box_item.blank?
      @error_message = "没有找到相关联的装箱产品"
      return
    end
    @shipping_box_item.destroy
    redirect_to board_shipping_box_path(@shipping_box), notice: "操作成功"
  end

  # GET /shipping_boxes/new
  def new
    @shipping_box = ShippingBox.new
    @shipping_box.lot_no = ShippingBox.generate_lot_no("shnt")
  end

  # GET /shipping_boxes/1/edit
  def edit
  end

  # POST /shipping_boxes
  # POST /shipping_boxes.json
  def create
    @shipping_box = ShippingBox.where(po: shipping_box_params[:po], lot_no: shipping_box_params[:lot_no], box_id: shipping_box_params[:box_id]).first
    if @shipping_box.present?
      redirect_to @shipping_box and return
    end

    @shipping_box = ShippingBox.new(shipping_box_params)
    @materiel = Materiel.where(sn: @shipping_box.part_no).first
    @order = Order.where(sn: @shipping_box.po).first
    if @materiel.blank?
      @shipping_box.errors.add(:base, "物料编码没有找到!")
    end

    if @order.blank?
      @shipping_box.errors.add(:base, "订单编号没有找到!")
    end

    @shipping_box.client_id = @order&.client_id

    respond_to do |format|
      if @shipping_box.save
        format.html { redirect_to board_shipping_box_path(@shipping_box), notice: 'Shipping box was successfully created.' }
      else
        format.html { render action: :new }
        format.js
      end
    end
  end

  # PATCH/PUT /shipping_boxes/1
  # PATCH/PUT /shipping_boxes/1.json
  def update
    return
    respond_to do |format|
      if @shipping_box.update(shipping_box_params)
        format.html { redirect_to board_shipping_box_path(@shipping_box), notice: 'Shipping box was successfully updated.' }
        format.json { render :show, status: :ok, location: @shipping_box }
      else
        format.html { render :edit }
        format.json { render json: @shipping_box.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /shipping_boxes/1
  # DELETE /shipping_boxes/1.json
  def destroy
    if not @shipping_box.initial_status?
      @error_message = "未发货状态下才可操作!"
      return
    end
    ShippingBox.transaction do
      @shipping_box.shipping_box_items.destroy_all
      @shipping_box.destroy
    end
    redirect_to board_shipping_boxes_url, notice: 'Shipping box was successfully destroyed.' and return
  end

  # POST /shipping_boxes/prepare_shipping
  def prepare_shipping
    @errors = []
    File.open("/tmp/qrcode_scan.txt", "a") do |f|
      f.puts "#{Time.now} : prepare_shipping:#{params[:qrcode]}"
    end
    if params[:qrcode].blank?
      @errors.append("Params error!")
      return
    end

    @info = params[:qrcode].split(",").collect { |word| word.strip }
    if @info.size != 5
      @errors.append("箱标签格式无效 !")
      return
    end
    if @info.any? { |item| item.blank? }
      @errors.append("箱标签数据无效 !")
      return
    end

    @order_number = @info[0]
    @materiel_number = @info[1]
    @lot_number = @info[2]
    @qty_number = @info[3].to_i
    @box_number = @info[4]

    @shipping_box = ShippingBox.where(po: @order_number, lot_no: @lot_number, part_no: @materiel_number, box_id: @box_number).first
    @order = Order.where(sn: @order_number).first
    @materiel = Materiel.where(sn: @materiel_number).first

    if @shipping_box.present? && @shipping_box.initial_status? && @order.present? && @materiel.present?
      redirect_to shipping_board_shipping_box_path(@shipping_box)
    end
  end

  # GET /shipping_boxes/1/shipping
  def shipping
    @shipping_box_item = ShippingBoxItem.new(shipping_box_id: @shipping_box.id)
    @shipping_box_items = @shipping_box.shipping_box_items
  end

  # POST /shipping_boxes/1/deliver
  def deliver
    File.open("/tmp/qrcode_scan.txt", "a") do |f|
      f.puts "#{Time.now} : #{current_user.true_name} deliver:#{params[:qrcode]}"
    end

    @errors = []

    @info = params[:qrcode].split(",").collect { |word| word.strip }
    if @info.size != 5
      @errors << "箱标签格式无效 ! 数据:#{@info.inspect}"
      return
    end
    if @info.any? { |item| item.blank? }
      @errors << "箱标签数据无效 ! 数据:#{@info.inspect}"
    end

    @order_number = @info[0]
    @materiel_number = @info[1]
    @lot_number = @info[2]
    @qty_number = @info[3].to_i
    @box_number = @info[4]
    @scan_shipping_box = ShippingBox.where(po: @order_number, lot_no: @lot_number, part_no: @materiel_number, box_id: @box_number).first
    if @scan_shipping_box.blank? || @scan_shipping_box.id != @shipping_box.id
      @errors << "扫描的发货箱与实际的发货箱不一致!"
      return
    end

    if @shipping_box.sent_status?
      @shipping_box.errors.add(:base, "发货箱之前已经发货, 发货时间 #{@shipping_box.shipping_at&.to_formatted_s(:work)}")
      @errors = @shipping_box.errors.full_messages
      return
    end

    @shipping_box_items = @shipping_box.shipping_box_items
    if @materiel_number != "M619R0022HL-A" && @materiel_number != "M624R0008HL-A"
      if @shipping_box_items.size == 0
        @shipping_box.errors.add(:base, "箱中还没有装入产品!")
        @errors = @shipping_box.errors.full_messages
        return
      end
    end

    ShippingBox.transaction do
      @shipping_box.status = 'sent'
      @shipping_box.shipping_at = Time.now
      @shipping_box_items.each do |item|
        item.status = 'sent'
        item.location = 'Ascleway'
        item.done_at = Time.now
        item.done_by = current_user.true_name
        product = Product.where(sn: item.product_sn).first
        if product.blank?
          @shipping_box.errors.add(:base, "没有发现关联的产品!")
          @errors << invalid.record.errors.full_messages
          raise ActiveRecord::Rollback, "Product not found!"
        else
          product.status = 'sent'
          product.location = 'ascleway'
          product.save!
          item.save!
        end
      end
      @shipping_box.save!
      redirect_to board_shipping_boxes_path, notice: "发货操作成功!" and return
    end
  rescue ActiveRecord::RecordInvalid => invalid
    @errors << invalid.record.errors.full_messages
  end

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

    # Only allow a list of trusted parameters through.
    def shipping_box_params
      params.require(:shipping_box).permit(:part_no, :lot_no, :qty, :box_id, :po)
    end
end
