class Api::V1::LocationNetworksController < Api::V1::ApiController
  before_action :user_authentication_for_api
  before_action :set_location_network, only: [:show, :get_network_devices, :update, :destroy]

  api :GET, "/v1/location_networks/list_networks", "List Networks"
  # param :access_token, String, :desc => "User Access Token", :required => true
  param :network_name, String, :desc => "Network name"

  def list_networks
    network_name = params[:network_name]
    network_id = params[:network_id]
    @all_networks = @user.location_networks.page(params[:page] || 1).per(params[:per_page] || 100)
    current, total, per_page = @all_networks.current_page, @all_networks.total_pages, @all_networks.limit_value

    if network_name
      network = @user.organisation.location_networks.where(:network_name => network_name).first
    else
      network = @user.organisation.location_networks.where(:id => network_id).first
    end
    if network_name.present? || network_id.present?
      if network.present?
        render json: { data: network.json_build, status: 200 }
      else
        render json: { msg: "Requested Network not found check your Network", error_code: 1001}, status: 404
      end
    else
      render json: { data: { networks: @all_networks.map{|n| n.json_build}, meta: { current: current, previous: (current>1 ? (current-1) : nil), next: (current==total ? nil : (current+1)), per_page: per_page, pages: total, count: @all_networks.total_count } }, status: 200 }
    end
  end

  api :GET, "/v1/location_networks/list_network_timezone", "List Network Timezone"
  # param :access_token, String, :desc => "User Access Token", :required => true

  def list_network_timezone
    timezone = ActiveSupport::TimeZone.all.map(&:name).sort
    render json: { data: { timezone: timezone }, status: 200 }
  end

  api :POST, "/v1/location_networks", "Create Network"
  # param :access_token, String, :desc => "User Access Token", :required => true
  param :location_networks, Hash, :desc => "Param description for all fields" do  
    # param :mac_id, String, :desc => "Device Macid", :required => true
    # param :network_configuration, String, :desc => "Configuration to the network default or clone", :required => true
    # param :cloned_network_name, String, :desc => "Existing network name", :required => true
    # param :cloned_network_id, Integer, :desc => "Existing network name", :required => true
    param :network_name, String, :desc => "New network name which you are going to create", :required => true
    param :timezone, String, :desc => "Network you are going to create to which area", :required => true
  end

  def create
    macids = params[:location_network] ? router_inventory_params[:mac_id] : ""
    exist_network_name_params = params[:location_network][:cloned_network_name]
    exist_network_id_params = params[:location_network][:cloned_network_id]
    if exist_network_name_params
      existing_network_name = @user.organisation.location_networks.where(network_name: exist_network_name_params).first
    else
      existing_network_name = @user.organisation.location_networks.where(id: exist_network_id_params).first
    end
    invalid_mac_ids = []
    unless macids.blank?
      inventory = macids.split(',')
      inventory.each do |router|
        status, message = RouterInventory.validate_router(router,@user.organisation)
        invalid_mac_ids << router if status == false
      end
    end
    if !invalid_mac_ids.present?
      if params[:location_network][:network_configuration] == "clone" && existing_network_name.present?
        params[:location_network][:cloned_network_id] = existing_network_name.id
        params[:location_network][:network_configuration] = "clone"
        @network = @user.location_networks.build(location_network_params)
      elsif (params[:location_network][:network_configuration] == "clone") && (!exist_network_name_params.present? && !exist_network_id_params.present?)
        return render json: { msg: "Configuration is clone but the clone network name and clone network id is not present", error_code: 1002}, status: 422
      elsif params[:location_network][:network_configuration] == "clone" && !existing_network_name.present?
        return render json: { msg: "Requested clone network is not found please check and try again.", error_code: 1003}, status: 422
      else
        @network = @user.location_networks.build(location_network_params)
      end
      @network.organisation_id = @user.organisation.id
      if @network.save
        render json: { msg: "Successfully created new Network", data: @network.json_build(true), status: 200 }
        inventory = macids
        unless inventory.blank?
          inventory = inventory.split(',')
          inventory.each do |router|
            RouterInventory.router_activation([router,@network.network_name],@user,false)
          end
        end
      else
        render json: { msg: "Oops! there was some problem in creating Network", errors: "#{@network.errors.full_messages.join(",")}", error_code: 1004}, status: 422
      end
    elsif @user.organisation.router_inventories.count.to_i >= @user.organisation.no_of_aps.to_i
      render json: { msg: "You have reached the maximum limit #{@user.organisation.no_of_aps} to add inventories", error_code: 1005}, status: 422 
    else
      render json: { msg: "Following macid #{invalid_mac_ids.join(",")} are invalid or already provisioned. Please check your macids", error_code: 1006 }, status: 422
    end
  end

  def destroy
    unless @location_network.blank?
      unless @location_network.router_inventories.present?
        if @location_network.destroy
          render json: { msg: "Successfully deleted the Network ( #{@location_network.network_name} )", data: {id: @location_network.id, network_name: @location_network.network_name, timezone: @location_network.timezone}, status: 200}
        else
          render json: { msg: "Oops! there was some problem in deleting network #{@location_network.errors.full_messages}", error_code: 1007}, status: 422
        end
      else
        render json: { msg: "Oops! cannot delete network, Requested network has devices associated with it", data: @location_network.json_build, error_code: 1008}, status: 422
      end
    else
      render json: { msg: "Requested Network is not found", error_code: 1001}, status: 404
    end
  end

  def update
    if @location_network.present?
      if @location_network.update_attributes(update_location_network_params(@location_network))
        render json: { msg: "Successfully updated the network", data: @location_network.json_build, status: 200 }
      else
        render json: { msg: "Oops! there was some problem in updating network", errors: "#{@location_network.errors.full_messages.join(",")}", error_code: 1010}, status: 422
      end
    else
      render json: { msg: "Requested Network not found. Please check your Network", error_code: 1001}, status: 404
    end
  end

  def show
    render json: {data: {location_network: @location_network.json_build}, status: 200}, status: 200
  end

  def get_network_devices
    render json: {data: {devices: @location_network.router_inventories.map(&:json_build)}, status: 200}, status: 200
  end

  def location_network_params
    params.require(:location_network).permit(:id, :network_name, :timezone,:cloned_network_id,:network_configuration, :tag_list => [])
  end

  def update_location_network_params(network)
    if network.network_template && network.enable_policy
      params.require(:location_network).permit(:network_name, template_policy_attributes: [unlock_controls: [ssid_configuration: [unlock: []]]])
    else
      params.require(:location_network).permit(:network_name, :timezone, :presence, :presence_url, :vendor_type, :network_template, :template_adherence, :enable_policy, :template_policy_attributes => [unlock_controls: [ssid_configuration: [unlock: []]]], :tag_list => [])
    end
  end


  def router_inventory_params
    params.require(:location_network).permit(:mac_id)
  end

  def set_location_network
    @location_network = @user.organisation.location_networks.where(id: params[:id]).last
    if @location_network.blank?
      render json: { msg: "Requested location network is not found.", error_code: 1001}, status: 404
    end
  end

  # api :POST, "/v1/location_networks/:network_id/config_rollback", "Rollback Network Configuration"
  # param :access_token, String, desc: "User Access Token"
  # param :network_id, :number, desc: "Network ID"
  #param :configuration, Hash, :desc => "configurations for the network like ssid_configuration etc." 
  
  def config_rollback
    network_id = params[:network_id]
    network_template_id = params[:network_template_id]
    location_network = @user.organisation.location_networks.where(id: network_id).last
    ssid_configuration = params[:configuration].try(:[], :ssid_configuration)
  
    if location_network
      begin
        location_network.clear_and_clone_configs(ssid_configuration, network_template_id)
        render json: { message: "Configuration rollback completed for Network: #{location_network.network_name}" }
      rescue ActiveRecord::RecordNotFound => e
        render json: { message: e.message }, status: :not_found
      end
    else
      render json: { message: "Network not found" }, status: :not_found
    end
  end
  
end
