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

import '../../models/office.dart';
import '../../providers/profile_provider.dart';
import '../../providers/tickets_provider.dart';
import '../../providers/services_provider.dart';
import '../../widgets/mono_text.dart';
import '../../widgets/responsive_body.dart';
import '../../theme/app_surfaces.dart';
import '../../widgets/tasq_adaptive_list.dart';
import '../../utils/snackbar.dart';

class OfficesScreen extends ConsumerStatefulWidget {
  const OfficesScreen({super.key});

  @override
  ConsumerState<OfficesScreen> createState() => _OfficesScreenState();
}

class _OfficesScreenState extends ConsumerState<OfficesScreen> {
  final TextEditingController _searchController = TextEditingController();

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

  @override
  Widget build(BuildContext context) {
    final isAdmin = ref.watch(isAdminProvider);
    final officesAsync = ref.watch(officesProvider);

    return Stack(
      children: [
        ResponsiveBody(
          maxWidth: double.infinity,
          child: !isAdmin
              ? const Center(child: Text('Admin access required.'))
              : officesAsync.when(
                  data: (offices) {
                    if (offices.isEmpty) {
                      return const Center(child: Text('No offices found.'));
                    }

                    final query = _searchController.text.trim().toLowerCase();
                    final filteredOffices = query.isEmpty
                        ? offices
                        : offices
                              .where(
                                (office) =>
                                    office.name.toLowerCase().contains(query) ||
                                    office.id.toLowerCase().contains(query),
                              )
                              .toList();

                    final listBody = TasQAdaptiveList<Office>(
                      items: filteredOffices,
                      filterHeader: SizedBox(
                        width: 320,
                        child: TextField(
                          controller: _searchController,
                          onChanged: (_) => setState(() {}),
                          decoration: const InputDecoration(
                            labelText: 'Search name',
                            prefixIcon: Icon(Icons.search),
                          ),
                        ),
                      ),
                      columns: [
                        TasQColumn<Office>(
                          header: 'Office ID',
                          technical: true,
                          cellBuilder: (context, office) => Text(office.id),
                        ),
                        TasQColumn<Office>(
                          header: 'Office Name',
                          cellBuilder: (context, office) => Text(office.name),
                        ),
                      ],
                      rowActions: (office) => [
                        IconButton(
                          tooltip: 'Edit',
                          icon: const Icon(Icons.edit),
                          onPressed: () =>
                              _showOfficeDialog(context, ref, office: office),
                        ),
                        IconButton(
                          tooltip: 'Delete',
                          icon: const Icon(Icons.delete),
                          onPressed: () => _confirmDelete(context, ref, office),
                        ),
                      ],
                      mobileTileBuilder: (context, office, actions) {
                        return Card(
                          child: ListTile(
                            dense: true,
                            visualDensity: VisualDensity.compact,
                            leading: const Icon(Icons.apartment_outlined),
                            title: Text(office.name),
                            subtitle: MonoText('ID ${office.id}'),
                            trailing: Wrap(spacing: 8, children: actions),
                          ),
                        );
                      },
                      onRequestRefresh: () {
                        // For server-side pagination, update the query provider
                        ref.read(officesQueryProvider.notifier).state =
                            const OfficeQuery(offset: 0, limit: 50);
                      },
                      onPageChanged: (firstRow) {
                        ref
                            .read(officesQueryProvider.notifier)
                            .update((q) => q.copyWith(offset: firstRow));
                      },
                      isLoading: false,
                    );

                    return Column(
                      mainAxisSize: MainAxisSize.max,
                      crossAxisAlignment: CrossAxisAlignment.stretch,
                      children: [
                        Padding(
                          padding: const EdgeInsets.only(top: 16, bottom: 8),
                          child: Stack(
                            alignment: Alignment.center,
                            children: [
                              Align(
                                alignment: Alignment.center,
                                child: Text(
                                  'Office Management',
                                  textAlign: TextAlign.center,
                                  style: Theme.of(context).textTheme.titleLarge
                                      ?.copyWith(fontWeight: FontWeight.w700),
                                ),
                              ),
                            ],
                          ),
                        ),
                        Expanded(child: listBody),
                      ],
                    );
                  },
                  loading: () =>
                      const Center(child: CircularProgressIndicator()),
                  error: (error, _) =>
                      Center(child: Text('Failed to load offices: $error')),
                ),
        ),
        if (isAdmin)
          Positioned(
            right: 16,
            bottom: 16,
            child: SafeArea(
              child: FloatingActionButton.extended(
                onPressed: () => _showOfficeDialog(context, ref),
                icon: const Icon(Icons.add),
                label: const Text('New Office'),
              ),
            ),
          ),
      ],
    );
  }

  Future<void> _showOfficeDialog(
    BuildContext context,
    WidgetRef ref, {
    Office? office,
  }) async {
    final nameController = TextEditingController(text: office?.name ?? '');
    String? selectedServiceId = office?.serviceId;

    await showDialog<void>(
      context: context,
      builder: (dialogContext) {
        bool saving = false;
        return StatefulBuilder(
          builder: (context, setState) {
            return AlertDialog(
              shape: AppSurfaces.of(context).dialogShape,
              title: Text(office == null ? 'Create Office' : 'Edit Office'),
              content: SingleChildScrollView(
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    TextField(
                      controller: nameController,
                      decoration: const InputDecoration(
                        labelText: 'Office name',
                      ),
                      enabled: !saving,
                    ),
                    const SizedBox(height: 12),
                    Consumer(
                      builder: (ctx, dialogRef, _) {
                        final servicesAsync = dialogRef.watch(
                          servicesOnceProvider,
                        );
                        return servicesAsync.when(
                          data: (services) {
                            return DropdownButtonFormField<String?>(
                              initialValue: selectedServiceId,
                              decoration: const InputDecoration(
                                labelText: 'Service',
                              ),
                              items: [
                                const DropdownMenuItem<String?>(
                                  value: null,
                                  child: Text('None'),
                                ),
                                ...services.map(
                                  (s) => DropdownMenuItem<String?>(
                                    value: s.id,
                                    child: Text(s.name),
                                  ),
                                ),
                              ],
                              onChanged: saving
                                  ? null
                                  : (v) =>
                                        setState(() => selectedServiceId = v),
                            );
                          },
                          loading: () => const Padding(
                            padding: EdgeInsets.symmetric(vertical: 8.0),
                            child: LinearProgressIndicator(),
                          ),
                          error: (e, _) => Text('Failed to load services: $e'),
                        );
                      },
                    ),
                  ],
                ),
              ),
              actions: [
                TextButton(
                  onPressed: saving
                      ? null
                      : () => Navigator.of(dialogContext).pop(),
                  child: const Text('Cancel'),
                ),
                FilledButton(
                  onPressed: saving
                      ? null
                      : () async {
                          final name = nameController.text.trim();
                          if (name.isEmpty) {
                            showWarningSnackBar(context, 'Name is required.');
                            return;
                          }
                          setState(() => saving = true);
                          final controller = ref.read(
                            officesControllerProvider,
                          );
                          if (office == null) {
                            await controller.createOffice(
                              name: name,
                              serviceId: selectedServiceId,
                            );
                          } else {
                            await controller.updateOffice(
                              id: office.id,
                              name: name,
                              serviceId: selectedServiceId,
                            );
                          }
                          ref.invalidate(officesProvider);
                          if (context.mounted) {
                            Navigator.of(dialogContext).pop();
                            showSuccessSnackBar(
                              context,
                              office == null
                                  ? 'Office "$name" has been created successfully.'
                                  : 'Office "$name" has been updated successfully.',
                            );
                          }
                        },
                  child: saving
                      ? const SizedBox(
                          height: 18,
                          width: 18,
                          child: CircularProgressIndicator(strokeWidth: 2),
                        )
                      : Text(office == null ? 'Create' : 'Save'),
                ),
              ],
            );
          },
        );
      },
    );
  }

  Future<void> _confirmDelete(
    BuildContext context,
    WidgetRef ref,
    Office office,
  ) async {
    await showDialog<void>(
      context: context,
      builder: (dialogContext) {
        return AlertDialog(
          title: const Text('Delete Office'),
          content: Text('Delete ${office.name}? This cannot be undone.'),
          actions: [
            TextButton(
              onPressed: () => Navigator.of(dialogContext).pop(),
              child: const Text('Cancel'),
            ),
            FilledButton(
              onPressed: () async {
                await ref
                    .read(officesControllerProvider)
                    .deleteOffice(id: office.id);
                ref.invalidate(officesProvider);
                if (context.mounted) {
                  Navigator.of(dialogContext).pop();
                }
              },
              child: const Text('Delete'),
            ),
          ],
        );
      },
    );
  }
}
