defmodule TeslaMateWeb.GeoFenceLiveTest do
  use TeslaMateWeb.ConnCase

  alias TeslaMate.{Locations, Settings, Log, Repo}
  alias TeslaMate.Locations.GeoFence

  import TestHelper, only: [decimal: 1]
  import Ecto.Query

  def geofence_fixture(attrs \\ %{}) do
    {:ok, address} =
      attrs
      |> Enum.into(%{radius: 100})
      |> Locations.create_geofence()

    address
  end

  defp car_fixture(attrs \\ %{}) do
    {:ok, car} =
      attrs
      |> Enum.into(%{
        efficiency: 0.153,
        eid: 42,
        model: "S",
        vid: 42,
        name: "foo",
        trim_badging: "P100D",
        vin: "12345F"
      })
      |> Log.create_car()

    car
  end

  describe "Index" do
    test "renders all geo-fences", %{conn: conn} do
      _gf1 =
        geofence_fixture(%{name: "Post office", latitude: -25.066188, longitude: -130.100502})

      _gf2 =
        geofence_fixture(%{name: "Service Center", latitude: 52.394246, longitude: 13.542552})

      _gf3 =
        geofence_fixture(%{name: "Victory Column", latitude: 52.514521, longitude: 13.350144})

      assert {:ok, _view, html} = live(conn, "/geo-fences")

      assert [
               _,
               ["Post office", "-25.066188, -130.100502", "100 m", _],
               ["Service Center", "52.394246, 13.542552", "100 m", _],
               ["Victory Column", "52.514521, 13.350144", "100 m", _]
             ] =
               html
               |> Floki.parse_document!()
               |> Floki.find("tr")
               |> Enum.map(fn row ->
                 row |> Floki.find("td") |> Enum.map(&Floki.text/1) |> Enum.map(&String.trim/1)
               end)
    end

    test "displays radius in ft", %{conn: conn} do
      {:ok, _settings} =
        Settings.get_global_settings!() |> Settings.update_global_settings(%{unit_of_length: :mi})

      _gf1 =
        geofence_fixture(%{
          name: "Post office",
          latitude: -25.066188,
          longitude: -130.100502,
          radius: 100
        })

      assert {:ok, _view, html} = live(conn, "/geo-fences")

      assert ["Post office", "-25.066188, -130.100502", "328 ft", _] =
               html
               |> Floki.parse_document!()
               |> Floki.find("td")
               |> Enum.map(&Floki.text/1)
               |> Enum.map(&String.trim/1)
    end

    test "allows deletion of a geo-fence", %{conn: conn} do
      %GeoFence{id: id} =
        geofence_fixture(%{name: "Victory Column", latitude: 52.514521, longitude: 13.350144})

      assert {:ok, view, html} = live(conn, "/geo-fences")

      assert ["Victory Column", "52.514521, 13.350144", "100 m", _] =
               html
               |> Floki.parse_document!()
               |> Floki.find("td")
               |> Enum.map(&Floki.text/1)
               |> Enum.map(&String.trim/1)

      assert [{"a", _, _}] =
               html
               |> Floki.parse_document!()
               |> Floki.find("[data-id=#{id}]")

      assert [{"tbody", _, []}] =
               view
               |> render_click(:delete, %{"id" => "#{id}"})
               |> Floki.parse_document!()
               |> Floki.find("tbody")
    end
  end

  describe "Edit" do
    test "validates changes when editing of a geo-fence", %{conn: conn} do
      %GeoFence{id: id} =
        geofence_fixture(%{
          name: "Post office",
          latitude: -25.066188,
          longitude: -130.100502,
          billing_type: :per_kwh,
          cost_per_unit: 0.2599,
          session_fee: 5.49
        })

      assert {:ok, view, html} = live(conn, "/geo-fences/#{id}/edit")
      html = Floki.parse_document!(html)

      name = Floki.find(html, "#geo_fence_name")
      assert ["Post office"] = Floki.attribute(name, "value")

      latitude = Floki.find(html, "#geo_fence_latitude")
      assert ["-25.066188"] = Floki.attribute(latitude, "value")

      longitude = Floki.find(html, "#geo_fence_longitude")
      assert ["-130.100502"] = Floki.attribute(longitude, "value")

      radius = Floki.find(html, "#geo_fence_radius")
      assert ["100"] = Floki.attribute(radius, "value")

      radius = Floki.find(html, "#geo_fence_cost_per_unit")
      assert ["0.2599"] = Floki.attribute(radius, "value")

      radius = Floki.find(html, "#geo_fence_session_fee")
      assert ["5.49"] = Floki.attribute(radius, "value")

      html =
        render_submit(view, :save, %{geo_fence: %{name: "", radius: ""}})
        |> Floki.parse_document!()

      assert [""] = html |> Floki.find("#geo_fence_name") |> Floki.attribute("value")

      for kind <- ["name", "radius"] do
        error_html =
          html
          |> Floki.find(".field-body .field")
          |> Enum.filter(fn field ->
            Floki.find(field, "input[name=\"geo_fence[#{kind}]\"]") |> length() == 1
          end)
          |> Enum.map(fn field -> Floki.find(field, "span.help.is-danger.pl-15") end)
          |> List.flatten()
          |> Enum.map(&Floki.raw_html(&1, encode: false))
          |> Enum.join()

        assert error_html ==
                 "<span class=\"help is-danger pl-15\" phx-feedback-for=\"geo_fence[#{kind}]\">can't be blank</span>"
      end
    end

    test "allows editing of a geo-fence", %{conn: conn} do
      %GeoFence{id: id} =
        geofence_fixture(%{name: "Post office", latitude: -25.066188, longitude: -130.100502})

      assert {:ok, view, html} = live(conn, "/geo-fences/#{id}/edit")
      html = Floki.parse_document!(html)

      name = Floki.find(html, "#geo_fence_name")
      assert ["Post office"] = Floki.attribute(name, "value")

      latitude = Floki.find(html, "#geo_fence_latitude")
      assert ["-25.066188"] = Floki.attribute(latitude, "value")

      longitude = Floki.find(html, "#geo_fence_longitude")
      assert ["-130.100502"] = Floki.attribute(longitude, "value")

      radius = Floki.find(html, "#geo_fence_radius")
      assert ["100"] = Floki.attribute(radius, "value")

      render_submit(view, :save, %{
        geo_fence: %{name: "Adamstown", longitude: 0, latitude: 0, radius: 20}
      })

      assert_redirect(view, "/geo-fences")

      assert {:ok, _view, html} = live(conn, "/geo-fences")

      assert ["Adamstown", "0.000000, 0.000000", "20 m", _] =
               html
               |> Floki.parse_document!()
               |> Floki.find("td")
               |> Enum.map(&Floki.text/1)
               |> Enum.map(&String.trim/1)
    end
  end

  describe "New" do
    test "pre-fills the coordinates with the most recent position", %{conn: conn} do
      car = car_fixture()

      assert {:ok, _} =
               Log.insert_position(car, %{
                 date: DateTime.utc_now(),
                 latitude: 48.067612,
                 longitude: 12.862226
               })

      assert {:ok, _view, html} = live(conn, "/geo-fences/new")
      html = Floki.parse_document!(html)

      latitude = Floki.find(html, "#geo_fence_latitude")
      longitude = Floki.find(html, "#geo_fence_longitude")

      assert ["48.067612"] = Floki.attribute(latitude, "value")
      assert ["12.862226"] = Floki.attribute(longitude, "value")
    end

    test "validates changes when creating a new geo-fence", %{conn: conn} do
      assert {:ok, view, _html} = live(conn, "/geo-fences/new")

      html =
        render_submit(view, :save, %{
          geo_fence: %{
            name: "",
            longitude: nil,
            latitude: nil,
            radius: "",
            billing_type: :per_kwh,
            cost_per_unit: "wat",
            session_fee: "wat"
          }
        })
        |> Floki.parse_document!()

      assert [""] = html |> Floki.find("#geo_fence_name") |> Floki.attribute("value")
      assert [""] = html |> Floki.find("#geo_fence_latitude") |> Floki.attribute("value")
      assert [""] = html |> Floki.find("#geo_fence_longitude") |> Floki.attribute("value")
      assert [""] = html |> Floki.find("#geo_fence_radius") |> Floki.attribute("value")
      assert ["wat"] = html |> Floki.find("#geo_fence_cost_per_unit") |> Floki.attribute("value")
      assert ["wat"] = html |> Floki.find("#geo_fence_session_fee") |> Floki.attribute("value")

      assert [
               field_position,
               field_name,
               field_cost_per_unit,
               field_session_fee,
               _
             ] = Floki.find(html, ".field.is-horizontal")

      assert ["can't be blank", "can't be blank", "can't be blank"] =
               field_position |> Floki.find("span") |> Enum.map(&Floki.text/1)

      assert ["can't be blank"] = field_name |> Floki.find("span") |> Enum.map(&Floki.text/1)

      assert "Per kWh" =
               field_cost_per_unit
               |> Floki.find("#geo_fence_billing_type option[selected]")
               |> Floki.text()

      assert "is invalid" =
               field_cost_per_unit
               |> Floki.find("span.help")
               |> Floki.text()

      assert "is invalid" =
               field_session_fee
               |> Floki.find("span")
               |> Floki.text()

      html =
        render_submit(view, :save, %{
          geo_fence: %{
            name: "foo",
            longitude: "wot",
            latitude: "wat",
            radius: "40",
            billing_type: :per_minute,
            cost_per_unit: 0.25,
            session_fee: 4.79
          }
        })
        |> Floki.parse_document!()

      assert ["foo"] = html |> Floki.find("#geo_fence_name") |> Floki.attribute("value")
      assert ["wat"] = html |> Floki.find("#geo_fence_latitude") |> Floki.attribute("value")
      assert ["wot"] = html |> Floki.find("#geo_fence_longitude") |> Floki.attribute("value")
      assert ["40"] = html |> Floki.find("#geo_fence_radius") |> Floki.attribute("value")
      assert ["0.25"] = html |> Floki.find("#geo_fence_cost_per_unit") |> Floki.attribute("value")
      assert ["4.79"] = html |> Floki.find("#geo_fence_session_fee") |> Floki.attribute("value")

      assert [
               field_position,
               field_name,
               field_cost_per_unit,
               field_session_fee,
               _
             ] = Floki.find(html, ".field.is-horizontal")

      assert ["is invalid", "is invalid"] =
               field_position |> Floki.find("span") |> Enum.map(&Floki.text/1)

      assert [] =
               field_name
               |> Floki.find("span")
               |> Enum.map(&Floki.text/1)

      assert "Per Minute" =
               field_cost_per_unit
               |> Floki.find("#geo_fence_billing_type option[selected]")
               |> Floki.text()

      assert "" =
               field_cost_per_unit
               |> Floki.find("span.help")
               |> Floki.text()

      assert "" =
               field_session_fee
               |> Floki.find("span")
               |> Floki.text()
    end

    test "creates a new geo-fence", %{conn: conn} do
      assert {:ok, view, html} = live(conn, "/geo-fences/new")

      # Default radius of 20m
      assert html
             |> Floki.parse_document!()
             |> Floki.find("#geo_fence_radius")
             |> Floki.attribute("value") == ["20"]

      render_submit(view, :save, %{
        geo_fence: %{
          name: "post office",
          latitude: -25.066188,
          longitude: -130.100502,
          radius: 25
        }
      })

      assert_redirect(view, "/geo-fences")

      assert {:ok, _view, html} = live(conn, "/geo-fences")

      assert ["post office", "-25.066188, -130.100502", "25 m", _] =
               html
               |> Floki.parse_document!()
               |> Floki.find("td")
               |> Enum.map(&Floki.text/1)
               |> Enum.map(&String.trim/1)
    end

    test "allows creating of a geo-fence with radius being displayed in ft", %{conn: conn} do
      {:ok, _settings} =
        Settings.get_global_settings!() |> Settings.update_global_settings(%{unit_of_length: :mi})

      assert {:ok, view, _html} = live(conn, "/geo-fences/new")

      render_submit(view, :save, %{
        geo_fence: %{
          name: "post office",
          latitude: -25.066188,
          longitude: -130.100502,
          radius: 15
        }
      })

      assert_redirect(view, "/geo-fences")

      assert {:ok, _view, html} = live(conn, "/geo-fences")

      assert ["post office", "-25.066188, -130.100502", "49 ft", _] =
               html
               |> Floki.parse_document!()
               |> Floki.find("td")
               |> Enum.map(&Floki.text/1)
               |> Enum.map(&String.trim/1)

      {:ok, _settings} =
        Settings.get_global_settings!() |> Settings.update_global_settings(%{unit_of_length: :km})

      assert {:ok, _view, html} = live(conn, "/geo-fences")

      assert ["post office", "-25.066188, -130.100502", "15 m", _] =
               html
               |> Floki.parse_document!()
               |> Floki.find("td")
               |> Enum.map(&Floki.text/1)
               |> Enum.map(&String.trim/1)
    end
  end

  describe "grafana URL" do
    alias TeslaMate.Settings.GlobalSettings

    test "sets the base URL", %{conn: conn} do
      assert %GlobalSettings{grafana_url: nil} = Settings.get_global_settings!()

      assert {:ok, _parent_view, _html} =
               conn
               |> put_connect_params(%{"referrer" => "http://grafana.example.com/d/xyz/12"})
               |> live("/geo-fences/new?lat=0.0&lng=0.0")

      assert %GlobalSettings{grafana_url: "http://grafana.example.com"} =
               Settings.get_global_settings!()
    end

    test "handles weird referrers", %{conn: conn} do
      assert %GlobalSettings{grafana_url: nil} = Settings.get_global_settings!()

      for referrer <- [nil, "", "example.com", "http://example.com", "http://example.com/"] do
        assert {:ok, _parent_view, _html} =
                 conn
                 |> put_connect_params(%{"referrer" => referrer})
                 |> live("/geo-fences/new?lat=0.0&lng=0.0")

        assert %GlobalSettings{grafana_url: nil} = Settings.get_global_settings!()
      end
    end

    test "keeps the path", %{conn: conn} do
      assert %GlobalSettings{grafana_url: nil} = Settings.get_global_settings!()

      assert {:ok, _parent_view, _html} =
               conn
               |> put_connect_params(%{"referrer" => "http://example.com:9090/grafana/d/xyz/12"})
               |> live("/geo-fences/new?lat=0.0&lng=0.0")

      assert %GlobalSettings{grafana_url: "http://example.com:9090/grafana"} =
               Settings.get_global_settings!()
    end

    test "does not update the base URL if exists already", %{conn: conn} do
      assert {:ok, _settings} =
               Settings.get_global_settings!()
               |> Settings.update_global_settings(%{grafana_url: "https://grafana.example.com"})

      assert {:ok, _parent_view, _html} =
               conn
               |> put_connect_params(%{"referrer" => "http://grafana.foo.com/d/xyz/12"})
               |> live("/geo-fences/new?lat=0.0&lng=0.0")

      assert %GlobalSettings{grafana_url: "https://grafana.example.com"} =
               Settings.get_global_settings!()
    end
  end

  describe "charging cost" do
    alias TeslaMate.Log.{ChargingProcess, Position}
    alias TeslaMate.Log

    test "shows modal if cost per kWh was entered", %{conn: conn} do
      car = car_fixture()

      lat = 47.81444104508753
      lng = 12.367612123489382

      params = %{
        name: "Supercharger",
        latitude: 47.814441,
        longitude: 12.367768,
        radius: 30,
        billing_type: :per_kwh,
        cost_per_unit: 0.33,
        session_fee: nil
      }

      # Does not show modal if there aren't any charging sessions at this location

      assert {:ok, view, _html} = live(conn, "/geo-fences/new")
      render_submit(view, :save, %{geo_fence: params})
      assert_redirect(view, "/geo-fences")

      # Insert charging sessions ...

      :ok = insert_charging_processes(car, {lat, lng})
      assert {:ok, view, html} = live(conn, "/geo-fences/new")

      assert [] == html |> Floki.parse_document!() |> Floki.find(".modal.is-active")

      html =
        render_submit(view, :save, %{geo_fence: params})
        |> Floki.parse_document!()

      modal = Floki.find(html, ".modal.is-active")

      assert "3 charging sessions" =
               modal |> Floki.find(".modal-card-body strong") |> Floki.text()

      assert ["Continue", "Add costs retroactively"] =
               modal
               |> Floki.find(".modal-card-foot button")
               |> Enum.map(&Floki.text/1)
               |> Enum.map(&String.trim/1)
    end

    test "shows modal if a session fee was entered", %{conn: conn} do
      car = car_fixture()
      lat = 47.81444104508753
      lng = 12.367612123489382
      :ok = insert_charging_processes(car, {lat, lng})

      assert {:ok, view, html} = live(conn, "/geo-fences/new")

      assert [] == html |> Floki.parse_document!() |> Floki.find(".modal.is-active")

      html =
        render_submit(view, :save, %{
          geo_fence: %{
            name: "Supercharger",
            latitude: 47.814441,
            longitude: 12.367768,
            radius: 30,
            billing_type: :per_kwh,
            cost_per_unit: nil,
            session_fee: 4.69
          }
        })
        |> Floki.parse_document!()

      modal = Floki.find(html, ".modal.is-active")

      assert "3 charging sessions" =
               modal |> Floki.find(".modal-card-body strong") |> Floki.text()

      assert ["Continue", "Add costs retroactively"] =
               modal
               |> Floki.find(".modal-card-foot button")
               |> Enum.map(&Floki.text/1)
               |> Enum.map(&String.trim/1)
    end

    test "shows modal if the position changed", %{conn: conn} do
      car = car_fixture()

      %GeoFence{id: id} =
        geofence_fixture(%{
          name: "Supercharger",
          latitude: 47.814441,
          longitude: 12.367768,
          radius: 30,
          billing_type: :per_kwh,
          cost_per_unit: nil,
          session_fee: 4.69
        })

      :ok = insert_charging_processes(car, {47.81444104508753, 12.367612123489382})

      # Edit geofence

      assert {:ok, view, h} = live(conn, "/geo-fences/#{id}/edit")
      h = Floki.parse_document!(h)

      assert [] == Floki.find(h, ".modal.is-active")
      assert ["47.814441"] = h |> Floki.find("#geo_fence_latitude") |> Floki.attribute("value")
      assert ["12.367768"] = h |> Floki.find("#geo_fence_longitude") |> Floki.attribute("value")

      html =
        render_submit(view, :save, %{geo_fence: %{latitude: 47.814451, longitude: 12.367761}})
        |> Floki.parse_document!()

      modal = Floki.find(html, ".modal.is-active")

      assert "3 charging sessions" =
               modal |> Floki.find(".modal-card-body strong") |> Floki.text()

      assert ["Continue", "Add costs retroactively"] =
               modal
               |> Floki.find(".modal-card-foot button")
               |> Enum.map(&Floki.text/1)
               |> Enum.map(&String.trim/1)
    end

    test "shows modal if the radius changed", %{conn: conn} do
      car = car_fixture()

      %GeoFence{id: id} =
        geofence_fixture(%{
          name: "Supercharger",
          latitude: 47.814441,
          longitude: 12.367768,
          radius: 30,
          billing_type: :per_kwh,
          cost_per_unit: 0.42,
          session_fee: nil
        })

      :ok = insert_charging_processes(car, {47.81444104508753, 12.367612123489382})

      # Edit geofence

      assert {:ok, view, h} = live(conn, "/geo-fences/#{id}/edit")
      h = Floki.parse_document!(h)

      assert [] == Floki.find(h, ".modal.is-active")
      assert ["47.814441"] = h |> Floki.find("#geo_fence_latitude") |> Floki.attribute("value")
      assert ["12.367768"] = h |> Floki.find("#geo_fence_longitude") |> Floki.attribute("value")

      html =
        render_submit(view, :save, %{geo_fence: %{radius: 50}})
        |> Floki.parse_document!()

      modal = Floki.find(html, ".modal.is-active")

      assert "3 charging sessions" =
               modal |> Floki.find(".modal-card-body strong") |> Floki.text()

      assert ["Continue", "Add costs retroactively"] =
               modal
               |> Floki.find(".modal-card-foot button")
               |> Enum.map(&Floki.text/1)
               |> Enum.map(&String.trim/1)
    end

    test "adds charging costs", %{conn: conn} do
      car = car_fixture()
      :ok = insert_charging_processes(car, {47.81444104508753, 12.367612123489382})
      :ok = insert_charging_processes(car, {42.0, 69.0})

      assert {:ok, view, html} = live(conn, "/geo-fences/new")
      assert [] == html |> Floki.parse_document!() |> Floki.find(".modal.is-active")

      html =
        render_submit(view, :save, %{
          geo_fence: %{
            name: "Supercharger",
            latitude: 47.814441,
            longitude: 12.367768,
            radius: 30,
            billing_type: :per_kwh,
            cost_per_unit: 0.33,
            session_fee: 5.00
          }
        })
        |> Floki.parse_document!()

      assert [
               {"button", [_, {"phx-click", "calc-costs"}, {"phx-value-result", "no"}],
                [no_button_text]},
               {"button", [_, {"phx-click", "calc-costs"}, {"phx-value-result", "yes"}],
                [yes_button_text]}
             ] = html |> Floki.find(".modal.is-active") |> Floki.find(".modal-card-foot button")

      assert "Continue" == String.trim(no_button_text)
      assert "Add costs retroactively" == String.trim(yes_button_text)

      view
      |> element(".modal button", "Add costs retroactively")
      |> render_click()

      assert_redirect(view, "/geo-fences")

      assert [
               %ChargingProcess{
                 geofence_id: id,
                 charge_energy_added: decimal(50.63),
                 charge_energy_used: nil,
                 cost: decimal("99.00")
               },
               %ChargingProcess{
                 geofence_id: id,
                 charge_energy_added: decimal(4.57),
                 charge_energy_used: nil,
                 cost: decimal(6.51)
               },
               %ChargingProcess{
                 geofence_id: id,
                 charge_energy_added: decimal(11.82),
                 charge_energy_used: nil,
                 cost: decimal("8.90")
               },
               %ChargingProcess{
                 geofence_id: id,
                 charge_energy_added: decimal("52.10"),
                 charge_energy_used: nil,
                 cost: decimal(22.19)
               },
               %ChargingProcess{geofence_id: nil, cost: decimal("99.00")},
               %ChargingProcess{geofence_id: nil, cost: nil},
               %ChargingProcess{geofence_id: nil, cost: nil},
               %ChargingProcess{geofence_id: nil, cost: nil}
             ] = Repo.all(from c in ChargingProcess, order_by: c.id)

      assert %GeoFence{
               name: "Supercharger",
               latitude: decimal(47.814441),
               longitude: decimal(12.367768),
               radius: 30,
               billing_type: :per_kwh,
               cost_per_unit: decimal("0.3300"),
               session_fee: decimal("5.00")
             } = Repo.get(GeoFence, id)
    end

    test "skips adding charging costs", %{conn: conn} do
      car = car_fixture()
      :ok = insert_charging_processes(car, {47.81444104508753, 12.367612123489382})

      assert {:ok, view, _html} = live(conn, "/geo-fences/new")

      html =
        render_submit(view, :save, %{
          geo_fence: %{
            name: "Supercharger",
            latitude: 47.814441,
            longitude: 12.367768,
            radius: 30,
            billing_type: :per_kwh,
            cost_per_unit: 0.33,
            session_fee: 5.00
          }
        })
        |> Floki.parse_document!()

      assert [
               {"button", [_, {"phx-click", "calc-costs"}, {"phx-value-result", "no"}],
                [no_button_text]},
               {"button", [_, {"phx-click", "calc-costs"}, {"phx-value-result", "yes"}],
                [yes_button_text]}
             ] = html |> Floki.find(".modal.is-active") |> Floki.find(".modal-card-foot button")

      assert String.trim(no_button_text) == "Continue"
      assert String.trim(yes_button_text) == "Add costs retroactively"

      view
      |> element(".modal button", "Continue")
      |> render_click()

      assert_redirect(view, "/geo-fences")

      assert [
               %ChargingProcess{geofence_id: id, cost: decimal("99.00")},
               %ChargingProcess{geofence_id: id, cost: nil},
               %ChargingProcess{geofence_id: id, cost: nil},
               %ChargingProcess{geofence_id: id, cost: nil}
             ] = Repo.all(from c in ChargingProcess, order_by: c.id)

      assert %GeoFence{
               name: "Supercharger",
               latitude: decimal(47.814441),
               longitude: decimal(12.367768),
               radius: 30,
               billing_type: :per_kwh,
               cost_per_unit: decimal("0.3300"),
               session_fee: decimal("5.00")
             } = Repo.get(GeoFence, id)
    end

    defp insert_charging_processes(car, {lat, lng}) do
      {:ok, %Position{id: position_id}} =
        Log.insert_position(car, %{date: DateTime.utc_now(), latitude: lat, longitude: lng})

      data =
        for {sir, eir, srr, err, ca, sl, el, d, c} <- [
              {80.5, 412.4, nil, nil, 50.63, 16, 83, 70, 99.0},
              {109.7, 139.7, 108.7, 139.7, 4.57, 22, 28, 26, nil},
              {63.9, 142.3, 64.9, 142.3, 11.82, 13, 29, 221, nil},
              {107.9, 450.1, 108.9, 450.1, 52.1, 22, 90, 40, nil}
            ] do
          %{
            car_id: car.id,
            start_date: DateTime.utc_now(),
            position_id: position_id,
            start_ideal_range_km: sir,
            end_ideal_range_km: eir,
            start_rated_range_km: srr,
            end_rated_range_km: err,
            charge_energy_added: ca,
            start_battery_level: sl,
            end_battery_level: el,
            duration_min: d,
            cost: c
          }
        end

      {_, nil} = Repo.insert_all(ChargingProcess, data)

      :ok
    end
  end
end
