import "package:flutter/material.dart";

import "../i18n.dart";
import "../main.dart";
import "../models.dart";
import "../theme.dart";

/// Create a home charger from one on a connected charger service (Anker Solix or
/// Greencell today; the endpoints are generic, so the next service needs no
/// changes here).
///
/// Shorter than the car import on purpose: a charger is a name, a serial and the
/// hardware behind it, and the service's list already carries all three. There is
/// nothing to choose about what to pull, so the whole sheet is pick one, press
/// Import. Pops the created [HomeCharger] when it saved.
Future<HomeCharger?> showChargerImportSheet(BuildContext context) {
  return showModalBottomSheet<HomeCharger>(
    context: context,
    isScrollControlled: true,
    builder: (_) => const _ChargerImportSheet(),
  );
}

class _ChargerImportSheet extends StatefulWidget {
  const _ChargerImportSheet();
  @override
  State<_ChargerImportSheet> createState() => _ChargerImportSheetState();
}

class _ChargerImportSheetState extends State<_ChargerImportSheet> {
  final _name = TextEditingController();

  List<ChargerProvider> _providers = const [];
  String _provider = "";
  List<ProviderCharger> _chargers = const [];
  String _selectedId = "";

  bool _loading = true;
  bool _loadingChargers = false;
  bool _importing = false;
  String? _error;

  /// Why the provider can't be used right now (not connected, an org switch off,
  /// …). The server phrases this; the sheet just shows it.
  String _detail = "";

  /// The name field tracks the selected charger until the user types their own.
  bool _nameEdited = false;

  @override
  void initState() {
    super.initState();
    _init();
  }

  @override
  void dispose() {
    _name.dispose();
    super.dispose();
  }

  ChargerProvider? get _current {
    for (final p in _providers) {
      if (p.id == _provider) return p;
    }
    return null;
  }

  ProviderCharger? get _selected {
    for (final c in _chargers) {
      if (c.id == _selectedId) return c;
    }
    return null;
  }

  bool get _canImport =>
      _selected != null && _selected!.linkedChargerId.isEmpty && !_importing;

  Future<void> _init() async {
    try {
      final list = await apiClient.listChargerProviders();
      if (!mounted) return;
      setState(() {
        _providers = list;
        final connected = list.where((p) => p.connected);
        _provider = connected.isNotEmpty
            ? connected.first.id
            : (list.isNotEmpty ? list.first.id : "");
      });
    } catch (e) {
      if (mounted) setState(() => _error = "$e");
    } finally {
      if (mounted) setState(() => _loading = false);
    }
    await _loadChargers();
  }

  Future<void> _loadChargers() async {
    setState(() {
      _chargers = const [];
      _selectedId = "";
      _detail = "";
    });
    if (_provider.isEmpty) return;
    // A provider that is not connected has nothing to list; say what to do about
    // it instead of asking the server a question it has already answered.
    if (_current?.connected != true) {
      setState(() => _detail = _current?.detail ?? "");
      return;
    }

    setState(() {
      _loadingChargers = true;
      _error = null;
    });
    try {
      final res = await apiClient.listProviderChargers(_provider);
      if (!mounted) return;
      // Preselect the first charger that isn't here already — with one charger
      // on the account that is the whole selection step.
      var pick = "";
      for (final c in res.chargers) {
        if (c.linkedChargerId.isEmpty) {
          pick = c.id;
          break;
        }
      }
      setState(() {
        _chargers = res.chargers;
        _detail = res.unavailable ? res.detail : "";
        _selectedId = pick;
      });
      _syncName();
    } catch (e) {
      if (mounted) setState(() => _error = "$e");
    } finally {
      if (mounted) setState(() => _loadingChargers = false);
    }
  }

  void _syncName() {
    if (_nameEdited) return;
    _name.text = _selected?.name ?? "";
  }

  Future<void> _submit() async {
    if (!_canImport) return;
    setState(() {
      _importing = true;
      _error = null;
    });
    try {
      final charger = await apiClient.importProviderCharger(
        _provider,
        _selected!.id,
        name: _name.text.trim(),
      );
      if (mounted) Navigator.pop(context, charger);
    } catch (e) {
      if (mounted) setState(() => _error = "$e");
    } finally {
      if (mounted) setState(() => _importing = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    final muted = DriverVault.muted(context);
    return Padding(
      padding: EdgeInsets.only(
        left: 16,
        right: 16,
        top: 16,
        bottom: DriverVault.sheetBottomInset(context),
      ),
      child: SingleChildScrollView(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(t("forms.importCharger.title"),
                style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600)),
            const SizedBox(height: 12),
            if (_error != null)
              Padding(
                padding: const EdgeInsets.only(bottom: 8),
                child: Text(_error!, style: const TextStyle(color: DriverVault.danger)),
              ),
            if (_loading)
              Text(t("common.loading"), style: TextStyle(fontSize: 13, color: muted))
            else if (_providers.isEmpty)
              Text(t("forms.importCharger.noProviders"),
                  style: TextStyle(fontSize: 13, color: muted))
            else
              ..._form(context, muted),
            const SizedBox(height: 12),
            Row(children: [
              Expanded(
                child: OutlinedButton(
                  onPressed: () => Navigator.pop(context),
                  child: Text(t("common.cancel")),
                ),
              ),
              if (!_loading && _providers.isNotEmpty) ...[
                const SizedBox(width: 8),
                Expanded(
                  child: FilledButton(
                    onPressed: _canImport ? _submit : null,
                    child: Text(_importing
                        ? t("forms.import.importing")
                        : t("forms.importCharger.submit")),
                  ),
                ),
              ],
            ]),
          ],
        ),
      ),
    );
  }

  List<Widget> _form(BuildContext context, Color muted) {
    return [
      Text(t("forms.importCharger.subtitle"), style: TextStyle(fontSize: 13, color: muted)),
      const SizedBox(height: 12),

      // Service picker. Hidden while there is only one to pick.
      if (_providers.length > 1) ...[
        DropdownButtonFormField<String>(
          initialValue: _provider.isEmpty ? null : _provider,
          isExpanded: true,
          decoration: InputDecoration(
            labelText: t("forms.import.service"),
            border: const OutlineInputBorder(),
            isDense: true,
          ),
          items: [
            for (final p in _providers)
              DropdownMenuItem(
                value: p.id,
                enabled: p.connected,
                child: Text(
                  p.connected ? p.label : "${p.label} — ${t("forms.import.notConnected")}",
                  overflow: TextOverflow.ellipsis,
                ),
              ),
          ],
          onChanged: (id) {
            if (id == null || id == _provider) return;
            setState(() => _provider = id);
            _loadChargers();
          },
        ),
        const SizedBox(height: 12),
      ],

      if (_detail.isNotEmpty) ...[
        Container(
          width: double.infinity,
          padding: const EdgeInsets.all(12),
          decoration: BoxDecoration(
            color: DriverVault.isDark(context)
                ? DriverVault.warningSoftDark
                : DriverVault.warningSoft,
            borderRadius: BorderRadius.circular(DriverVault.radiusControl),
          ),
          child: Text(_detail,
              style: const TextStyle(fontSize: 13, color: DriverVault.warning)),
        ),
        const SizedBox(height: 12),
      ],

      Text(t("forms.importCharger.selectCharger"),
          style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600)),
      const SizedBox(height: 6),
      if (_loadingChargers)
        Text(t("forms.importCharger.loadingChargers"),
            style: TextStyle(fontSize: 13, color: muted))
      else if (_chargers.isEmpty && _detail.isEmpty)
        Text(t("forms.importCharger.noChargers"), style: TextStyle(fontSize: 13, color: muted))
      else
        for (final c in _chargers) _chargerRow(context, c, muted),

      if (_selected != null) ...[
        const SizedBox(height: 12),
        TextField(
          controller: _name,
          decoration: InputDecoration(
            labelText: t("forms.importCharger.name"),
            border: const OutlineInputBorder(),
            isDense: true,
          ),
          onChanged: (_) => _nameEdited = true,
        ),
      ],
    ];
  }

  Widget _chargerRow(BuildContext context, ProviderCharger c, Color muted) {
    final imported = c.linkedChargerId.isNotEmpty;
    final picked = _selectedId == c.id;
    return Padding(
      padding: const EdgeInsets.only(bottom: 8),
      child: InkWell(
        borderRadius: BorderRadius.circular(DriverVault.radiusControl),
        onTap: imported
            ? null
            : () {
                setState(() => _selectedId = c.id);
                _syncName();
              },
        child: Container(
          padding: const EdgeInsets.all(12),
          decoration: BoxDecoration(
            color: picked ? DriverVault.brandTint(context) : null,
            border: Border.all(
              color: picked
                  ? Theme.of(context).colorScheme.primary
                  : Theme.of(context).dividerColor,
            ),
            borderRadius: BorderRadius.circular(DriverVault.radiusControl),
          ),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Padding(
                padding: const EdgeInsets.only(right: 10, top: 2),
                child: Icon(
                  picked ? Icons.radio_button_checked : Icons.radio_button_unchecked,
                  size: 20,
                  color: imported
                      ? muted
                      : picked
                          ? Theme.of(context).colorScheme.primary
                          : muted,
                ),
              ),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(c.name.isNotEmpty ? c.name : c.id,
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                        style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600)),
                    if (c.subtitle.isNotEmpty)
                      Text(c.subtitle,
                          maxLines: 1,
                          overflow: TextOverflow.ellipsis,
                          style: TextStyle(fontSize: 12, color: muted)),
                    Text(c.id,
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                        style: DriverVault.mono(context, size: 11).copyWith(color: muted)),
                    if (imported)
                      Padding(
                        padding: const EdgeInsets.only(top: 4),
                        child: Text(t("forms.importCharger.alreadyImported"),
                            style: TextStyle(fontSize: 12, color: muted)),
                      )
                    else if (c.online == false)
                      Padding(
                        padding: const EdgeInsets.only(top: 4),
                        child: Text(t("settings.integrations.chargerOffline"),
                            style: const TextStyle(fontSize: 12, color: DriverVault.warning)),
                      ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
