module Comee
  module Core
    class QuotationRequestService
      def create_request_with_items(params)
        request = nil
        QuotationRequest.transaction do
          request = QuotationRequest.create!(
            client_id: params[:client_id],
            status: QuotationRequest.statuses[:draft],
            order_number: params[:order_number],
            order_date: params[:order_date],
            delivery_address: params[:delivery_address],
            invoice_address: params[:invoice_address]
          )
          items = params[:items]
          items.each do |item|
            item[:price] = 0
            item[:quotation_request_id] = request.id
            item[:discount] = 0
          end
          QuotationRequestItem.insert_all!(items)
        end
        request
      rescue StandardError
        raise
      end

      def submit(id)
        rfq = QuotationRequest.find(id)

        raise(StandardError, "RFQ should be in draft state.") if QuotationRequest.statuses[rfq.status] != QuotationRequest.statuses[:draft]

        raise(StandardError, "RFQ does not have any items.") if rfq.quotation_request_items.count.zero?

        raise(StandardError, "RFQ contains only canceled items.") if rfq.quotation_request_items.all?(&:canceled?)

        QuotationRequest.transaction do
          product_ids = rfq.quotation_request_items.map(&:product_id)
          prices = MasterPrice.where(product_id: product_ids).each_with_object({}) do |price, res|
            res[price.product_id] = [price.selling_price, price.valid_from, price.valid_to]
          end
          items = rfq.quotation_request_items.each_with_object({}) do |item, res|
            price = prices[item.product_id]
            res[item.id] = {price: price[0], valid_from: price[1], valid_to: price[2]} if price
          end
          QuotationRequestItem.update!(items.keys, items.values)
          rfq.status = QuotationRequest.statuses[:submitted]
          rfq.save!
        end
        rfq
      end

      def submit_for_confirmation(id)
        rfq = QuotationRequest.find(id)
        if QuotationRequest.statuses[rfq.status] != QuotationRequest.statuses[:submitted]
          raise(StandardError, "RFQ should be in submitted state.")
        end

        rfq.status = QuotationRequest.statuses[:awaiting_confirmation]
        rfq.save!
        rfq
      end

      def confirm(id)
        rfq = QuotationRequest.find(id)
        if QuotationRequest.statuses[rfq.status] != QuotationRequest.statuses[:awaiting_confirmation]
          raise(StandardError, "RFQ should be in awaiting_confirmation state.")
        end

        data = rfq.quotation_request_items.each_with_object([]) do |item, res|
          res << {
            client_id: rfq.client_id,
            product_id: item.product_id,
            unit_id: item.unit_id,
            price: item.price,
            discount: 0,
            valid_from: item.valid_from,
            valid_to: item.valid_to,
            status: ClientPrice.statuses[:current]
          }
        end

        ClientPrice.transaction do
          ClientPrice.insert_all!(data)
          rfq.status = QuotationRequest.statuses[:confirmed]
          rfq.save!
        end
        rfq
      end

      def convert_to_order(id)
        rfq = QuotationRequest.find(id)
        if QuotationRequest.statuses[rfq.status] != QuotationRequest.statuses[:confirmed]
          raise(StandardError, "RFQ should be in confirmed state for conversion to order.")
        end

        if rfq.quotation_request_items.any? { |item| item.customer_item_no.nil? }
          raise(StandardError, "All RFQ items should have customer item number set.")
        end

        order = nil
        CustomerOrder.transaction do
          order = CustomerOrder.create!(
            order_number: rfq.order_number,
            order_date: Date.current,
            client_id: rfq.client_id,
            order_terms: "",
            delivery_address: rfq.delivery_address,
            invoice_address: rfq.invoice_address,
            status: CustomerOrder.statuses[:draft]
          )

          items = rfq.quotation_request_items.each_with_object([]) do |item, res|
            res << {
              customer_order_id: order.id,
              product_id: item.product_id,
              unit_id: item.unit_id,
              customer_item_no: item.customer_item_no,
              quantity: item.quantity,
              price: item.price,
              delivery_date: item.expected_delivery_date,
              canceled: false
            }
          end

          CustomerOrderItem.insert_all!(items)
          rfq.status = QuotationRequest.statuses[:converted]
          rfq.save!
        end

        order
      end
    end
  end
end