part of '../settings_modal.dart';

class _ProfileSection extends ConsumerStatefulWidget {
  final PyramidTheme pt;
  const _ProfileSection({required this.pt});

  @override
  ConsumerState<_ProfileSection> createState() => _ProfileSectionState();
}

class _ProfileSectionState extends ConsumerState<_ProfileSection> {
  late TextEditingController _nameCtrl;
  late TextEditingController _statusCtrl;
  bool _saving = false;
  bool _saved = false;
  String? _error;
  Uint8List? _pendingAvatar;
  Uri? _avatarUri;
  Uint8List? _pendingBanner;
  String? _bannerMxcUri;
  Uint8List? _pendingServerBanner;
  bool _serverBannerSaving = false;

  @override
  void initState() {
    super.initState();
    _nameCtrl = TextEditingController();
    _statusCtrl = TextEditingController();
    _loadProfile();
  }

  @override
  void dispose() {
    _nameCtrl.dispose();
    _statusCtrl.dispose();
    super.dispose();
  }

  Future<void> _loadProfile() async {
    final client = await ref.read(matrixClientProvider.future);
    if (!mounted) return;

    // 1) SOFORT aus dem lokalen Cache füllen — kein Warten auf den Server.
    _nameCtrl.text = client.userID ?? '';
    for (final room in client.rooms) {
      final u = room.unsafeGetUserFromMemoryOrFallback(client.userID!);
      if (u.displayName != null || u.avatarUrl != null) {
        if (u.displayName != null) _nameCtrl.text = u.displayName!;
        _avatarUri = u.avatarUrl;
        break;
      }
    }
    try {
      final bannerData = client.accountData['com.pyramid.profile.banner'];
      _bannerMxcUri = bannerData?.content['url'] as String?;
    } catch (_) {}
    setState(() {});

    // 2) Server-Daten PARALLEL nachladen, UI aktualisiert sich pro Antwort.
    client
        .getProfileFromUserId(client.userID!)
        .then((profile) {
      if (!mounted) return;
      setState(() {
        if (profile.displayName != null) _nameCtrl.text = profile.displayName!;
        _avatarUri = profile.avatarUrl ?? _avatarUri;
      });
    }).catchError((_) {});

    () async {
      try {
        final apiUri = client.homeserver!.replace(
          path:
              '/_matrix/client/v3/profile/${Uri.encodeComponent(client.userID!)}',
        );
        final resp = await client.httpClient.get(
          apiUri,
          headers: {'Authorization': 'Bearer ${client.accessToken}'},
        );
        if (resp.statusCode == 200 && mounted) {
          final data = jsonDecode(resp.body) as Map<String, dynamic>;
          final url = data['io.pyramid.profile.banner_url'] as String?;
          if (url != null) setState(() => _bannerMxcUri = url);
        }
      } catch (_) {}
    }();
  }

  Future<void> _pickAvatar() async {
    final result = await FilePicker.platform.pickFiles(type: FileType.image, withData: true);
    final file = result?.files.first;
    if (file == null) return;
    final bytes = file.bytes ?? await file.xFile.readAsBytes();
    setState(() => _pendingAvatar = bytes);
  }

  Future<void> _pickBanner() async {
    final result = await FilePicker.platform.pickFiles(type: FileType.image, withData: true);
    final file = result?.files.first;
    if (file == null) return;
    final raw = file.bytes ?? await file.xFile.readAsBytes();
    if (!mounted) return;
    final cropped = await showDialog<Uint8List>(
      context: context,
      builder: (_) => BannerCropDialog(imageBytes: raw, aspectRatio: 3.0),
    );
    if (cropped == null || !mounted) return;
    setState(() => _pendingBanner = cropped);
  }

  Future<void> _pickServerBanner() async {
    final result = await FilePicker.platform.pickFiles(type: FileType.image, withData: true);
    final file = result?.files.first;
    if (file == null) return;
    final raw = file.bytes ?? await file.xFile.readAsBytes();
    if (!mounted) return;
    final cropped = await showDialog<Uint8List>(
      context: context,
      builder: (_) => BannerCropDialog(imageBytes: raw, aspectRatio: 2.4),
    );
    if (cropped == null || !mounted) return;
    setState(() => _serverBannerSaving = true);
    try {
      final client = await ref.read(matrixClientProvider.future);
      final uri = await client.uploadContent(cropped, filename: 'server_banner.png', contentType: 'image/png');
      await ref.read(serverBannerProvider.notifier).set(client.homeserver.toString(), uri.toString());
      if (mounted) setState(() { _pendingServerBanner = cropped; _serverBannerSaving = false; });
    } catch (_) {
      if (mounted) setState(() => _serverBannerSaving = false);
    }
  }

  Future<void> _removeServerBanner() async {
    final client = ref.read(matrixClientProvider).valueOrNull;
    if (client == null) return;
    await ref.read(serverBannerProvider.notifier).set(client.homeserver.toString(), null);
    if (mounted) setState(() => _pendingServerBanner = null);
  }

  Future<void> _save() async {
    setState(() { _saving = true; _error = null; _saved = false; });
    try {
      final client = await ref.read(matrixClientProvider.future);
      final name = _nameCtrl.text.trim();
      if (name.isNotEmpty) {
        await client.setProfileField(
          client.userID!,
          'displayname',
          {'displayname': name},
        );
      }
      if (_pendingAvatar != null) {
        await client.setAvatar(MatrixFile(
          bytes: _pendingAvatar!,
          name: 'avatar.jpg',
          mimeType: 'image/jpeg',
        ));
        setState(() => _pendingAvatar = null);
      }
      if (_pendingBanner != null) {
        final uri = await client.uploadContent(
            _pendingBanner!, filename: 'banner.png', contentType: 'image/png');
        final uriStr = uri.toString();
        // Store as a profile custom field so other users can see it
        await client.setProfileField(
          client.userID!,
          'io.pyramid.profile.banner_url',
          {'io.pyramid.profile.banner_url': uriStr},
        );
        // Also keep in account data as legacy fallback
        await client.setAccountData(client.userID!, 'com.pyramid.profile.banner',
            {'url': uriStr});
        setState(() { _bannerMxcUri = uriStr; _pendingBanner = null; });
      }
      final status = _statusCtrl.text.trim();
      await client.setPresence(
        client.userID!,
        PresenceType.online,
        statusMsg: status.isEmpty ? null : status,
      );
      if (mounted) setState(() { _saving = false; _saved = true; });
      await Future.delayed(const Duration(seconds: 2));
      if (mounted) setState(() => _saved = false);
    } catch (e) {
      if (mounted) setState(() { _saving = false; _error = e.toString().split('\n').first; });
    }
  }

  @override
  Widget build(BuildContext context) {
    final pt = widget.pt;
    final clientAsync = ref.watch(matrixClientProvider);
    final client = clientAsync.valueOrNull;

    return SingleChildScrollView(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          _SectionTitle(
              title: 'Mein Profil',
              subtitle: 'Wie du in Pyramid erscheinst.',
              pt: pt),
          // Banner
          GestureDetector(
            onTap: _pickBanner,
            child: Stack(
              children: [
                Container(
                  height: 100,
                  decoration: BoxDecoration(
                    color: pt.bg3,
                    borderRadius: BorderRadius.circular(pt.rBase),
                    border: Border.all(color: pt.border),
                  ),
                  clipBehavior: Clip.hardEdge,
                  child: _pendingBanner != null
                      ? Image.memory(_pendingBanner!, fit: BoxFit.cover, width: double.infinity)
                      : (client != null && _bannerMxcUri != null
                          ? MxcImage(
                              mxcUri: _bannerMxcUri!,
                              client: client,
                              fit: BoxFit.cover,
                              width: double.infinity,
                            )
                          : Center(
                              child: Column(
                                mainAxisSize: MainAxisSize.min,
                                children: [
                                  Icon(Icons.add_photo_alternate_outlined, size: 28, color: pt.fgDim),
                                  const SizedBox(height: 4),
                                  Text('Profilbanner auswählen', style: TextStyle(color: pt.fgDim, fontSize: 12)),
                                ],
                              ),
                            )),
                ),
                Positioned(
                  right: 8,
                  bottom: 8,
                  child: Container(
                    padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                    decoration: BoxDecoration(
                      color: pt.bg0.withAlpha(200),
                      borderRadius: BorderRadius.circular(6),
                      border: Border.all(color: pt.border),
                    ),
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Icon(Icons.edit_rounded, size: 11, color: pt.fgMuted),
                        const SizedBox(width: 4),
                        Text('Banner ändern', style: TextStyle(color: pt.fgMuted, fontSize: 11)),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
          const SizedBox(height: 16),
          // Avatar row
          Row(
            children: [
              GestureDetector(
                onTap: _pickAvatar,
                child: Stack(
                  children: [
                    Container(
                      width: 72,
                      height: 72,
                      decoration: BoxDecoration(
                        shape: BoxShape.circle,
                        border: Border.all(color: pt.border, width: 2),
                      ),
                      child: ClipOval(
                        child: _pendingAvatar != null
                            ? Image.memory(_pendingAvatar!, fit: BoxFit.cover)
                            : (client != null && _avatarUri != null
                                ? MxcAvatar(
                                    mxcUri: _avatarUri,
                                    client: client,
                                    size: 72,
                                    placeholder: (_) => _AvatarFallback(
                                        name: _nameCtrl.text, size: 72, pt: pt),
                                  )
                                : _AvatarFallback(
                                    name: _nameCtrl.text, size: 72, pt: pt)),
                      ),
                    ),
                    Positioned(
                      right: 0,
                      bottom: 0,
                      child: Container(
                        width: 24,
                        height: 24,
                        decoration: BoxDecoration(
                          color: pt.accent,
                          shape: BoxShape.circle,
                          border: Border.all(color: pt.bg1, width: 2),
                        ),
                        child: Icon(Icons.edit_rounded, size: 12, color: pt.accentFg),
                      ),
                    ),
                  ],
                ),
              ),
              const SizedBox(width: 20),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      _nameCtrl.text.isNotEmpty ? _nameCtrl.text : (client?.userID ?? ''),
                      style: TextStyle(
                          color: pt.fg, fontSize: 16, fontWeight: FontWeight.w600),
                    ),
                    const SizedBox(height: 2),
                    SelectableText(
                      client?.userID ?? '',
                      style: TextStyle(color: pt.fgDim, fontSize: 12),
                    ),
                    const SizedBox(height: 6),
                    if (_pendingAvatar != null)
                      Container(
                        padding:
                            const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                        decoration: BoxDecoration(
                          color: pt.accent.withAlpha(40),
                          borderRadius: BorderRadius.circular(6),
                        ),
                        child: Text('Neues Bild ausgewählt',
                            style: TextStyle(color: pt.accent, fontSize: 11)),
                      ),
                  ],
                ),
              ),
            ],
          ),
          const SizedBox(height: 24),
          _SettingsGroup(title: 'Name & Status', pt: pt, children: [
            Padding(
              padding: const EdgeInsets.fromLTRB(14, 14, 14, 4),
              child: _PrefTextField(
                controller: _nameCtrl,
                label: 'Anzeigename',
                pt: pt,
              ),
            ),
            const SizedBox(height: 2),
            Padding(
              padding: const EdgeInsets.fromLTRB(14, 4, 14, 14),
              child: _PrefTextField(
                controller: _statusCtrl,
                label: 'Statusnachricht (optional)',
                pt: pt,
                maxLength: 120,
              ),
            ),
          ]),
          const SizedBox(height: 20),
          if (_error != null)
            Padding(
              padding: const EdgeInsets.only(bottom: 12),
              child: _StatusCard(
                  pt: pt, color: pt.danger, icon: Icons.error_outline_rounded, text: _error!),
            ),
          if (_saved)
            Padding(
              padding: const EdgeInsets.only(bottom: 12),
              child: _StatusCard(
                  pt: pt,
                  color: PyramidColors.success,
                  icon: Icons.check_circle_outline_rounded,
                  text: 'Profil gespeichert.'),
            ),
          _PrimaryBtn(
            label: _saving ? 'Speichern…' : 'Speichern',
            icon: Icons.save_outlined,
            pt: pt,
            loading: _saving,
            onPressed: _save,
          ),
          const SizedBox(height: 24),

          // ── Server-Banner ─────────────────────────────────────────────────
          _SectionTitle(
            title: 'Server-Darstellung',
            subtitle: 'Banner für ${client?.homeserver?.host ?? 'diesen Server'}',
            pt: pt,
          ),
          Consumer(builder: (context, ref, _) {
            final serverBanners = ref.watch(serverBannerProvider).valueOrNull ?? {};
            final homeserver = client?.homeserver.toString();
            final existingMxc = homeserver != null ? serverBanners[homeserver] : null;
            final hasBanner = _pendingServerBanner != null || existingMxc != null;

            return Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                GestureDetector(
                  onTap: _serverBannerSaving ? null : _pickServerBanner,
                  child: Container(
                    height: 90,
                    decoration: BoxDecoration(
                      color: pt.bg3,
                      borderRadius: BorderRadius.circular(pt.rBase),
                      border: Border.all(color: pt.border),
                    ),
                    clipBehavior: Clip.hardEdge,
                    child: Stack(
                      fit: StackFit.expand,
                      children: [
                        if (_pendingServerBanner != null)
                          Image.memory(_pendingServerBanner!, fit: BoxFit.cover,
                              errorBuilder: (_, _, _) => const SizedBox.shrink())
                        else if (existingMxc != null && client != null)
                          MxcImage(mxcUri: existingMxc, client: client, fit: BoxFit.cover)
                        else
                          Center(
                            child: Column(
                              mainAxisSize: MainAxisSize.min,
                              children: [
                                Icon(Icons.add_photo_alternate_outlined, size: 24, color: pt.fgDim),
                                const SizedBox(height: 4),
                                Text('Server-Banner auswählen', style: TextStyle(color: pt.fgDim, fontSize: 12)),
                              ],
                            ),
                          ),
                        if (_serverBannerSaving)
                          Container(
                            color: Colors.black38,
                            child: const Center(child: CircularProgressIndicator(strokeWidth: 2)),
                          ),
                        if (hasBanner)
                          Positioned(
                            right: 8,
                            bottom: 8,
                            child: Container(
                              padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                              decoration: BoxDecoration(
                                color: pt.bg0.withAlpha(200),
                                borderRadius: BorderRadius.circular(6),
                                border: Border.all(color: pt.border),
                              ),
                              child: Row(
                                mainAxisSize: MainAxisSize.min,
                                children: [
                                  Icon(Icons.edit_rounded, size: 11, color: pt.fgMuted),
                                  const SizedBox(width: 4),
                                  Text('Banner ändern', style: TextStyle(color: pt.fgMuted, fontSize: 11)),
                                ],
                              ),
                            ),
                          ),
                      ],
                    ),
                  ),
                ),
                if (hasBanner) ...[
                  const SizedBox(height: 8),
                  GestureDetector(
                    onTap: _removeServerBanner,
                    child: Text(
                      'Banner entfernen',
                      style: TextStyle(color: pt.danger, fontSize: 12),
                    ),
                  ),
                ],
              ],
            );
          }),

          const SizedBox(height: 24),
          _SettingsGroup(title: 'Konto', pt: pt, children: [
            _SettingsRow(
              title: 'Passwort ändern',
              desc: 'Aktuelles Passwort zum Ändern erforderlich',
              pt: pt,
              showArrow: true,
              onTap: _changePassword,
            ),
          ]),
          const SizedBox(height: 12),
          _SettingsGroup(title: 'Gefahrenbereich', pt: pt, children: [
            _SettingsRow(
              title: 'Konto löschen',
              desc: 'Konto dauerhaft deaktivieren – nicht rückgängig zu machen',
              pt: pt,
              showArrow: true,
              destructive: true,
              onTap: _deleteAccount,
            ),
          ]),
        ],
      ),
    );
  }

  Future<void> _changePassword() async {
    await showDialog<void>(
      context: context,
      barrierDismissible: false,
      builder: (ctx) => _ChangePasswordDialog(pt: widget.pt),
    );
  }

  Future<void> _deleteAccount() async {
    await showDialog<void>(
      context: context,
      barrierDismissible: false,
      builder: (ctx) => _DeleteAccountDialog(pt: widget.pt),
    );
  }
}
