// The charging page's home half.
//
// Nothing here can talk to a server, so what is worth guarding is what the page
// says without one: that both tabs render, that the home tab degrades to the
// "import one" invitation rather than a blank column, and that the arrange sheet
// offers exactly the tabs and cards the profile can store — those key sets are
// shared with the web app and the server, so a card added here and forgotten
// there would arrange into nothing.
import "package:flutter/material.dart";
import "package:flutter_test/flutter_test.dart";
import "package:intl/date_symbol_data_local.dart";
import "package:shared_preferences/shared_preferences.dart";

import "package:drivervault_phone/i18n.dart";
import "package:drivervault_phone/main.dart";
import "package:drivervault_phone/screens/charging_screen.dart";

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  setUpAll(() async {
    await initializeDateFormatting();
    await loadTranslations();
    appSettings.locale = "en-GB";
    appSettings.dateFormat = "DMY_NUM";
  });

  setUp(() {
    // The page reads its folded cards and its last serial from here.
    SharedPreferences.setMockInitialValues({});
  });

  // A surface tall enough that the page's lazy list builds the home cards as
  // well as the header above them.
  Future<void> pump(WidgetTester tester) async {
    tester.view.physicalSize = const Size(800, 3000);
    tester.view.devicePixelRatio = 1.0;
    addTearDown(tester.view.reset);
    await tester.pumpWidget(const MaterialApp(home: ChargingScreen()));
    await tester.pumpAndSettle();
  }

  testWidgets("both tabs render, and the home half invites an import", (tester) async {
    await pump(tester);

    expect(find.text(t("charging.tabs.public")), findsWidgets);
    expect(find.text(t("charging.tabs.home")), findsWidgets);

    // The page opens on the public half; the tab that is not shown is not built,
    // so the home cards are only findable once it is.
    expect(find.textContaining(t("charging.stations.heading")), findsWidgets);
    await tester.tap(find.text(t("charging.tabs.home")));
    await tester.pumpAndSettle();

    // With no chargers and no control mode, the home tab is the information card
    // saying there is nothing yet plus the list saying what it is for.
    expect(find.text(t("charging.info.title")), findsOneWidget);
    expect(find.text(t("charging.info.empty")), findsOneWidget);
    expect(find.text(t("charging.home.empty")), findsOneWidget);
    // No charger service answered, so importing is not on offer — the hint is.
    expect(find.text(t("charging.home.connectFirst")), findsOneWidget);
    expect(find.text(t("charging.home.import")), findsNothing);

    // Control is off, so the cards that act on a charger are absent and the
    // information card says why.
    expect(find.text(t("charging.control.title")), findsNothing);
    expect(find.text(t("charging.control.connectionTitle")), findsNothing);
    expect(find.text(t("charging.modbus.title")), findsNothing);
    expect(find.text(t("charging.stations.noControlHint")), findsOneWidget);
  });

  testWidgets("the arrange sheet offers every tab and every card", (tester) async {
    await pump(tester);

    await tester.tap(find.byIcon(Icons.swap_vert));
    await tester.pumpAndSettle();

    expect(find.text(t("charging.arrange.title")), findsOneWidget);
    for (final key in kChargerTabKeys) {
      expect(find.text(t("charging.tabs.$key")), findsWidgets,
          reason: "the $key tab is not on offer");
    }
    // Named by their own headings, so the sheet reads like the page.
    const cardLabels = {
      "control": "charging.control.title",
      "connection": "charging.control.connectionTitle",
      "readings": "charging.modbus.title",
      "info": "charging.info.title",
    };
    expect(cardLabels.keys.toSet(), kChargerCardKeys.toSet());
    for (final key in kChargerCardKeys) {
      expect(find.text(t(cardLabels[key]!)), findsWidgets,
          reason: "the $key card is not on offer");
    }

    // One drag handle per row: both lists rearrange, not just the first.
    expect(find.byIcon(Icons.drag_handle),
        findsNWidgets(kChargerTabKeys.length + kChargerCardKeys.length));
  });
}
