import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

import '../services/admin_api.dart';
import 'login_screen.dart';

class DashboardScreen extends StatefulWidget {
  const DashboardScreen({super.key});

  @override
  State<DashboardScreen> createState() => _DashboardScreenState();
}

class _DashboardScreenState extends State<DashboardScreen> {
  int tab = 0;
  bool loading = false;
  Map<String, dynamic> stats = {};
  List<Map<String, dynamic>> users = [];
  List<Map<String, dynamic>> donors = [];
  List<Map<String, dynamic>> donorApplications = [];
  List<Map<String, dynamic>> requests = [];
  List<Map<String, dynamic>> banners = [];
  List<Map<String, dynamic>> districts = [];
  List<Map<String, dynamic>> thanas = [];
  List<Map<String, dynamic>> bloodGroups = [];
  Map<String, dynamic> settings = {};
  final userSearch = TextEditingController();
  final applicationSearch = TextEditingController();
  String userStatus = 'all';
  String applicationStatus = 'pending';

  static const labels = ['Dashboard', 'Users', 'Donors', 'Donor Applications', 'Requests', 'Banners', 'Settings', 'Filter Setup'];
  static const icons = [Icons.dashboard_rounded, Icons.manage_accounts_rounded, Icons.people_alt_rounded, Icons.how_to_reg_rounded, Icons.bloodtype_rounded, Icons.image_rounded, Icons.settings_rounded, Icons.account_tree_rounded];

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

  @override
  void dispose() {
    userSearch.dispose();
    applicationSearch.dispose();
    super.dispose();
  }

  Map<String, dynamic> _map(dynamic v) {
    if (v is Map<String, dynamic>) return v;
    if (v is Map) return v.map((k, val) => MapEntry(k.toString(), val));
    return {};
  }

  List<Map<String, dynamic>> _list(dynamic v) {
    if (v is! List) return [];
    return v.whereType<Map>().map((e) => e.map((k, val) => MapEntry(k.toString(), val))).toList();
  }

  int _id(dynamic value) => int.tryParse('$value') ?? 0;

  Future<void> _loadCatalog() async {
    final results = await Future.wait([
      AdminApi.request('GET', '/admin/districts'),
      AdminApi.request('GET', '/admin/thanas'),
      AdminApi.request('GET', '/admin/blood-groups'),
    ]);
    districts = _list(results[0]['data']);
    thanas = _list(results[1]['data']);
    bloodGroups = _list(results[2]['data']);
  }

  List<Map<String, dynamic>> _thanasForAdmin(int districtId) =>
      thanas.where((t) => _id(t['district_id']) == districtId).toList();

  Future<void> load() async {
    if (mounted) setState(() => loading = true);
    try {
      if (tab == 0) stats = _map((await AdminApi.request('GET', '/admin/dashboard'))['stats']);
      if (tab == 1) {
        final q = Uri.encodeQueryComponent(userSearch.text.trim());
        final status = userStatus == 'all' ? '' : '&status=$userStatus';
        users = _list((await AdminApi.request('GET', '/admin/users?q=$q$status'))['data']);
      }
      if (tab == 2) {
        donors = _list((await AdminApi.request('GET', '/admin/donors'))['data']);
        await _loadCatalog();
      }
      if (tab == 3) {
        final q = Uri.encodeQueryComponent(applicationSearch.text.trim());
        final status = applicationStatus == 'all' ? '' : '&status=$applicationStatus';
        donorApplications = _list((await AdminApi.request('GET', '/admin/donor-applications?q=$q$status'))['data']);
      }
      if (tab == 4) requests = _list((await AdminApi.request('GET', '/admin/requests'))['data']);
      if (tab == 5) banners = _list((await AdminApi.request('GET', '/admin/banners'))['data']);
      if (tab == 6) settings = _map(await AdminApi.request('GET', '/admin/settings'));
      if (tab == 7) await _loadCatalog();
    } on AdminApiException catch (e) {
      if (e.statusCode == 401 && mounted) {
        Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => const LoginScreen()));
        return;
      }
      _snack(e.message, error: true);
    } catch (e) {
      _snack('$e', error: true);
    }
    if (mounted) setState(() => loading = false);
  }

  void _snack(String text, {bool error = false}) {
    if (!mounted) return;
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(text), backgroundColor: error ? Colors.red.shade800 : null));
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        final wide = constraints.maxWidth >= 900;
        return Scaffold(
          appBar: AppBar(
            title: Text('Sadaka Blood Admin • ${labels[tab]}'),
            actions: [
              IconButton(onPressed: load, tooltip: 'Refresh', icon: const Icon(Icons.refresh)),
              IconButton(onPressed: _logout, tooltip: 'Logout', icon: const Icon(Icons.logout)),
              const SizedBox(width: 8),
            ],
          ),
          drawer: wide ? null : Drawer(child: SafeArea(child: _drawerMenu())),
          body: Row(
            children: [
              if (wide) ...[
                NavigationRail(
                  selectedIndex: tab,
                  onDestinationSelected: _selectTab,
                  extended: constraints.maxWidth >= 1180,
                  labelType: constraints.maxWidth >= 1180 ? NavigationRailLabelType.none : NavigationRailLabelType.all,
                  leading: const Padding(
                    padding: EdgeInsets.symmetric(vertical: 18),
                    child: Icon(Icons.bloodtype_rounded, size: 42, color: Color(0xFFC62828)),
                  ),
                  destinations: List.generate(labels.length, (i) => NavigationRailDestination(icon: Icon(icons[i]), label: Text(labels[i]))),
                ),
                const VerticalDivider(width: 1),
              ],
              Expanded(
                child: loading
                    ? const Center(child: CircularProgressIndicator())
                    : Padding(
                        padding: EdgeInsets.all(wide ? 24 : 14),
                        child: _body(),
                      ),
              ),
            ],
          ),
        );
      },
    );
  }

  Widget _drawerMenu() => ListView(
        padding: const EdgeInsets.all(12),
        children: [
          const ListTile(leading: Icon(Icons.bloodtype, color: Color(0xFFC62828)), title: Text('Sadaka Admin', style: TextStyle(fontWeight: FontWeight.w900))),
          const Divider(),
          ...List.generate(labels.length, (i) => ListTile(
                selected: tab == i,
                leading: Icon(icons[i]),
                title: Text(labels[i]),
                onTap: () {
                  Navigator.pop(context);
                  _selectTab(i);
                },
              )),
        ],
      );

  void _selectTab(int i) {
    setState(() => tab = i);
    load();
  }

  Widget _body() {
    switch (tab) {
      case 0:
        return _dashboard();
      case 1:
        return _users();
      case 2:
        return _donors();
      case 3:
        return _donorApplications();
      case 4:
        return _requests();
      case 5:
        return _banners();
      case 6:
        return _settings();
      default:
        return _filterSetup();
    }
  }

  Widget _dashboard() => SingleChildScrollView(
        child: Wrap(
          spacing: 16,
          runSpacing: 16,
          children: stats.entries
              .map((e) => SizedBox(
                    width: 220,
                    height: 126,
                    child: Card(
                      elevation: 0,
                      color: Theme.of(context).colorScheme.surfaceContainerLow,
                      child: Padding(
                        padding: const EdgeInsets.all(20),
                        child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                          Text(e.key.replaceAll('_', ' ').toUpperCase(), style: const TextStyle(color: Colors.black54, fontWeight: FontWeight.w700)),
                          const Spacer(),
                          Text('${e.value}', style: const TextStyle(fontSize: 32, fontWeight: FontWeight.w900)),
                        ]),
                      ),
                    ),
                  ))
              .toList(),
        ),
      );

  Widget _users() {
    return Column(
      children: [
        Wrap(
          spacing: 10,
          runSpacing: 10,
          crossAxisAlignment: WrapCrossAlignment.center,
          children: [
            FilledButton.icon(
              onPressed: _addUser,
              icon: const Icon(Icons.person_add_alt_1_rounded),
              label: const Text('Add User'),
            ),
            SizedBox(
              width: 340,
              child: TextField(
                controller: userSearch,
                onSubmitted: (_) => load(),
                decoration: InputDecoration(
                  hintText: 'Name, phone, email, district...',
                  prefixIcon: const Icon(Icons.search),
                  suffixIcon: IconButton(onPressed: load, icon: const Icon(Icons.arrow_forward)),
                  border: const OutlineInputBorder(),
                ),
              ),
            ),
            SizedBox(
              width: 170,
              child: DropdownButtonFormField<String>(
                value: userStatus,
                decoration: const InputDecoration(labelText: 'Status', border: OutlineInputBorder()),
                items: const [
                  DropdownMenuItem(value: 'all', child: Text('All users')),
                  DropdownMenuItem(value: 'active', child: Text('Active')),
                  DropdownMenuItem(value: 'blocked', child: Text('Banned')),
                ],
                onChanged: (v) {
                  userStatus = v ?? 'all';
                  load();
                },
              ),
            ),
            Text('${users.length} user', style: const TextStyle(fontWeight: FontWeight.w800)),
          ],
        ),
        const SizedBox(height: 14),
        Expanded(
          child: users.isEmpty
              ? const Center(child: Text('No users found'))
              : ListView.separated(
                  itemCount: users.length,
                  separatorBuilder: (_, __) => const SizedBox(height: 8),
                  itemBuilder: (_, i) => _userCard(users[i]),
                ),
        ),
      ],
    );
  }

  Widget _userCard(Map<String, dynamic> u) {
    final active = u['status'] == 'active';
    final verified = u['verified'] == 1 || u['verified'] == '1';
    return Card(
      elevation: 0,
      child: Padding(
        padding: const EdgeInsets.all(14),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            CircleAvatar(
              radius: 26,
              backgroundColor: active ? Colors.green.shade50 : Colors.red.shade50,
              backgroundImage: (u['photo_url'] ?? '').toString().trim().isNotEmpty
                  ? NetworkImage((u['photo_url'] ?? '').toString())
                  : null,
              child: (u['photo_url'] ?? '').toString().trim().isEmpty
                  ? Icon(Icons.person, color: active ? Colors.green : Colors.red)
                  : null,
            ),
            const SizedBox(width: 12),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Wrap(
                    spacing: 7,
                    crossAxisAlignment: WrapCrossAlignment.center,
                    children: [
                      Text((u['name'] ?? '').toString(), style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w900)),
                      if (verified) const Icon(Icons.verified, size: 18, color: Colors.blue),
                      Chip(label: Text(active ? 'ACTIVE' : 'BANNED'), visualDensity: VisualDensity.compact),
                    ],
                  ),
                  const SizedBox(height: 4),
                  Text('${u['phone'] ?? ''}${(u['email'] ?? '').toString().isNotEmpty ? ' • ${u['email']}' : ''}'),
                  Text('${u['blood_group'] ?? '-'} • ${u['district'] ?? '-'}', style: const TextStyle(color: Colors.black54)),
                  const SizedBox(height: 3),
                  Text('Joined: ${u['created_at'] ?? '-'}  •  Last login: ${u['last_login_at'] ?? '-'}', style: const TextStyle(fontSize: 12, color: Colors.black45)),
                ],
              ),
            ),
            PopupMenuButton<String>(
              tooltip: 'User actions',
              onSelected: (action) => _userAction(action, u),
              itemBuilder: (_) => [
                const PopupMenuItem(value: 'edit', child: ListTile(leading: Icon(Icons.edit), title: Text('Edit user'))),
                PopupMenuItem(value: 'status', child: ListTile(leading: Icon(active ? Icons.block : Icons.check_circle), title: Text(active ? 'Ban user' : 'Unban user'))),
                PopupMenuItem(value: 'verify', child: ListTile(leading: Icon(verified ? Icons.verified_outlined : Icons.verified), title: Text(verified ? 'Remove verification' : 'Verify user'))),
                const PopupMenuItem(value: 'password', child: ListTile(leading: Icon(Icons.password), title: Text('Reset password'))),
                const PopupMenuDivider(),
                const PopupMenuItem(value: 'delete', child: ListTile(leading: Icon(Icons.delete_forever, color: Colors.red), title: Text('Delete user', style: TextStyle(color: Colors.red)))),
              ],
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _userAction(String action, Map<String, dynamic> u) async {
    final id = u['id'];
    try {
      if (action == 'status') {
        await AdminApi.request('PUT', '/admin/users/$id', body: {'status': u['status'] == 'active' ? 'blocked' : 'active'});
        _snack(u['status'] == 'active' ? 'User banned' : 'User unbanned');
      } else if (action == 'verify') {
        final verified = u['verified'] == 1 || u['verified'] == '1';
        await AdminApi.request('PUT', '/admin/users/$id', body: {'verified': !verified});
        _snack('Verification updated');
      } else if (action == 'edit') {
        await _editUser(u);
      } else if (action == 'password') {
        await _resetPassword(u);
      } else if (action == 'delete') {
        final ok = await showDialog<bool>(
          context: context,
          builder: (ctx) => AlertDialog(
            title: const Text('Delete user?'),
            content: Text('${u['name']} এর account, donor application এবং linked donor record permanently delete হবে।'),
            actions: [TextButton(onPressed: () => Navigator.pop(ctx, false), child: const Text('Cancel')), FilledButton(onPressed: () => Navigator.pop(ctx, true), child: const Text('Delete'))],
          ),
        );
        if (ok == true) {
          await AdminApi.request('DELETE', '/admin/users/$id');
          _snack('User deleted');
        }
      }
      await load();
    } catch (e) {
      _snack('$e', error: true);
    }
  }

  Future<void> _addUser() async {
    final n = TextEditingController();
    final p = TextEditingController();
    final e = TextEditingController();
    final pass = TextEditingController();
    final d = TextEditingController();
    String group = '';
    String status = 'active';
    bool verified = false;

    final saved = await showDialog<bool>(
      context: context,
      builder: (ctx) => StatefulBuilder(
        builder: (ctx, setDialogState) => AlertDialog(
          title: const Text('Add User'),
          content: SizedBox(
            width: 480,
            child: SingleChildScrollView(
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  TextField(controller: n, decoration: const InputDecoration(labelText: 'Name *')),
                  TextField(controller: p, keyboardType: TextInputType.phone, decoration: const InputDecoration(labelText: 'Phone *')),
                  TextField(controller: e, keyboardType: TextInputType.emailAddress, decoration: const InputDecoration(labelText: 'Email')),
                  TextField(controller: pass, obscureText: true, decoration: const InputDecoration(labelText: 'Password * (minimum 6 characters)')),
                  DropdownButtonFormField<String>(
                    value: group.isEmpty ? null : group,
                    decoration: const InputDecoration(labelText: 'Blood group'),
                    items: ['A+','A-','B+','B-','AB+','AB-','O+','O-'].map((x) => DropdownMenuItem(value: x, child: Text(x))).toList(),
                    onChanged: (v) => setDialogState(() => group = v ?? ''),
                  ),
                  TextField(controller: d, decoration: const InputDecoration(labelText: 'District')),
                  DropdownButtonFormField<String>(
                    value: status,
                    decoration: const InputDecoration(labelText: 'Account status'),
                    items: const [
                      DropdownMenuItem(value: 'active', child: Text('Active')),
                      DropdownMenuItem(value: 'blocked', child: Text('Banned')),
                    ],
                    onChanged: (v) => setDialogState(() => status = v ?? 'active'),
                  ),
                  SwitchListTile.adaptive(
                    contentPadding: EdgeInsets.zero,
                    title: const Text('Verified user'),
                    value: verified,
                    onChanged: (v) => setDialogState(() => verified = v),
                  ),
                ],
              ),
            ),
          ),
          actions: [
            TextButton(onPressed: () => Navigator.pop(ctx, false), child: const Text('Cancel')),
            FilledButton.icon(
              icon: const Icon(Icons.person_add_alt_1_rounded),
              onPressed: () async {
                if (n.text.trim().isEmpty || p.text.trim().isEmpty || pass.text.length < 6) {
                  _snack('Name, phone এবং minimum 6 character password দিন', error: true);
                  return;
                }
                try {
                  await AdminApi.request('POST', '/admin/users', body: {
                    'name': n.text.trim(),
                    'phone': p.text.trim(),
                    'email': e.text.trim(),
                    'password': pass.text,
                    'blood_group': group,
                    'district': d.text.trim(),
                    'status': status,
                    'verified': verified,
                  });
                  if (ctx.mounted) Navigator.pop(ctx, true);
                } catch (err) {
                  _snack('$err', error: true);
                }
              },
              label: const Text('Create User'),
            ),
          ],
        ),
      ),
    );

    n.dispose(); p.dispose(); e.dispose(); pass.dispose(); d.dispose();
    if (saved == true) {
      _snack('User created successfully');
      await load();
    }
  }

  Future<void> _editUser(Map<String, dynamic> u) async {
    final n = TextEditingController(text: (u['name'] ?? '').toString());
    final p = TextEditingController(text: (u['phone'] ?? '').toString());
    final e = TextEditingController(text: (u['email'] ?? '').toString());
    final d = TextEditingController(text: (u['district'] ?? '').toString());
    String group = (u['blood_group'] ?? '').toString();
    String status = (u['status'] ?? 'active').toString() == 'blocked' ? 'blocked' : 'active';
    bool verified = u['verified'] == 1 || u['verified'] == '1' || u['verified'] == true;

    final saved = await showDialog<bool>(
      context: context,
      builder: (ctx) => StatefulBuilder(
        builder: (ctx, setDialogState) => AlertDialog(
          title: Text('Edit User • ${u['name'] ?? ''}'),
          content: SizedBox(
            width: 480,
            child: SingleChildScrollView(
              child: Column(mainAxisSize: MainAxisSize.min, children: [
                TextField(controller: n, decoration: const InputDecoration(labelText: 'Name *')),
                TextField(controller: p, keyboardType: TextInputType.phone, decoration: const InputDecoration(labelText: 'Phone *')),
                TextField(controller: e, keyboardType: TextInputType.emailAddress, decoration: const InputDecoration(labelText: 'Email')),
                TextField(controller: d, decoration: const InputDecoration(labelText: 'District')),
                DropdownButtonFormField<String>(
                  value: group.isEmpty ? null : group,
                  decoration: const InputDecoration(labelText: 'Blood group'),
                  items: ['A+','A-','B+','B-','AB+','AB-','O+','O-'].map((x) => DropdownMenuItem(value: x, child: Text(x))).toList(),
                  onChanged: (v) => setDialogState(() => group = v ?? ''),
                ),
                DropdownButtonFormField<String>(
                  value: status,
                  decoration: const InputDecoration(labelText: 'Account status'),
                  items: const [
                    DropdownMenuItem(value: 'active', child: Text('Active')),
                    DropdownMenuItem(value: 'blocked', child: Text('Banned')),
                  ],
                  onChanged: (v) => setDialogState(() => status = v ?? 'active'),
                ),
                SwitchListTile.adaptive(
                  contentPadding: EdgeInsets.zero,
                  title: const Text('Verified user'),
                  value: verified,
                  onChanged: (v) => setDialogState(() => verified = v),
                ),
              ]),
            ),
          ),
          actions: [
            TextButton(onPressed: () => Navigator.pop(ctx, false), child: const Text('Cancel')),
            FilledButton(
              onPressed: () async {
                if (n.text.trim().isEmpty || p.text.trim().isEmpty) {
                  _snack('Name এবং phone required', error: true);
                  return;
                }
                try {
                  await AdminApi.request('PUT', '/admin/users/${u['id']}', body: {
                    'name': n.text.trim(),
                    'phone': p.text.trim(),
                    'email': e.text.trim(),
                    'district': d.text.trim(),
                    'blood_group': group,
                    'status': status,
                    'verified': verified,
                  });
                  if (ctx.mounted) Navigator.pop(ctx, true);
                } catch (err) {
                  _snack('$err', error: true);
                }
              },
              child: const Text('Save Changes'),
            ),
          ],
        ),
      ),
    );
    n.dispose(); p.dispose(); e.dispose(); d.dispose();
    if (saved == true) _snack('User updated');
  }

  Future<void> _resetPassword(Map<String, dynamic> u) async {
    final p = TextEditingController();
    final done = await showDialog<bool>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: Text('Reset password • ${u['name']}'),
        content: TextField(controller: p, obscureText: true, decoration: const InputDecoration(labelText: 'New password (6+ characters)')),
        actions: [
          TextButton(onPressed: () => Navigator.pop(ctx, false), child: const Text('Cancel')),
          FilledButton(
            onPressed: () async {
              if (p.text.length < 6) return;
              try {
                await AdminApi.request('POST', '/admin/users/${u['id']}/reset-password', body: {'password': p.text});
                if (ctx.mounted) Navigator.pop(ctx, true);
              } catch (err) {
                _snack('$err', error: true);
              }
            },
            child: const Text('Reset'),
          ),
        ],
      ),
    );
    p.dispose();
    if (done == true) _snack('Password reset. User must login again.');
  }

  Widget _donors() => Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Wrap(
            spacing: 10,
            runSpacing: 10,
            children: [
              FilledButton.icon(onPressed: _addDonor, icon: const Icon(Icons.add), label: const Text('Add Donor')),
              OutlinedButton.icon(onPressed: () => _selectTab(7), icon: const Icon(Icons.account_tree_rounded), label: const Text('District / Thana / Blood Group')),
            ],
          ),
          const SizedBox(height: 16),
          Expanded(
            child: SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              child: DataTable(
                columns: const [
                  DataColumn(label: Text('Photo')),
                  DataColumn(label: Text('Name')),
                  DataColumn(label: Text('Group')),
                  DataColumn(label: Text('District')),
                  DataColumn(label: Text('Thana')),
                  DataColumn(label: Text('Phone')),
                  DataColumn(label: Text('Verified')),
                  DataColumn(label: Text('View')),
                ],
                rows: donors
                    .map((d) => DataRow(cells: [
                          DataCell(CircleAvatar(
                            radius: 18,
                            backgroundColor: Colors.red.shade50,
                            backgroundImage: (d['photo_url'] ?? '').toString().trim().isNotEmpty
                                ? NetworkImage((d['photo_url'] ?? '').toString())
                                : null,
                            child: (d['photo_url'] ?? '').toString().trim().isEmpty
                                ? const Icon(Icons.person, size: 18)
                                : null,
                          )),
                          DataCell(Text((d['name'] ?? '').toString())),
                          DataCell(Text((d['blood_group'] ?? '').toString())),
                          DataCell(Text((d['district'] ?? '').toString())),
                          DataCell(Text((d['upazila'] ?? '').toString())),
                          DataCell(Text((d['phone'] ?? '').toString())),
                          DataCell(Icon(
                            (d['verified'] == 1 || d['verified'] == '1') ? Icons.verified : Icons.circle_outlined,
                            color: (d['verified'] == 1 || d['verified'] == '1') ? Colors.green : Colors.grey,
                          )),
                          DataCell(IconButton(
                            tooltip: 'View all details',
                            onPressed: () => _showDonorDetails(d),
                            icon: const Icon(Icons.visibility_outlined),
                          )),
                        ]))
                    .toList(),
              ),
            ),
          ),
        ],
      );

  Future<void> _showDonorDetails(Map<String, dynamic> d) async {
    final photo = (d['photo_url'] ?? '').toString().trim();
    final verified = d['verified'] == 1 || d['verified'] == '1';
    final available = d['available'] == 1 || d['available'] == '1';
    await showDialog<void>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text('Donor details'),
        content: SizedBox(
          width: 520,
          child: SingleChildScrollView(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisSize: MainAxisSize.min,
              children: [
                Center(
                  child: CircleAvatar(
                    radius: 44,
                    backgroundColor: Colors.red.shade50,
                    backgroundImage: photo.isNotEmpty ? NetworkImage(photo) : null,
                    child: photo.isEmpty ? const Icon(Icons.person, size: 46) : null,
                  ),
                ),
                const SizedBox(height: 16),
                _detailLine('ID', '#${d['id'] ?? '-'}'),
                _detailLine('Name', d['name']),
                _detailLine('Phone', d['phone']),
                _detailLine('Blood group', d['blood_group']),
                _detailLine('District', d['district']),
                _detailLine('Thana / Upazila', d['upazila']),
                _detailLine('Address', d['address']),
                _detailLine('Last donation', d['last_donation_date']),
                _detailLine('Available', available ? 'Yes' : 'No'),
                _detailLine('Verified', verified ? 'Yes' : 'No'),
                _detailLine('Created', d['created_at']),
                if (photo.isNotEmpty) _detailLine('Photo URL', photo),
              ],
            ),
          ),
        ),
        actions: [
          FilledButton(onPressed: () => Navigator.pop(ctx), child: const Text('Close')),
        ],
      ),
    );
  }

  Widget _detailLine(String label, dynamic value) {
    final text = (value ?? '').toString().trim();
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 7),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(width: 130, child: Text(label, style: const TextStyle(fontWeight: FontWeight.w800))),
          Expanded(child: SelectableText(text.isEmpty ? '-' : text)),
        ],
      ),
    );
  }

  Widget _donorApplications() {
    Color statusColor(String value) {
      switch (value) {
        case 'approved':
          return Colors.green.shade700;
        case 'rejected':
          return Colors.red.shade700;
        default:
          return Colors.orange.shade800;
      }
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Wrap(
          spacing: 10,
          runSpacing: 10,
          crossAxisAlignment: WrapCrossAlignment.center,
          children: [
            SizedBox(
              width: 330,
              child: TextField(
                controller: applicationSearch,
                onSubmitted: (_) => load(),
                decoration: InputDecoration(
                  hintText: 'Name, phone, district, thana, group...',
                  prefixIcon: const Icon(Icons.search),
                  suffixIcon: IconButton(onPressed: load, icon: const Icon(Icons.arrow_forward)),
                  border: const OutlineInputBorder(),
                ),
              ),
            ),
            SizedBox(
              width: 180,
              child: DropdownButtonFormField<String>(
                value: applicationStatus,
                decoration: const InputDecoration(labelText: 'Application status', border: OutlineInputBorder()),
                items: const [
                  DropdownMenuItem(value: 'pending', child: Text('Pending')),
                  DropdownMenuItem(value: 'approved', child: Text('Approved')),
                  DropdownMenuItem(value: 'rejected', child: Text('Rejected')),
                  DropdownMenuItem(value: 'all', child: Text('All')),
                ],
                onChanged: (v) {
                  applicationStatus = v ?? 'pending';
                  load();
                },
              ),
            ),
            Text('${donorApplications.length} application', style: const TextStyle(fontWeight: FontWeight.w800)),
          ],
        ),
        const SizedBox(height: 14),
        Expanded(
          child: donorApplications.isEmpty
              ? const Center(child: Text('No donor application found'))
              : ListView.separated(
                  itemCount: donorApplications.length,
                  separatorBuilder: (_, __) => const SizedBox(height: 10),
                  itemBuilder: (_, i) {
                    final a = donorApplications[i];
                    final status = (a['status'] ?? 'pending').toString();
                    final color = statusColor(status);
                    final photo = (a['photo_url'] ?? '').toString().trim();
                    return Card(
                      elevation: 0,
                      child: Padding(
                        padding: const EdgeInsets.all(14),
                        child: Row(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            CircleAvatar(
                              radius: 30,
                              backgroundColor: Colors.red.shade50,
                              backgroundImage: photo.isNotEmpty ? NetworkImage(photo) : null,
                              child: photo.isEmpty ? const Icon(Icons.person, size: 30) : null,
                            ),
                            const SizedBox(width: 14),
                            Expanded(
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Wrap(
                                    spacing: 8,
                                    runSpacing: 6,
                                    crossAxisAlignment: WrapCrossAlignment.center,
                                    children: [
                                      Text((a['name'] ?? '').toString(), style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w900)),
                                      Container(
                                        padding: const EdgeInsets.symmetric(horizontal: 9, vertical: 4),
                                        decoration: BoxDecoration(color: color.withAlpha(24), borderRadius: BorderRadius.circular(20)),
                                        child: Text(status.toUpperCase(), style: TextStyle(color: color, fontSize: 11, fontWeight: FontWeight.w900)),
                                      ),
                                    ],
                                  ),
                                  const SizedBox(height: 6),
                                  Text('${a['blood_group'] ?? '-'}  •  ${a['phone'] ?? '-'}  •  ${a['district'] ?? '-'} > ${a['upazila'] ?? '-'}'),
                                  if ((a['address'] ?? '').toString().trim().isNotEmpty)
                                    Padding(
                                      padding: const EdgeInsets.only(top: 3),
                                      child: Text('Address: ${a['address']}', style: const TextStyle(color: Colors.black54)),
                                    ),
                                  Padding(
                                    padding: const EdgeInsets.only(top: 3),
                                    child: Text('Last donation: ${a['last_donation_date'] ?? '-'}  •  Available: ${(a['available'] == 1 || a['available'] == '1') ? 'Yes' : 'No'}', style: const TextStyle(color: Colors.black54)),
                                  ),
                                  if ((a['admin_note'] ?? '').toString().trim().isNotEmpty)
                                    Padding(
                                      padding: const EdgeInsets.only(top: 4),
                                      child: Text('Admin note: ${a['admin_note']}', style: TextStyle(color: color)),
                                    ),
                                  const SizedBox(height: 10),
                                  Wrap(
                                    spacing: 8,
                                    runSpacing: 8,
                                    children: [
                                      OutlinedButton.icon(
                                        onPressed: () => _showApplicationDetails(a),
                                        icon: const Icon(Icons.visibility_outlined),
                                        label: const Text('View details'),
                                      ),
                                      if (status != 'approved')
                                        FilledButton.icon(
                                          style: FilledButton.styleFrom(backgroundColor: Colors.green.shade700),
                                          onPressed: () => _reviewDonorApplication(a, 'approved'),
                                          icon: const Icon(Icons.check_circle_outline),
                                          label: const Text('Approve'),
                                        ),
                                      if (status != 'rejected')
                                        OutlinedButton.icon(
                                          style: OutlinedButton.styleFrom(foregroundColor: Colors.red.shade700),
                                          onPressed: () => _reviewDonorApplication(a, 'rejected'),
                                          icon: const Icon(Icons.cancel_outlined),
                                          label: const Text('Reject'),
                                        ),
                                    ],
                                  ),
                                ],
                              ),
                            ),
                          ],
                        ),
                      ),
                    );
                  },
                ),
        ),
      ],
    );
  }

  Future<void> _showApplicationDetails(Map<String, dynamic> a) async {
    await showDialog<void>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text('Donor application details'),
        content: SizedBox(
          width: 540,
          child: SingleChildScrollView(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisSize: MainAxisSize.min,
              children: [
                _detailLine('Application ID', '#${a['id'] ?? '-'}'),
                _detailLine('User ID', '#${a['user_id'] ?? '-'}'),
                _detailLine('Name', a['name']),
                _detailLine('Phone', a['phone']),
                _detailLine('Email', a['email']),
                _detailLine('Blood group', a['blood_group']),
                _detailLine('District', a['district']),
                _detailLine('Thana / Upazila', a['upazila']),
                _detailLine('Address', a['address']),
                _detailLine('Last donation', a['last_donation_date']),
                _detailLine('Available', (a['available'] == 1 || a['available'] == '1') ? 'Yes' : 'No'),
                _detailLine('Status', a['status']),
                _detailLine('Admin note', a['admin_note']),
                _detailLine('Submitted', a['created_at']),
                _detailLine('Updated', a['updated_at']),
                _detailLine('Reviewed', a['reviewed_at']),
              ],
            ),
          ),
        ),
        actions: [FilledButton(onPressed: () => Navigator.pop(ctx), child: const Text('Close'))],
      ),
    );
  }

  Future<void> _reviewDonorApplication(Map<String, dynamic> a, String status) async {
    final note = TextEditingController(text: (a['admin_note'] ?? '').toString());
    final approved = status == 'approved';
    final ok = await showDialog<bool>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: Text(approved ? 'Approve donor?' : 'Reject donor application?'),
        content: SizedBox(
          width: 440,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('${a['name']} • ${a['blood_group']} • ${a['district']} > ${a['upazila']}'),
              const SizedBox(height: 14),
              TextField(
                controller: note,
                maxLines: 3,
                decoration: InputDecoration(
                  labelText: approved ? 'Admin note (optional)' : 'Rejection reason / note',
                  border: const OutlineInputBorder(),
                ),
              ),
              if (approved) ...[
                const SizedBox(height: 12),
                const Text('Approve করলে user সাথে সাথে Donor List-এ চলে যাবে।', style: TextStyle(color: Colors.green, fontWeight: FontWeight.w700)),
              ],
            ],
          ),
        ),
        actions: [
          TextButton(onPressed: () => Navigator.pop(ctx, false), child: const Text('Cancel')),
          FilledButton(
            style: FilledButton.styleFrom(backgroundColor: approved ? Colors.green.shade700 : Colors.red.shade700),
            onPressed: () => Navigator.pop(ctx, true),
            child: Text(approved ? 'Approve' : 'Reject'),
          ),
        ],
      ),
    );
    if (ok == true) {
      try {
        final result = await AdminApi.request('PUT', '/admin/donor-applications/${a['id']}', body: {
          'status': status,
          'admin_note': note.text.trim(),
        });
        _snack((result['message'] ?? 'Updated').toString());
        await load();
      } catch (e) {
        _snack('$e', error: true);
      }
    }
    note.dispose();
  }

  Widget _requests() => ListView.separated(
        itemCount: requests.length,
        separatorBuilder: (_, __) => const SizedBox(height: 10),
        itemBuilder: (_, i) {
          final r = requests[i];
          return Card(
            elevation: 0,
            child: ListTile(
              title: Text('${r['blood_group']} • ${r['patient_problem']}', style: const TextStyle(fontWeight: FontWeight.w800)),
              subtitle: Text('${r['hospital']}\n${r['contact_phone']} • ${r['donation_date']}\nUser: ${r['user_name'] ?? 'Unknown'} ${r['user_phone'] ?? ''}'),
              isThreeLine: false,
              trailing: DropdownButton<String>(
                value: (r['status'] ?? 'pending').toString(),
                items: ['pending','approved','completed','cancelled'].map((s) => DropdownMenuItem(value: s, child: Text(s))).toList(),
                onChanged: (v) async {
                  if (v == null) return;
                  await AdminApi.request('PUT', '/admin/requests/${r['id']}', body: {'status': v});
                  load();
                },
              ),
            ),
          );
        },
      );

  Widget _banners() => Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Wrap(
            spacing: 10,
            runSpacing: 8,
            crossAxisAlignment: WrapCrossAlignment.center,
            children: [
              FilledButton.icon(
                onPressed: _addBanner,
                icon: const Icon(Icons.add_photo_alternate_rounded),
                label: const Text('Add Banner'),
              ),
              const Text(
                'Home page-এর নির্দিষ্ট banner slot-এ প্রথম Active banner দেখাবে। Banner-টি clickable নয়।',
                style: TextStyle(color: Colors.black54, fontSize: 12),
              ),
            ],
          ),
          const SizedBox(height: 16),
          Expanded(
            child: banners.isEmpty
                ? const Center(child: Text('কোনো banner নেই। Add Banner থেকে image upload করুন।'))
                : ListView.separated(
                    itemCount: banners.length,
                    separatorBuilder: (_, __) => const SizedBox(height: 10),
                    itemBuilder: (_, i) {
                      final b = banners[i];
                      final imageUrl = (b['image_url'] ?? '').toString().trim();
                      final active = '${b['is_active']}' == '1' || b['is_active'] == true;
                      return Card(
                        elevation: 0,
                        clipBehavior: Clip.antiAlias,
                        child: Padding(
                          padding: const EdgeInsets.all(10),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              AspectRatio(
                                aspectRatio: 679 / 461,
                                child: ClipRRect(
                                  borderRadius: BorderRadius.circular(12),
                                  child: imageUrl.isEmpty
                                      ? Container(
                                          color: const Color(0xFFFFEEEE),
                                          alignment: Alignment.center,
                                          child: const Icon(Icons.image_not_supported_outlined),
                                        )
                                      : Image.network(
                                          imageUrl,
                                          fit: BoxFit.cover,
                                          errorBuilder: (_, __, ___) => Container(
                                            color: const Color(0xFFFFEEEE),
                                            alignment: Alignment.center,
                                            child: const Icon(Icons.broken_image_outlined),
                                          ),
                                        ),
                                ),
                              ),
                              const SizedBox(height: 10),
                              Row(
                                children: [
                                  Expanded(
                                    child: Column(
                                      crossAxisAlignment: CrossAxisAlignment.start,
                                      children: [
                                        Text(
                                          (b['title'] ?? 'Banner').toString().isEmpty
                                              ? 'Banner'
                                              : (b['title'] ?? '').toString(),
                                          style: const TextStyle(fontWeight: FontWeight.w800),
                                        ),
                                        if ((b['subtitle'] ?? '').toString().trim().isNotEmpty)
                                          Text((b['subtitle'] ?? '').toString(), style: const TextStyle(color: Colors.black54)),
                                      ],
                                    ),
                                  ),
                                  Switch(
                                    value: active,
                                    onChanged: (value) async {
                                      try {
                                        await AdminApi.request(
                                          'PUT',
                                          '/admin/banners/${b['id']}',
                                          body: {'is_active': value},
                                        );
                                        await load();
                                      } catch (e) {
                                        _snack('$e', error: true);
                                      }
                                    },
                                  ),
                                  IconButton(
                                    tooltip: 'Delete',
                                    icon: const Icon(Icons.delete_outline_rounded),
                                    onPressed: () async {
                                      try {
                                        await AdminApi.request('DELETE', '/admin/banners/${b['id']}');
                                        await load();
                                      } catch (e) {
                                        _snack('$e', error: true);
                                      }
                                    },
                                  ),
                                ],
                              ),
                            ],
                          ),
                        ),
                      );
                    },
                  ),
          ),
        ],
      );

  Widget _settings() {
    final name = TextEditingController(text: (settings['organization_name'] ?? '').toString());
    final tag = TextEditingController(text: (settings['tagline'] ?? '').toString());
    final phone = TextEditingController(text: (settings['emergency_phone'] ?? '').toString());
    return SingleChildScrollView(
      child: ConstrainedBox(
        constraints: const BoxConstraints(maxWidth: 700),
        child: Column(children: [
          TextField(controller: name, decoration: const InputDecoration(labelText: 'Organization name', border: OutlineInputBorder())),
          const SizedBox(height: 12),
          TextField(controller: tag, decoration: const InputDecoration(labelText: 'Tagline', border: OutlineInputBorder())),
          const SizedBox(height: 12),
          TextField(controller: phone, decoration: const InputDecoration(labelText: 'Emergency phone', border: OutlineInputBorder())),
          const SizedBox(height: 20),
          FilledButton(
            onPressed: () async {
              await AdminApi.request('PUT', '/admin/settings', body: {'organization_name': name.text, 'tagline': tag.text, 'emergency_phone': phone.text, 'primary_color': '#C62828'});
              _snack('Settings saved');
            },
            child: const Text('Save Settings'),
          ),
        ]),
      ),
    );
  }

  Future<void> _addDonor() async {
    if (districts.isEmpty || bloodGroups.isEmpty) {
      await _loadCatalog();
      if (mounted) setState(() {});
    }
    if (districts.isEmpty || bloodGroups.isEmpty) {
      _snack('আগে Filter Setup থেকে জেলা, থানা ও রক্তের গ্রুপ যোগ করুন।', error: true);
      return;
    }

    final n = TextEditingController();
    final p = TextEditingController();
    int districtId = 0;
    int thanaId = 0;
    int bloodGroupId = 0;

    await showDialog(
      context: context,
      builder: (ctx) => StatefulBuilder(
        builder: (context, setDialogState) {
          final localThanas = _thanasForAdmin(districtId);
          return AlertDialog(
            title: const Text('Add donor'),
            content: SizedBox(
              width: 440,
              child: SingleChildScrollView(
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    TextField(controller: n, decoration: const InputDecoration(labelText: 'Name')),
                    TextField(controller: p, decoration: const InputDecoration(labelText: 'Phone')),
                    const SizedBox(height: 10),
                    DropdownButtonFormField<int>(
                      value: districtId == 0 ? null : districtId,
                      isExpanded: true,
                      items: districts.map((d) => DropdownMenuItem(value: _id(d['id']), child: Text((d['name'] ?? '').toString()))).toList(),
                      onChanged: (v) => setDialogState(() {
                        districtId = v ?? 0;
                        thanaId = 0;
                      }),
                      decoration: const InputDecoration(labelText: 'District', border: OutlineInputBorder()),
                    ),
                    const SizedBox(height: 10),
                    DropdownButtonFormField<int>(
                      value: thanaId == 0 ? null : thanaId,
                      isExpanded: true,
                      items: localThanas.map((t) => DropdownMenuItem(value: _id(t['id']), child: Text((t['name'] ?? '').toString()))).toList(),
                      onChanged: districtId == 0 ? null : (v) => setDialogState(() => thanaId = v ?? 0),
                      decoration: const InputDecoration(labelText: 'Thana', border: OutlineInputBorder()),
                    ),
                    const SizedBox(height: 10),
                    DropdownButtonFormField<int>(
                      value: bloodGroupId == 0 ? null : bloodGroupId,
                      isExpanded: true,
                      items: bloodGroups.map((g) => DropdownMenuItem(value: _id(g['id']), child: Text((g['name'] ?? '').toString()))).toList(),
                      onChanged: (v) => setDialogState(() => bloodGroupId = v ?? 0),
                      decoration: const InputDecoration(labelText: 'Blood group', border: OutlineInputBorder()),
                    ),
                  ],
                ),
              ),
            ),
            actions: [
              TextButton(onPressed: () => Navigator.pop(ctx), child: const Text('Cancel')),
              FilledButton(
                onPressed: () async {
                  if (n.text.trim().isEmpty || p.text.trim().isEmpty || districtId == 0 || thanaId == 0 || bloodGroupId == 0) {
                    _snack('Name, phone, district, thana and blood group are required', error: true);
                    return;
                  }
                  try {
                    await AdminApi.request('POST', '/admin/donors', body: {
                      'name': n.text,
                      'phone': p.text,
                      'district_id': districtId,
                      'thana_id': thanaId,
                      'blood_group_id': bloodGroupId,
                      'available': true,
                      'verified': true,
                    });
                    if (ctx.mounted) Navigator.pop(ctx);
                    await load();
                  } catch (e) {
                    _snack('$e', error: true);
                  }
                },
                child: const Text('Save'),
              ),
            ],
          );
        },
      ),
    );
    n.dispose();
    p.dispose();
  }

  Widget _filterSetup() {
    Widget section(String title, Widget child, VoidCallback onAdd) {
      return Card(
        elevation: 0,
        child: Padding(
          padding: const EdgeInsets.all(16),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                children: [
                  Expanded(child: Text(title, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w900))),
                  FilledButton.icon(onPressed: onAdd, icon: const Icon(Icons.add), label: const Text('Add')),
                ],
              ),
              const SizedBox(height: 12),
              child,
            ],
          ),
        ),
      );
    }

    return SingleChildScrollView(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Text('Donor Search Filter Setup', style: TextStyle(fontSize: 24, fontWeight: FontWeight.w900)),
          const SizedBox(height: 6),
          const Text('এখান থেকে জেলা, জেলার অধীনে থানা এবং রক্তের গ্রুপ যোগ করুন। User app এই ডাটাই filter হিসেবে দেখাবে।'),
          const SizedBox(height: 18),
          section(
            'Districts',
            districts.isEmpty
                ? const Text('No district added')
                : Wrap(
                    spacing: 8,
                    runSpacing: 8,
                    children: districts.map((d) => InputChip(
                      label: Text((d['name'] ?? '').toString()),
                      onDeleted: () => _deleteCatalog('districts', _id(d['id'])),
                    )).toList(),
                  ),
            _addDistrict,
          ),
          const SizedBox(height: 12),
          section(
            'Thanas',
            thanas.isEmpty
                ? const Text('No thana added')
                : Column(
                    children: thanas.map((t) => ListTile(
                      dense: true,
                      leading: const Icon(Icons.account_balance_rounded),
                      title: Text((t['name'] ?? '').toString()),
                      subtitle: Text((t['district_name'] ?? '').toString()),
                      trailing: IconButton(icon: const Icon(Icons.delete_outline), onPressed: () => _deleteCatalog('thanas', _id(t['id']))),
                    )).toList(),
                  ),
            _addThana,
          ),
          const SizedBox(height: 12),
          section(
            'Blood Groups',
            bloodGroups.isEmpty
                ? const Text('No blood group added')
                : Wrap(
                    spacing: 8,
                    runSpacing: 8,
                    children: bloodGroups.map((g) => InputChip(
                      avatar: const Icon(Icons.bloodtype_rounded, size: 18),
                      label: Text((g['name'] ?? '').toString()),
                      onDeleted: () => _deleteCatalog('blood-groups', _id(g['id'])),
                    )).toList(),
                  ),
            _addBloodGroup,
          ),
        ],
      ),
    );
  }

  Future<void> _addDistrict() async {
    final c = TextEditingController();
    final ok = await showDialog<bool>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text('Add district'),
        content: TextField(controller: c, autofocus: true, decoration: const InputDecoration(labelText: 'District name', border: OutlineInputBorder())),
        actions: [
          TextButton(onPressed: () => Navigator.pop(ctx, false), child: const Text('Cancel')),
          FilledButton(onPressed: () => Navigator.pop(ctx, true), child: const Text('Add')),
        ],
      ),
    );
    if (ok == true && c.text.trim().isNotEmpty) {
      try {
        await AdminApi.request('POST', '/admin/districts', body: {'name': c.text.trim()});
        await load();
      } catch (e) {
        _snack('$e', error: true);
      }
    }
    c.dispose();
  }

  Future<void> _addThana() async {
    if (districts.isEmpty) {
      _snack('আগে একটি district যোগ করুন।', error: true);
      return;
    }
    final c = TextEditingController();
    int districtId = _id(districts.first['id']);
    final ok = await showDialog<bool>(
      context: context,
      builder: (ctx) => StatefulBuilder(
        builder: (context, setDialogState) => AlertDialog(
          title: const Text('Add thana'),
          content: SizedBox(
            width: 420,
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                DropdownButtonFormField<int>(
                  value: districtId,
                  isExpanded: true,
                  items: districts.map((d) => DropdownMenuItem(value: _id(d['id']), child: Text((d['name'] ?? '').toString()))).toList(),
                  onChanged: (v) => setDialogState(() => districtId = v ?? districtId),
                  decoration: const InputDecoration(labelText: 'District', border: OutlineInputBorder()),
                ),
                const SizedBox(height: 12),
                TextField(controller: c, autofocus: true, decoration: const InputDecoration(labelText: 'Thana name', border: OutlineInputBorder())),
              ],
            ),
          ),
          actions: [
            TextButton(onPressed: () => Navigator.pop(ctx, false), child: const Text('Cancel')),
            FilledButton(onPressed: () => Navigator.pop(ctx, true), child: const Text('Add')),
          ],
        ),
      ),
    );
    if (ok == true && c.text.trim().isNotEmpty) {
      try {
        await AdminApi.request('POST', '/admin/thanas', body: {'district_id': districtId, 'name': c.text.trim()});
        await load();
      } catch (e) {
        _snack('$e', error: true);
      }
    }
    c.dispose();
  }

  Future<void> _addBloodGroup() async {
    final c = TextEditingController();
    final ok = await showDialog<bool>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text('Add blood group'),
        content: TextField(controller: c, autofocus: true, textCapitalization: TextCapitalization.characters, decoration: const InputDecoration(labelText: 'Example: A+', border: OutlineInputBorder())),
        actions: [
          TextButton(onPressed: () => Navigator.pop(ctx, false), child: const Text('Cancel')),
          FilledButton(onPressed: () => Navigator.pop(ctx, true), child: const Text('Add')),
        ],
      ),
    );
    if (ok == true && c.text.trim().isNotEmpty) {
      try {
        await AdminApi.request('POST', '/admin/blood-groups', body: {'name': c.text.trim().toUpperCase()});
        await load();
      } catch (e) {
        _snack('$e', error: true);
      }
    }
    c.dispose();
  }

  Future<void> _deleteCatalog(String endpoint, int id) async {
    try {
      await AdminApi.request('DELETE', '/admin/$endpoint/$id');
      await load();
    } catch (e) {
      _snack('$e', error: true);
    }
  }

  Future<void> _addBanner() async {
    final title = TextEditingController();
    final subtitle = TextEditingController();
    final imageUrl = TextEditingController();
    final sortOrder = TextEditingController(text: '0');
    Uint8List? pickedBytes;
    String pickedName = '';
    bool active = true;
    bool saving = false;

    try {
      await showDialog(
        context: context,
        barrierDismissible: false,
        builder: (ctx) => StatefulBuilder(
          builder: (ctx, dialogSetState) => AlertDialog(
            title: const Text('Add Home Banner'),
            content: SingleChildScrollView(
              child: SizedBox(
                width: 470,
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    if (pickedBytes != null)
                      Padding(
                        padding: const EdgeInsets.only(bottom: 10),
                        child: AspectRatio(
                          aspectRatio: 679 / 461,
                          child: ClipRRect(
                            borderRadius: BorderRadius.circular(12),
                            child: Image.memory(pickedBytes!, fit: BoxFit.cover),
                          ),
                        ),
                      ),
                    OutlinedButton.icon(
                      onPressed: saving
                          ? null
                          : () async {
                              try {
                                final picked = await ImagePicker().pickImage(
                                  source: ImageSource.gallery,
                                  imageQuality: 92,
                                  maxWidth: 2200,
                                );
                                if (picked == null) return;
                                final bytes = await picked.readAsBytes();
                                dialogSetState(() {
                                  pickedBytes = bytes;
                                  pickedName = picked.name;
                                });
                              } catch (e) {
                                _snack('Image select করা যায়নি: $e', error: true);
                              }
                            },
                      icon: const Icon(Icons.upload_rounded),
                      label: Text(pickedBytes == null ? 'কম্পিউটার/ফোন থেকে Banner Upload' : 'অন্য Banner নির্বাচন করুন'),
                    ),
                    const SizedBox(height: 8),
                    const Text(
                      'Recommended ratio: প্রায় 679×461. JPG / PNG / WEBP, সর্বোচ্চ 8 MB.',
                      style: TextStyle(fontSize: 11, color: Colors.black54),
                    ),
                    const SizedBox(height: 14),
                    TextField(
                      controller: imageUrl,
                      enabled: !saving,
                      decoration: const InputDecoration(
                        labelText: 'অথবা Image URL',
                        hintText: 'https://...',
                        border: OutlineInputBorder(),
                      ),
                    ),
                    const SizedBox(height: 12),
                    TextField(
                      controller: title,
                      enabled: !saving,
                      decoration: const InputDecoration(labelText: 'Title (optional)', border: OutlineInputBorder()),
                    ),
                    const SizedBox(height: 12),
                    TextField(
                      controller: subtitle,
                      enabled: !saving,
                      decoration: const InputDecoration(labelText: 'Subtitle (optional)', border: OutlineInputBorder()),
                    ),
                    const SizedBox(height: 12),
                    TextField(
                      controller: sortOrder,
                      enabled: !saving,
                      keyboardType: TextInputType.number,
                      decoration: const InputDecoration(
                        labelText: 'Sort order',
                        helperText: 'ছোট সংখ্যা আগে দেখাবে',
                        border: OutlineInputBorder(),
                      ),
                    ),
                    SwitchListTile(
                      contentPadding: EdgeInsets.zero,
                      value: active,
                      onChanged: saving ? null : (v) => dialogSetState(() => active = v),
                      title: const Text('Active'),
                    ),
                  ],
                ),
              ),
            ),
            actions: [
              TextButton(
                onPressed: saving ? null : () => Navigator.pop(ctx),
                child: const Text('Cancel'),
              ),
              FilledButton.icon(
                onPressed: saving
                    ? null
                    : () async {
                        dialogSetState(() => saving = true);
                        try {
                          String finalImageUrl = imageUrl.text.trim();
                          if (pickedBytes != null) {
                            final uploaded = await AdminApi.uploadBytes(
                              '/admin/banners/upload',
                              fieldName: 'banner',
                              bytes: pickedBytes!,
                              filename: pickedName.isEmpty ? 'banner.jpg' : pickedName,
                            );
                            finalImageUrl = (uploaded['image_url'] ?? '').toString().trim();
                          }
                          if (finalImageUrl.isEmpty) {
                            throw const AdminApiException(422, 'Banner image upload করুন অথবা Image URL দিন');
                          }
                          await AdminApi.request(
                            'POST',
                            '/admin/banners',
                            body: {
                              'title': title.text.trim(),
                              'subtitle': subtitle.text.trim(),
                              'image_url': finalImageUrl,
                              'link_url': '',
                              'is_active': active,
                              'sort_order': int.tryParse(sortOrder.text.trim()) ?? 0,
                            },
                          );
                          if (ctx.mounted) Navigator.pop(ctx);
                          _snack('Banner save হয়েছে');
                          await load();
                        } catch (e) {
                          _snack('$e', error: true);
                          if (ctx.mounted) dialogSetState(() => saving = false);
                        }
                      },
                icon: saving
                    ? const SizedBox(
                        width: 16,
                        height: 16,
                        child: CircularProgressIndicator(strokeWidth: 2),
                      )
                    : const Icon(Icons.save_rounded),
                label: Text(saving ? 'Saving...' : 'Save Banner'),
              ),
            ],
          ),
        ),
      );
    } finally {
      title.dispose();
      subtitle.dispose();
      imageUrl.dispose();
      sortOrder.dispose();
    }
  }

  Future<void> _logout() async {
    await AdminApi.logout();
    if (mounted) Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => const LoginScreen()));
  }
}
