import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:generp/Utils/app_colors.dart';
import 'package:graphview/GraphView.dart';
import 'package:provider/provider.dart';
import '../../Models/hrmmodels/ogresponse.dart';
import '../../Notifiers/hrmprovider/orgprovider.dart';
import '../../Utils/commonServices.dart';
import '../../Utils/commonWidgets.dart';

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

  @override
  State<OrgChartt> createState() => _OrgCharttState();
}

class _OrgCharttState extends State<OrgChartt> {
  Map _source = {ConnectivityResult.none: false};
  final MyConnectivity _connectivity = MyConnectivity.instance;
  final Graph graph = Graph();
  final Map<String, Node> nodeMap = {};
  String connection = 'Offline';
  bool _isGraphReady = false;
  final Map<String, GlobalKey> nodeKeys = {};

  final TransformationController _transformationController =
      TransformationController();
  final builder =
      BuchheimWalkerConfiguration()
        ..levelSeparation = 50
        ..siblingSeparation = 20
        ..subtreeSeparation = 30
        ..orientation = BuchheimWalkerConfiguration.ORIENTATION_TOP_BOTTOM;

  @override
  void initState() {
    super.initState();
    _connectivity.initialise();
    _connectivity.myStream.listen((source) {
      setState(() => _source = source);
    });
    _transformationController.value = Matrix4.identity()..scale(0.5);
    WidgetsBinding.instance.addPostFrameCallback((_) {
      Provider.of<Orgprovider>(context, listen: false).ogChart(context).then((
        _,
      ) {
        setState(() {
          _isGraphReady = true;
        });
      });
      _centerOnRoot("130");
    });
  }

  void _centerOnRoot(String rootId) {
    if (!nodeKeys.containsKey(rootId)) return;

    final key = nodeKeys[rootId]!;
    final context = key.currentContext;
    if (context == null) return;

    final renderBox = context.findRenderObject() as RenderBox;
    final rootPosition = renderBox.localToGlobal(Offset.zero);

    final screenSize = MediaQuery.of(context).size;
    final rootSize = renderBox.size;

    final screenCenter = Offset(screenSize.width / 2, screenSize.height / 2);
    final rootCenter =
        rootPosition + Offset(rootSize.width / 2, rootSize.height / 2);

    final dx = screenCenter.dx - rootCenter.dx;
    final dy = screenCenter.dy - rootCenter.dy;

    _transformationController.value = Matrix4.identity()..translate(dx, dy);
  }

  @override
  Widget build(BuildContext context) {
    switch (_source.keys.toList()[0]) {
      case ConnectivityResult.mobile:
      case ConnectivityResult.wifi:
        connection = 'Online';
        break;
      case ConnectivityResult.none:
      default:
        connection = 'Offline';
    }

    return Platform.isAndroid
        ? WillPopScope(
          onWillPop: () => onBackPressed(context),
          child: SafeArea(top: false, bottom: true, child: _scaffold(context)),
        )
        : _scaffold(context);
  }

  Widget _scaffold(BuildContext context) {
    return Consumer<Orgprovider>(
      builder: (context, provider, child) {
        graph.nodes.clear();
        graph.edges.clear();
        nodeMap.clear();

        if (provider.rootID != null && provider.employees.isNotEmpty) {
          _buildGraph(provider);
          if (kDebugMode) {
            print(
              'Graph built with ${graph.nodes.length} nodes and ${graph.edges.length} edges',
            );
          }
        }

        return Scaffold(
          backgroundColor: Color(0xFFF6F6F8),

          appBar: appbar2New(
            context,
            "Organisation Chart",
            null,
            SizedBox.shrink(),
            0xFFFFFFF,
          ),
          body:
              provider.rootID == null && provider.employees.isEmpty
                  ? Center(
                    child: CircularProgressIndicator(
                      valueColor: AlwaysStoppedAnimation(AppColors.app_blue),
                    ),
                  )
                  : SingleChildScrollView(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        if (graph.nodes.isNotEmpty && _isGraphReady)
                          SingleChildScrollView(
                            scrollDirection: Axis.horizontal,
                            child: SizedBox(
                              width: MediaQuery.of(context).size.width,
                              height: MediaQuery.of(context).size.height * 0.8,
                              child: InteractiveViewer(
                                boundaryMargin: const EdgeInsets.all(
                                  double.infinity,
                                ),
                                panEnabled: true,
                                scaleEnabled: true,
                                constrained: false,
                                minScale: 0.1,
                                scaleFactor: 1,
                                transformationController:
                                    _transformationController,
                                maxScale: 5,
                                panAxis: PanAxis.free,

                                // scaleEnabled: true,
                                // panAxis: PanAxis.free
                                child: GraphView(
                                  graph: graph,

                                  algorithm: BuchheimWalkerAlgorithm(
                                    builder,
                                    TreeEdgeRenderer(builder),
                                  ),
                                  paint:
                                      Paint()
                                        ..color = AppColors.grey_thick
                                        ..strokeWidth = 1
                                        ..style = PaintingStyle.stroke,

                                  builder: (Node node) {
                                    final key = GlobalKey();
                                    nodeKeys[node.key!.value] = key;
                                    final employee = _getEmployeeById(
                                      node.key!.value,
                                      provider,
                                    );
                                    if (employee == null) {
                                      if (kDebugMode) {
                                        print(
                                          'No employee found for node ID: ${node.key!.value}',
                                        );
                                      }
                                      return Container(
                                        width: 50,
                                        height: 82,
                                        color: Colors.transparent,
                                        child: const Center(
                                          child: Text('Invalid Node'),
                                        ),
                                      );
                                    }
                                    return InkResponse(
                                      onTap: () {
                                        // Navigator.push(
                                        //   context,
                                        //   MaterialPageRoute(
                                        //     builder:
                                        //         (context) =>
                                        //             employeeDetails(
                                        //               accountID: employee.id,
                                        //             ),
                                        //   ),
                                        // );
                                      },
                                      child: Container(
                                        key: key,
                                        width: 200,
                                        padding: const EdgeInsets.all(8.0),
                                        // Reduced padding
                                        child: Column(
                                          crossAxisAlignment:
                                              CrossAxisAlignment.center,
                                          mainAxisAlignment:
                                              MainAxisAlignment.center,
                                          mainAxisSize: MainAxisSize.min,
                                          children: [
                                            SizedBox(
                                              width: 100,
                                              height: 100,
                                              child: ClipRRect(
                                                borderRadius:
                                                    BorderRadius.circular(50),
                                                child: CachedNetworkImage(
                                                  cacheKey:
                                                      employee.profile ?? '',
                                                  fit: BoxFit.cover,
                                                  imageUrl:
                                                      employee.profile ?? '',
                                                  useOldImageOnUrlChange: false,
                                                  placeholder:
                                                      (context, url) =>
                                                          CircularProgressIndicator.adaptive(),
                                                  errorWidget:
                                                      (context, url, error) =>
                                                          Icon(Icons.error),
                                                ),
                                              ),
                                            ),

                                            const SizedBox(height: 8),
                                            Row(
                                              children: [
                                                Expanded(
                                                  child: Text(
                                                    employee.name ?? 'Unknown',
                                                    maxLines: 2,
                                                    textAlign: TextAlign.center,
                                                    overflow:
                                                        TextOverflow.ellipsis,
                                                    style: TextStyle(
                                                      color:
                                                          AppColors.semi_black,
                                                      fontFamily:
                                                          "JakartaMedium",
                                                      fontSize: 25,
                                                    ),
                                                  ),
                                                ),
                                              ],
                                            ),
                                            SizedBox(height: 10),
                                            Row(
                                              children: [
                                                Expanded(
                                                  child: Text(
                                                    employee.title ?? '',
                                                    maxLines: 2,
                                                    textAlign: TextAlign.center,
                                                    overflow:
                                                        TextOverflow.ellipsis,
                                                    style: TextStyle(
                                                      color:
                                                          AppColors.grey_thick,
                                                      fontSize: 18,
                                                    ), // Reduced font size
                                                  ),
                                                ),
                                              ],
                                            ),
                                          ],
                                        ),
                                      ),
                                    );
                                  },
                                ),
                              ),
                            ),
                          ),
                      ],
                    ),
                  ),
        );
      },
    );
  }

  void _buildGraph(Orgprovider provider) {
    final rootNode = Node.Id(provider.rootID!);
    nodeMap[provider.rootID!] = rootNode;
    graph.addNode(rootNode);
    _addChildren(provider.employees, rootNode, provider);
  }

  void _addChildren(
    List<Children> children,
    Node parentNode,
    Orgprovider provider,
  ) {
    for (var child in children) {
      if (child.id == null || child.id!.isEmpty) {
        if (kDebugMode) {
          print('Skipping invalid child with null or empty ID');
        }
        continue;
      }
      if (nodeMap.containsKey(child.id)) {
        if (kDebugMode) {
          print('Skipping duplicate node ID: ${child.id}');
        }
        continue;
      }
      final childNode = Node.Id(child.id!);
      nodeMap[child.id!] = childNode;
      graph.addNode(childNode);
      graph.addEdge(
        parentNode,
        childNode,
        paint: Paint()..color = AppColors.grey_thick,
      );
      if (child.children != null && child.children!.isNotEmpty) {
        _addChildren(child.children!, childNode, provider);
      }
    }
  }

  Children? _getEmployeeById(String id, Orgprovider provider) {
    if (id == provider.rootID) {
      return Children(
        id: provider.rootID,
        name: provider.rootName,
        title: provider.rootTitle,
        profile: provider.rootProfile,
      );
    }
    return _findEmployeeInList(id, provider.employees);
  }

  Children? _findEmployeeInList(String id, List<Children> employees) {
    for (var employee in employees) {
      if (employee.id == id) {
        return employee;
      }
      if (employee.children != null && employee.children!.isNotEmpty) {
        final found = _findEmployeeInList(id, employee.children!);
        if (found != null) {
          return found;
        }
      }
    }
    return null;
  }
}
