import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/new_models/site.dart';
import 'package:test_sa/models/new_models/department.dart';
import 'package:test_sa/providers/gas_request_providers/site_provider.dart';
import 'package:test_sa/providers/department_by_sites_provider.dart';
import 'package:test_sa/modules/site_request_module/models/request_type_model.dart';
import 'package:test_sa/modules/site_request_module/models/site_request_model.dart';
import 'package:test_sa/modules/site_request_module/models/dropdown_models.dart';
import 'package:test_sa/modules/site_request_module/providers/site_request_provider.dart';
import 'package:test_sa/modules/site_request_module/screens/site_request_history_screen.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart';
import 'package:test_sa/new_views/common_widgets/multiple_item_drop_down_menu.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
import 'package:test_sa/views/widgets/item_views/info_header_widget.dart';
import 'package:test_sa/views/widgets/item_views/info_text_widget.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart';

class SiteRequestFormScreen extends StatefulWidget {
  static const String routeName = "/site_request_form";

  const SiteRequestFormScreen({Key? key}) : super(key: key);

  @override
  State<SiteRequestFormScreen> createState() => _SiteRequestFormScreenState();
}

class _SiteRequestFormScreenState extends State<SiteRequestFormScreen> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  late SiteRequestProvider _provider;
  late UserProvider _userProvider;

  RequestTypeModel? _selectedRequestType;
  List<Site> _selectedSites = [];
  List<Site> _selectedOldSites = []; // For Change Site - old sites
  List<Department> _selectedDepartments = [];

  // Map to track replacements: oldSiteId -> {newSite, departments}
  Map<String, SiteReplacement> _siteReplacements = {};

  // Track which site IDs have already loaded departments to prevent infinite API calls
  Set<int> _loadedDepartmentSiteIds = {};

  bool _isSubmitting = false;
  bool _isLoadingData = true;

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

  Future<void> _loadInitialData() async {
    // Load data after first frame to access context
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      _provider = Provider.of<SiteRequestProvider>(context, listen: false);
      _userProvider = Provider.of<UserProvider>(context, listen: false);

      // Initialize department provider with empty state
      final departmentProvider = Provider.of<DepartmentBySitesProvider>(context, listen: false);
      departmentProvider.setSiteIds([]);
      departmentProvider.items = [];
      departmentProvider.loading = false;

      // Fetch only request types (sites and departments are loaded by their providers)
      await _provider.fetchRequestTypes();

      if (mounted) {
        setState(() {
          _isLoadingData = false;
        });
      }
    });
  }

  bool _isChangeSiteRequest() {
    return _selectedRequestType?.name?.toLowerCase().contains('change') ?? false;
  }

  bool _isRemoveSiteRequest() {
    return _selectedRequestType?.name?.toLowerCase().contains('remove') ?? false;
  }

  @override
  Widget build(BuildContext context) {
    _provider = Provider.of<SiteRequestProvider>(context);
    _userProvider = Provider.of<UserProvider>(context);
    return Scaffold(
      backgroundColor: AppColor.scaffoldBackground(context),
      appBar: const DefaultAppBar(title: "Site Request"),
      body: _isLoadingData
          ? const ALoading().center
          : Column(
              children: [
                Expanded(
                  child: Form(
                    key: _formKey,
                    child: SingleChildScrollView(
                      padding: EdgeInsets.all(16.toScreenWidth),
                      child: Column(
                        spacing: 12,
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          _buildUserInfoCard(),
                          _buildRequestTypeDropdown(),
                          if (_selectedRequestType != null) ...[
                            if (_isChangeSiteRequest()) ...[
                              _buildOldSiteDropdown(),
                              // Show replacement containers for each old site
                              if (_selectedOldSites.isNotEmpty) ...[
                                InfoHeader16Widget("Site Replacements"),
                                ..._buildSiteReplacementContainers(),
                              ],
                            ] else if (_isRemoveSiteRequest()) ...[
                              _buildRemoveSiteDropdown(),
                            ] else ...[
                              _buildSiteMultiSelect(),
                              _buildDepartmentMultiSelect(),
                            ],
                          ],
                        ],
                      ),
                    ),
                  ),
                ),
                if (_selectedRequestType != null)
                  Container(
                    padding: EdgeInsets.all(16.toScreenWidth),
                    decoration: BoxDecoration(
                      color: AppColor.background(context),
                      boxShadow: [
                        BoxShadow(
                          color: Colors.black.withValues(alpha: 0.05),
                          blurRadius: 10,
                          offset: const Offset(0, -2),
                        ),
                      ],
                    ),
                    child: SafeArea(
                      child: _buildSubmitButton(),
                    ),
                  ),
              ],
            ),
    );
  }

  Widget _buildRequestTypeDropdown() {
    return SingleItemDropDownMenu<RequestTypeModel, NullableLoadingProvider>(
      context: context,
      title: "Type of site request".addTranslation,
      initialValue: _selectedRequestType,
      staticData: _provider.requestTypes,
      showAsFullScreenDialog: true,
      onSelect: (value) async {
        setState(() {
          _selectedRequestType = value;
          _selectedSites.clear();
          _selectedOldSites.clear();
          _selectedDepartments.clear();
          _siteReplacements.clear();
          _loadedDepartmentSiteIds.clear(); // Reset loaded department site IDs
        });

        // Fetch user's current sites if Change Site or Remove Site is selected
        if ((_isChangeSiteRequest() || _isRemoveSiteRequest()) && value != null) {
          final userId = _provider.getCurrentUserUserId(_userProvider);
          await _provider.fetchUserCurrentSites(userId);
        }

        // Fetch all sites if Change Site is selected (needed for new site dropdown)
        if (_isChangeSiteRequest() && value != null) {
          final siteProvider = Provider.of<SiteProvider>(context, listen: false);
          if (siteProvider.items.isEmpty) {
            await siteProvider.getData();
          }
        }
      },
      validator: (value) {
        if (value == null) return "Please select request type";
        return null;
      },
    );
  }

  Widget _buildUserInfoCard() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        InfoHeader16Widget("Requester Information"),
        // 8.height,
        // InfoTextWidget(
        //   label: "Employee ID".addTranslation,
        //   value: _provider.getCurrentUserEmployeeId(_userProvider),
        //   showEmptyValue: true,
        // ),
        InfoTextWidget(
          label: "Full Name".addTranslation,
          value: _provider.getCurrentUserFullName(_userProvider),
          showEmptyValue: true,
        ),

        InfoTextWidget(
          label: "Email Address".addTranslation,
          value: _provider.getCurrentUserEmail(_userProvider),
          showEmptyValue: true,
        ),
        InfoTextWidget(
          label: "Mobile Number".addTranslation,
          value: _provider.getCurrentUserMobile(_userProvider),
          showEmptyValue: true,
        ),
        InfoTextWidget(
          label: "Extension Number".addTranslation,
          value: _provider.getCurrentUserExtension(_userProvider),
          showEmptyValue: true,
        ),
        InfoTextWidget(
          label: "Role".addTranslation,
          value: _provider.getCurrentUserRole(_userProvider),
          showEmptyValue: true,
        ),
      ],
    ).toShadowContainer(context);
  }

  Widget _buildOldSiteDropdown() {
    return MultipleItemDropDownMenu<SiteRequestSiteModel, NullableLoadingProvider>(
      context: context,
      title: "Current Sites",
      initialValue: _selectedOldSites
          .map((s) => SiteRequestSiteModel(
                id: s.identifier ?? '',
                name: s.name ?? '',
              ))
          .toList(),
      staticData: _provider.userCurrentSites,
      showAsBottomSheet: true,
      backgroundColor: context.isDark ? AppColor.neutral60 : Colors.white,
      showShadow: true,
      height: 56.toScreenHeight,
      showCancel: true,
      onSelect: (value) {
        if (value != null) {
          setState(() {
            _selectedOldSites = value.map((s) {
              final site = Site(
                id: int.tryParse(s.identifier ?? '0'),
                custName: s.name,
              );
              return site;
            }).toList();

            // Remove replacements for sites that are no longer selected
            final newSiteIds = _selectedOldSites.map((s) => s.identifier ?? '').toSet();
            _siteReplacements.removeWhere((key, value) => !newSiteIds.contains(key));

            // Initialize replacements for newly added sites
            for (var site in _selectedOldSites) {
              final siteId = site.identifier ?? '';
              if (!_siteReplacements.containsKey(siteId)) {
                _siteReplacements[siteId] = SiteReplacement(
                  newSite: null,
                  departments: [],
                );
              }
            }
          });
        }
      },
    );
  }

  Widget _buildRemoveSiteDropdown() {
    return MultipleItemDropDownMenu<SiteRequestSiteModel, NullableLoadingProvider>(
      context: context,
      title: "Site to Remove",
      initialValue: _selectedSites
          .map((s) => SiteRequestSiteModel(
                id: s.identifier ?? '',
                name: s.name ?? '',
              ))
          .toList(),
      staticData: _provider.userCurrentSites,
      showAsFullScreenDialog: true,
      backgroundColor: context.isDark ? AppColor.neutral60 : Colors.white,
      showShadow: true,
      height: 56.toScreenHeight,
      showCancel: true,
      onSelect: (value) {
        if (value != null) {
          setState(() {
            _selectedSites = value.map((s) {
              final site = Site(
                id: int.tryParse(s.identifier ?? '0'),
                custName: s.name,
              );
              return site;
            }).toList();
          });
        }
      },
    );
  }

  Widget _buildSiteMultiSelect() {
    return MultipleItemDropDownMenu<Site, SiteProvider>(
      context: context,
      title: context.translation.site,
      initialValue: _selectedSites,
      showAsBottomSheet: true,
      backgroundColor: context.isDark ? AppColor.neutral60 : Colors.white,
      showShadow: true,
      height: 56.toScreenHeight,
      showCancel: true,
      onSelect: (value) {
        if (value != null) {
          setState(() {
            _selectedSites = value;
            _selectedDepartments.clear(); // Clear departments when sites change

            // Update department provider with new site IDs
            final departmentProvider = Provider.of<DepartmentBySitesProvider>(context, listen: false);
            final siteIds = value.map((site) => int.tryParse(site.identifier ?? '0') ?? 0).toList();
            departmentProvider.setSiteIds(siteIds);
            departmentProvider.getData();
          });
        }
      },
    );
  }

  Widget _buildDepartmentMultiSelect() {
    return MultipleItemDropDownMenu<Department, DepartmentBySitesProvider>(
      context: context,
      title: "Department".addTranslation,
      initialValue: _selectedDepartments,
      showAsBottomSheet: true,
      backgroundColor: context.isDark ? AppColor.neutral60 : Colors.white,
      showShadow: true,
      height: 56.toScreenHeight,
      showCancel: true,
      enabled: _selectedSites.isNotEmpty,
      loading: _selectedSites.isEmpty ? false : null,
      onSelect: (value) {
        if (value != null) {
          setState(() {
            _selectedDepartments = value;
          });
        }
      },
    );
  }

  Widget _buildSubmitButton() {
    // Disable button if Remove Site is selected and no assigned sites
    final assignedSites = _provider.getCurrentUserAssignedSites(_userProvider);
    final isDisabled = _selectedRequestType?.name == 'Remove Site' && !_provider.hasAssignedSites(assignedSites);

    return AppFilledButton(
      label: "Submit",
      maxWidth: true,
      loading: _isSubmitting,
      disableButton: _isSubmitting || isDisabled,
      onPressed: isDisabled ? null : _submitForm,
    );
  }

  List<Widget> _buildSiteReplacementContainers() {
    return _selectedOldSites.map((oldSite) {
      final oldSiteId = oldSite.identifier ?? '';
      final replacement = _siteReplacements[oldSiteId];

      return Consumer<SiteProvider>(
        builder: (context, siteProvider, child) {
          // Get ALL user's current site IDs to exclude from new site selection
          final allUserCurrentSiteIds = _provider.userCurrentSites.map((s) => s.identifier ?? '').toSet();
          // Filter out already selected new sites and ALL user's current sites
          final alreadySelectedNewSites = _siteReplacements.values.where((r) => r.newSite != null).map((r) => r.newSite!.identifier).toSet();
          final filteredSites = siteProvider.items.where((site) {
            final siteId = site.identifier ?? '';
            // Exclude ALL user's current sites (not just selected old sites)
            if (allUserCurrentSiteIds.contains(siteId)) return false;
            // Exclude already selected new sites (except current one)
            if (replacement?.newSite?.identifier != siteId && alreadySelectedNewSites.contains(siteId)) {
              return false;
            }

            return true;
          }).toList();
          return Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            spacing: 12,
            children: [
              Text(
                oldSite.name ?? 'Unknown Site',
                style: AppTextStyles.bodyText,
              ),
              SingleItemDropDownMenu<Site, NullableLoadingProvider>(
                context: context,
                title: "New Site",
                initialValue: replacement?.newSite,
                staticData: filteredSites,
                showAsFullScreenDialog: true,
                backgroundColor: context.isDark ? AppColor.neutral60 : Colors.white,
                showShadow: true,
                height: 56.toScreenHeight,
                onSelect: (value) {
                  setState(() {
                    if (value != null) {
                      // Remove old site ID from loaded set to allow fetching new departments
                      if (replacement?.newSite != null) {
                        final oldNewSiteId = int.tryParse(replacement!.newSite!.identifier ?? '0') ?? 0;
                        _loadedDepartmentSiteIds.remove(oldNewSiteId);
                      }

                      _siteReplacements[oldSiteId] = SiteReplacement(
                        newSite: value,
                        departments: [], // Clear departments when new site changes
                      );
                    }
                  });
                },
              ),
              if (replacement?.newSite != null) ...[
                _buildDepartmentDropdownForSite(oldSiteId, replacement!.newSite!),
              ],
            ],
          ).toShadowContainer(context);
        },
      );
    }).toList();
  }

  Widget _buildDepartmentDropdownForSite(String oldSiteId, Site newSite) {
    final replacement = _siteReplacements[oldSiteId];
    final siteId = int.tryParse(newSite.identifier ?? '0') ?? 0;

    return Consumer<DepartmentBySitesProvider>(
      builder: (context, departmentProvider, child) {
        // Only fetch departments if we haven't loaded them for this site yet
        if (siteId > 0 && !_loadedDepartmentSiteIds.contains(siteId)) {
          // Mark this site as loaded to prevent infinite calls
          _loadedDepartmentSiteIds.add(siteId);

          // Fetch departments in post frame callback
          WidgetsBinding.instance.addPostFrameCallback((_) {
            if (mounted) {
              departmentProvider.setSiteIds([siteId]);
              departmentProvider.getData();
            }
          });
        }

        return MultipleItemDropDownMenu<Department, NullableLoadingProvider>(
          context: context,
          title: "Departments",
          initialValue: replacement?.departments ?? [],
          staticData: departmentProvider.items,
          showAsFullScreenDialog: true,
          backgroundColor: context.isDark ? AppColor.neutral60 : Colors.white,
          showShadow: true,
          height: 56.toScreenHeight,
          showCancel: true,
          loading: departmentProvider.loading,
          onSelect: (value) {
            setState(() {
              if (value != null && replacement != null) {
                _siteReplacements[oldSiteId] = SiteReplacement(
                  newSite: replacement.newSite,
                  departments: value,
                );
              }
            });
          },
        );
      },
    );
  }

  Future<void> _submitForm() async {
    // Client-side validation only (no toast messages)
    if (!_formKey.currentState!.validate()) {
      return;
    }

    if (_selectedRequestType == null) {
      return;
    }

    // Validation for Change Site request
    if (_isChangeSiteRequest()) {
      if (_selectedOldSites.isEmpty) {
        "Please select at least one site".showToast;
        return;
      }

      // Validate that each old site has a new site selected
      for (var oldSite in _selectedOldSites) {
        final oldSiteId = oldSite.identifier ?? '';
        final replacement = _siteReplacements[oldSiteId];
        if (replacement == null || replacement.newSite == null) {
          return;
        }
      }

      // Build the payload from replacements
      final newSiteIds = <String>[];
      final newSiteNames = <String>[];
      final oldSiteIds = <String>[];
      final oldSiteNames = <String>[];
      final departmentIds = <String>[];
      final departmentNames = <String>[];

      for (var oldSite in _selectedOldSites) {
        final oldSiteId = oldSite.identifier ?? '';
        final replacement = _siteReplacements[oldSiteId]!;

        // Add old site info
        oldSiteIds.add(oldSiteId);
        oldSiteNames.add(oldSite.name ?? '');

        // Add new site info
        newSiteIds.add(replacement.newSite!.identifier ?? '');
        newSiteNames.add(replacement.newSite!.name ?? '');

        // Add departments for this replacement
        for (var dept in replacement.departments) {
          departmentIds.add(dept.identifier ?? '');
          departmentNames.add(dept.name ?? '');
        }
      }

      setState(() {
        _isSubmitting = true;
      });

      if (mounted) {
        showDialog(
          context: context,
          barrierDismissible: false,
          builder: (context) => const AppLazyLoading(),
        );
      }

      final request = SiteRequestModel(
        requestType: _selectedRequestType!.identifier?.toString() ?? '',
        employeeId: _provider.getCurrentUserUserId(_userProvider),
        fullName: _provider.getCurrentUserFullName(_userProvider),
        emailAddress: _provider.getCurrentUserEmail(_userProvider),
        mobileNumber: _provider.getCurrentUserMobile(_userProvider),
        extensionNumber: _provider.getCurrentUserExtension(_userProvider),
        siteIds: newSiteIds,
        siteNames: newSiteNames,
        oldSiteIds: oldSiteIds,
        oldSiteNames: oldSiteNames,
        departmentIds: departmentIds.isNotEmpty ? departmentIds : null,
        departmentNames: departmentNames.isNotEmpty ? departmentNames : null,
        role: _provider.getCurrentUserRole(_userProvider),
        // status: 'Pending',
        // requestDate: DateTime.now(),
      );

      final success = await _provider.submitSiteRequest(request, _userProvider);

      if (mounted) {
        Navigator.pop(context); // Close loading dialog
      }

      setState(() {
        _isSubmitting = false;
      });

      // API will handle success/error toast messages

      if (success && mounted) {
        UserProvider userProvider = Provider.of<UserProvider>(context, listen: false);
        await _provider.fetchSiteRequests(pageNumber: 1, pageSize: 10, userProvider: userProvider);
        Navigator.pop(context);
        // Navigator.pushReplacementNamed(context, SiteRequestHistoryScreen.routeName);
      }
    } else {
      // For Add Site and Remove Site request types
      if (_selectedSites.isEmpty) {
        return;
      }

      setState(() {
        _isSubmitting = true;
      });

      if (mounted) {
        showDialog(
          context: context,
          barrierDismissible: false,
          builder: (context) => const AppLazyLoading(),
        );
      }

      final request = SiteRequestModel(
        requestType: _selectedRequestType!.identifier?.toString() ?? '',
        employeeId: _provider.getCurrentUserUserId(_userProvider),
        fullName: _provider.getCurrentUserFullName(_userProvider),
        emailAddress: _provider.getCurrentUserEmail(_userProvider),
        mobileNumber: _provider.getCurrentUserMobile(_userProvider),
        extensionNumber: _provider.getCurrentUserExtension(_userProvider),
        siteIds: _selectedSites.map((s) => s.identifier ?? '').toList(),
        siteNames: _selectedSites.map((s) => s.name ?? '').toList(),
        departmentIds: _selectedDepartments.isNotEmpty ? _selectedDepartments.map((d) => d.identifier ?? '').toList() : null,
        departmentNames: _selectedDepartments.isNotEmpty ? _selectedDepartments.map((d) => d.name ?? '').toList() : null,
        role: _provider.getCurrentUserRole(_userProvider),
        // status: 'Pending',
        // requestDate: DateTime.now(),
      );

      final success = await _provider.submitSiteRequest(request, _userProvider);

      if (mounted) {
        Navigator.pop(context); // Close loading dialog
      }

      setState(() {
        _isSubmitting = false;
      });

      // API will handle success/error toast messages
      if (success && mounted) {
        UserProvider userProvider = Provider.of<UserProvider>(context, listen: false);
        await _provider.fetchSiteRequests(pageNumber: 1, pageSize: 10, userProvider: userProvider);
        Navigator.pop(context);
      }
    }
  }
}

class SiteReplacement {
  final Site? newSite;
  final List<Department> departments;

  SiteReplacement({
    required this.newSite,
    required this.departments,
  });
}
