class Transactions::SalesController < ApplicationController
  load_and_authorize_resource except: [:create]
  before_action :set_transactions_sale, only: [:show, :edit, :update, :destroy]
  before_action :check_user

  # GET /transactions/sales
  # GET /transactions/sales.json
  def index
    
    receipt_no = params[:receipt_no]
    # from       = params[:from]
    # to         = params[:to]
    from, to  = get_date_range_from_params
    @shift = ''
    if params[:shift_name].to_i != 0
            @shift = ShiftSale.find(params[:shift_name])
    end

    if receipt_no.nil? && from.nil? && to.nil?
      if @shift.blank?
        @sales = Sale.where("NOT sale_status='new'").order("sale_id desc")
      else 
        @sales = Sale.where("NOT sale_status='new' and shift_sale_id ='#{@shift.id}'").order("sale_id desc")
      end
        @sales = Kaminari.paginate_array(@sales).page(params[:page]).per(20)
    else
        sale = Sale.search(receipt_no,from,to,@shift)
        if sale.count > 0
           @sales = sale 
           @sales = Kaminari.paginate_array(@sales).page(params[:page]).per(20)
         else
           @sales = 0
         end    
    end
    @receipt_no = receipt_no
    @from       = from
    @to         = to

    if @shift.present?
      @shift_from = @shift.shift_started_at.nil? ? '-' : @shift.shift_started_at.utc.getlocal.strftime("%e %b %I:%M%p")
      @shift_to = @shift.shift_closed_at.nil? ? '-' : @shift.shift_closed_at.utc.getlocal.strftime("%e %b %I:%M%p")
      @shift_data = @shift
    end
    
    # if receipt_no.nil? && search_date.nil?
    #      @sales = Sale.where("NOT sale_status = 'void' " ).order("sale_id desc").limit(500) 
    #      @sales = Kaminari.paginate_array(@sales).page(params[:page]).per(50)
    # else
    #     if !search_date.blank? && receipt_no.blank?  
    #       sale = Sale.where("DATE_FORMAT(receipt_date,'%d-%m-%Y') = ? and NOT sale_status = 'void' ", search_date).order("sale_id desc").limit(500).page(params[:page])
    #     elsif !search_date.blank? && !receipt_no.blank? 
    #       sale = Sale.where("receipt_no LIKE ? or DATE_FORMAT(receipt_date,'%d-%m-%Y') = ? and NOT sale_status = 'void' ", "%#{receipt_no}%", search_date).order("sale_id desc").limit(500).page(params[:page])
    #     else  
    #       sale = Sale.where("receipt_no LIKE ? and NOT sale_status = 'void' ", receipt_no).order("sale_id desc").limit(500).page(params[:page]) 
    #     end  
    #     if sale.count > 0
    #       @sales = sale 
    #       @sales = Kaminari.paginate_array(@sales).page(params[:page]).per(50)
    #     else
    #       @sales = 0
    #     end
    # end

    @sale_audits = []
    @sale_item_audits = []
    if @sales != 0
      @sales.each do |sale|
        sale_audit = SaleAudit.where("(action = 'SALEPAYMENT' or action = 'SALEVOID') and sale_id = ? and remark IS NOT NULL",sale.sale_id)
        if !sale_audit.nil?
          sale_audit.each do |audit|
            @sale_audits.push({sale.sale_id => audit.remark})
          end
        end

        sale_item_audit = SaleAudit.where("(action LIKE '%ITEM%') and sale_id = ?",sale.sale_id)
        if !sale_item_audit.nil? && sale_item_audit.count > 0
          @sale_item_audits.push({sale.sale_id => sale_item_audit.count})
        end
      end
    end

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @sales }
    end

  end

  # GET /transactions/sales/1
  # GET /transactions/sales/1.json
  def show
   
    @sale = Sale.find(params[:id])

    @order_items = []
    @sale.sale_orders.each do |sale_order|
      order = Order.find(sale_order.order_id)
      #if (order.status == "new")
        @order_items = @order_items + order.order_items
      #end
    end

    @sale_receivables = SalePayment.where('sale_id = ?', @sale.id)
    @sale_audits = SaleAudit.where('sale_id = ?', @sale.id)

    #get customer amount
      @customer       = Customer.find(@sale.customer_id)
       @response       = Customer.get_membership_transactions(@customer)
    #end customer amount

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @sale }
    end
  end

  # GET /transactions/sales/new
  def new
    @transactions_sale = Sale.new
  end

  # GET /transactions/sales/1/edit
  def edit
  end

  # POST /transactions/sales
  # POST /transactions/sales.json
  def create
    @transactions_sale = Sale.new(transactions_sale_params)

    respond_to do |format|
      if @transactions_sale.save
        format.html { redirect_to @transactions_sale, notice: 'Sale was successfully created.' }
        format.json { render :show, status: :created, location: @transactions_sale }
      else
        format.html { render :new }
        format.json { render json: @transactions_sale.errors, status: :unprocessable_entity }
      end
    end
  end

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

  # DELETE /transactions/sales/1
  # DELETE /transactions/sales/1.json
  def destroy
    @transactions_sale.destroy
    respond_to do |format|
      format.html { redirect_to transactions_sales_url, notice: 'Sale was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  # date range
  PERIOD = {
    "today" => 0,
    "yesterday" => 1,
    "this_week" => 2,
    "last_week" => 3,
    "last_7" => 4,
    "this_month" => 5,
    "last_month" => 6,
    "last_30" => 7,
    "this_year" => 8,
    "last_year" => 9
  }

  def get_date_range_from_params
      period_type = params[:period_type]
      period = params[:period]
      from = params[:from]
      to = params[:to]   
      day_ref = Time.now.utc.getlocal

        if from.present? && to.present?
            f_date = DateTime.parse(from)
            t_date = DateTime.parse(to)
            f_time = Time.mktime(f_date.year,f_date.month,f_date.day,f_date.hour,f_date.min,f_date.sec)
            t_time = Time.mktime(t_date.year,t_date.month,t_date.day,t_date.hour,t_date.min,t_date.sec)
            from   = f_time.beginning_of_day.utc.getlocal
            to     = t_time.end_of_day.utc.getlocal 
        else 
            case period.to_i
              when PERIOD["today"]
                from = day_ref.beginning_of_day.utc
                to = day_ref.end_of_day.utc

              when PERIOD["yesterday"]
                from = (day_ref - 1.day).beginning_of_day.utc
                to = (day_ref - 1.day).end_of_day.utc

              when PERIOD["this_week"]
                from = Time.now.beginning_of_week.utc
                to = Time.now.utc
              when PERIOD["last_week"]
                from = (day_ref - 7.day).beginning_of_week.utc
                to = (day_ref - 7.day).end_of_week.utc
              when PERIOD["last_7"]
                from = (day_ref - 7.day).utc
                to = Time.now.utc
              when PERIOD["this_month"]
                from = Time.now.beginning_of_month.utc
                to = Time.now.utc
              when PERIOD["last_month"]
                from = (day_ref - 1.month).beginning_of_month.utc
                to = (day_ref - 1.month).end_of_month.utc
              when PERIOD["last_30"]
                from = (day_ref - 30.day).utc
                to = Time.now.utc
              when PERIOD["this_year"]
                from = Time.now.beginning_of_year.utc
                to = Time.now.utc
              when PERIOD["last_year"]
                from = (day_ref - 1.year).beginning_of_year.utc
                to = (day_ref - 1.year).end_of_year.utc
            end  
        end

      return from, to 
  end

  def check_user
    if current_user.nil?
      redirect_to root_path
    end
  end

  def overall_void
    sale_id = params[:sale_id]
    remark  = params[:remark]
    order_source = params[:type] #tax profile source
    access_code = params[:access_code]
    if Sale.exists?(sale_id)
      sale = Sale.find_by_sale_id(sale_id)

      if sale.discount_type == "member_discount"
        sale.update_attributes(total_discount: 0)
        sale.compute_by_sale_items(sale_id, sale.sale_items,0,order_source)
      end

      # update count for shift sale
      if(sale.sale_status == "completed")
        if sale.shift_sale_id != nil
          shift = ShiftSale.find(sale.shift_sale_id)
          shift.calculate(sale_id, "void")
        end
      else
        # void before sale payment complete
        if sale.shift_sale_id != nil
          shift = ShiftSale.find(sale.shift_sale_id)
          shift.total_void = shift.total_void + sale.grand_total
          shift.save
        end
      end
            
      sale.rounding_adjustment = 0.0
      sale.payment_status = 'void'
      sale.sale_status = 'void'
      sale.save

      # No Need
      # bookings = sale.bookings
      # bookings.each do |booking|
      #   orders = booking.orders
      #   orders.each do |order|
      #     # order.status = 'void'
      #   end
      # end

      if sale.bookings[0].dining_facility_id.to_i > 0
        table_avaliable = true
        table_count = 0
        table = sale.bookings[0].dining_facility
        table.bookings.each do |booking|
          if booking.booking_status != 'moved'
            if booking.sale_id
              if booking.sale.sale_status != 'completed' && booking.sale.sale_status != 'void' && booking.sale.sale_status != 'spoile' && booking.sale.sale_status != 'waste'
                table_avaliable = false
                table_count += 1
              else
                table_avaliable = true
              end
            else
              table_avaliable = false
              table_count += 1
            end
          end
        end

        if table_avaliable && table_count == 0
          table.status = 'available'
          table.save
        end
      else
        table = nil
      end

      # FOr Sale Audit 
      action_by = current_user.name
      if access_code != "null" && current_user.role == "cashier"
        action_by = Employee.find_by_emp_id(access_code).name
      end
      
      # remark = "Void Sale ID #{sale_id} | Receipt No #{sale.receipt_no} | Receipt No #{sale.receipt_no} | Table ->#{table.name}"
      sale_audit = SaleAudit.record_audit_for_edit(sale_id,sale.cashier_id, action_by,remark,"SALEVOID" )

      # For Print 

      member_info   = nil
      rebate_amount = nil
      current_balance = nil

      # For Cashier by Zone
      bookings = Booking.where("sale_id='#{sale_id}'")
      if bookings.count > 1 
        # for Multiple Booking
        if bookings[0].dining_facility_id.to_i>0
          table = DiningFacility.find(bookings[0].dining_facility_id)
        end
      end

      if bookings[0].dining_facility_id.to_i > 0
        cashier_zone     = CashierTerminalByZone.find_by_zone_id(table.zone_id)
        cashier_terminal = CashierTerminal.find(cashier_zone.cashier_terminal_id)
      else
        shift = ShiftSale.find(sale.shift_sale_id)
        cashier_terminal = CashierTerminal.find(shift.cashier_terminal_id)
      end
      

      # if ENV["SERVER_MODE"] != "cloud" #no print in cloud server
        unique_code = "ReceiptBillPdf"
        customer= Customer.find(sale.customer_id)
        
         #shop detail
        shop_details = Shop.find(1)
         # get member information
        rebate = MembershipSetting.find_by_rebate(1)
        if customer.membership_id != nil && rebate
          member_info = Customer.get_member_account(customer)
          rebate_amount  = Customer.get_membership_transactions(customer,sale.receipt_no)
          # current_balance = SaleAudit.paymal_search(sale_id)
          current_balance = 0
        end

        # get printer info
        print_settings=PrintSetting.find_by_unique_code(unique_code)
        # Calculate Food and Beverage Total
        item_price_by_accounts = SaleItem.calculate_price_by_accounts(sale.sale_items)
        discount_price_by_accounts = SaleItem.get_discount_price_by_accounts(sale.sale_items)

        printer = Printer::ReceiptPrinter.new(print_settings)                                    
        filename, sale_receipt_no, printer_name = printer.print_receipt_bill(print_settings,cashier_terminal,sale.sale_items,sale,customer.name, item_price_by_accounts, discount_price_by_accounts, member_info,rebate_amount,shop_details, "VOID",current_balance,nil)   
        result = { 
              :filepath => filename, 
              :printer_model => print_settings.brand_name, 
              :printer_url => print_settings.api_settings 
            }

        # Mobile Print
        render :json => result.to_json
      # end
      
      #end print

      # update complete order items in oqs
      SaleOrder.where("sale_id = '#{ sale_id }'").find_each do |sodr|        
        AssignedOrderItem.where("order_id = '#{ sodr.order_id }'").find_each do |aoi|
          aoi.delivery_status = 1
          aoi.save
        end
      end
    end
  end 

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

    # Never trust parameters from the scary internet, only allow the white list through.
    def transactions_sale_params
      params.require(:transactions_sale).permit(:cashier_id, :cashier_name, :requested_by, :requested_at, :receipt_no, :receipt_date, :customer_id, :payment_status, :sale_status, :total_amount, :total_discount, :total_tax, :tax_type, :grand_total, :rounding_adjustment, :amount_received, :amount_changed)
    end
end
