import 'dart:async';
import 'dart:io';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:open_filex/open_filex.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_svg/svg.dart';
import 'package:generp/Utils/commonWidgets.dart';
import 'package:path_provider/path_provider.dart';
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';
import 'package:http/http.dart' as http;
import 'dart:typed_data';
import 'package:photo_view/photo_view.dart';

import '../../Utils/app_colors.dart';

class Fileviewer extends StatefulWidget {
  final String fileName;
  final String fileUrl;
  final bool downloadEnable;// use this to show download button or not at
  const Fileviewer({super.key, required this.fileName, required this.fileUrl, required this.downloadEnable});

  @override
  State<Fileviewer> createState() => _FileviewerState();
}

class _FileviewerState extends State<Fileviewer> {
  final Completer<InAppWebViewController> _controller =
  Completer<InAppWebViewController>();
  var empId = "";
  var sessionId = "";
  bool isLoading = true;
  InAppWebViewController? webViewController;
  PullToRefreshController? pullToRefreshController;
  PullToRefreshSettings pullToRefreshSettings = PullToRefreshSettings(
    color: AppColors.app_blue,
  );
  bool pullToRefreshEnabled = true;

  final GlobalKey webViewKey = GlobalKey();

  // Zoom control variables
  PhotoViewController _photoViewController = PhotoViewController();
  PhotoViewScaleStateController _scaleStateController = PhotoViewScaleStateController();

  String getFileExtension(String fileName) {
    print(widget.fileUrl);
    return fileName.split('.').last.toLowerCase();
  }

  Future<void> _launchUrl(String url) async {
    final Uri uri = Uri.parse(url);
    if (await canLaunchUrl(uri)) {
      await launchUrl(uri, mode: LaunchMode.externalApplication);
    } else {
      throw 'Could not launch $url';
    }
  }

  var Finalurl;

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

    // Create pullToRefreshController only for non-web platforms
    if (!kIsWeb) {
      pullToRefreshController = PullToRefreshController(
        settings: pullToRefreshSettings,
        onRefresh: () async {
          // Guard: don't run if widget disposed
          if (!mounted) return;
          try {
            if (defaultTargetPlatform == TargetPlatform.android) {
              await webViewController?.reload();
            } else if (defaultTargetPlatform == TargetPlatform.iOS) {
              final currentUrl = await webViewController?.getUrl();
              if (currentUrl != null) {
                await webViewController?.loadUrl(
                  urlRequest: URLRequest(url: currentUrl),
                );
              }
            }
          } catch (e) {
            // ignore errors during refresh
          } finally {
            // ensure refresh animation stops even if reload fails
            safeEndRefreshing();
          }
        },
      );
    } else {
      pullToRefreshController = null;
    }

    // Initialize photo view controllers
    _photoViewController = PhotoViewController();
    _scaleStateController = PhotoViewScaleStateController();
  }
  /// Safe helper to end pull-to-refresh only when mounted and controller exists.
  void safeEndRefreshing() {
    if (!mounted) return;
    final ctrl = pullToRefreshController;
    if (ctrl != null) {
      try {
        ctrl.endRefreshing();
      } catch (e) {
        // In some rare cases controller may already be disposed — ignore.
      }
    }
  }

  @override
  void dispose() {
    // Dispose photo controllers first
    _photoViewController.dispose();
    _scaleStateController.dispose();

    // Dispose pullToRefreshController and null it to avoid later use
    try {
      pullToRefreshController?.dispose();
    } catch (e) {
      // ignore dispose errors
    }
    pullToRefreshController = null;

    webViewController = null;
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: true,
      appBar: AppBar(
        backgroundColor: Color(0xFFFFFFFF),
        automaticallyImplyLeading: false,
        title: SizedBox(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              InkResponse(
                onTap: () => Navigator.pop(context, true),
                child: SvgPicture.asset(
                  "assets/svg/appbar_back_button.svg",
                  height: 25,
                ),
              ),
              SizedBox(width: 10),
              InkResponse(
                onTap: () => Navigator.pop(context, true),
                child: Text(
                  "File Viewer",
                  style: TextStyle(
                    fontSize: 16,
                    height: 1.1,
                    fontFamily: "JakartaSemiBold",
                    color: AppColors.semi_black,
                  ),
                ),
              ),

              Spacer(),

              /// DOWNLOAD BUTTON (NEW)
              /// -----------------------------
              if (widget.downloadEnable)
                IconButton(
                  icon: Icon(Icons.download_rounded, color: AppColors.app_blue),
                  onPressed: () async {
                    await _downloadFile(widget.fileUrl, widget.fileName);
                    },
                ),
            ],
          ),
        ),
      ),
      body: SafeArea(
        child: Center(
            child: fileWidget(context)
        ),
      ),
    );
  }

  Future<void> _downloadFile(String url, String fileName) async {
    try {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("Downloading...")),
      );

      final http.Response response = await http.get(Uri.parse(url));

      if (response.statusCode == 200) {
        final bytes = response.bodyBytes;

        // Get storage directory
        final directory = await getApplicationDocumentsDirectory();
        final filePath = "${directory.path}/$fileName";

        final file = File(filePath);
        await file.writeAsBytes(bytes);

        // Download success
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text("File downloaded successfully \n At this: ${directory.path}")),
        );

        //  ASK USER TO OPEN THE DOWNLOADED FILE
        // -------------------------------------


        showDialog(
          context: context,
          builder: (context) {
            return Dialog(
              backgroundColor: Colors.white,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(20),
              ),
              elevation: 0,
              child: Container(
                padding: const EdgeInsets.all(24),
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(20),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black.withOpacity(0.1),
                      blurRadius: 20,
                      offset: const Offset(0, 4),
                    ),
                  ],
                ),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    // Success Icon
                    Container(
                      width: 60,
                      height: 60,
                      decoration: BoxDecoration(
                        color: Colors.green.withOpacity(0.1),
                        shape: BoxShape.circle,
                      ),
                      child: const Icon(
                        Icons.check_circle_rounded,
                        color: Colors.green,
                        size: 36,
                      ),
                    ),
                    const SizedBox(height: 16),

                    // Title
                    const Text(
                      "Download Complete",
                      style: TextStyle(
                        fontSize: 18,
                        fontFamily: "Plus Jakarta Sans",
                        fontWeight: FontWeight.w700,
                        color: Colors.black87,
                      ),
                    ),
                    const SizedBox(height: 8),

                    // Description
                    Text(
                      "Do you want to open the file?",
                      textAlign: TextAlign.center,
                      style: TextStyle(
                        fontSize: 14,
                        fontFamily: "Plus Jakarta Sans",
                        fontWeight: FontWeight.w400,
                        color: Colors.grey[600],
                        height: 1.4,
                      ),
                    ),
                    const SizedBox(height: 24),

                    // Buttons Row
                    Row(
                      children: [
                        // Cancel Button
                        Expanded(
                          child: OutlinedButton(
                            onPressed: () => Navigator.pop(context),
                            style: OutlinedButton.styleFrom(
                              backgroundColor: Colors.transparent,
                              foregroundColor: Colors.grey[600],
                              side: BorderSide(
                                color: Colors.grey[300]!,
                                width: 1.5,
                              ),
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(12),
                              ),
                              padding: const EdgeInsets.symmetric(vertical: 14),
                              elevation: 0,
                            ),
                            child: Text(
                              "Cancel",
                              style: TextStyle(
                                fontFamily: "Plus Jakarta Sans",
                                fontWeight: FontWeight.w600,
                                fontSize: 14,
                                color: Colors.grey[700],
                              ),
                            ),
                          ),
                        ),
                        const SizedBox(width: 12),

                        // Open Button
                        Expanded(
                          child: ElevatedButton(
                            onPressed: () {
                              Navigator.pop(context);
                              OpenFilex.open(filePath);
                            },
                            style: ElevatedButton.styleFrom(
                              backgroundColor: const Color(0xFF008CDE),
                              foregroundColor: Colors.white,
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(12),
                              ),
                              padding: const EdgeInsets.symmetric(vertical: 14),
                              elevation: 0,
                              shadowColor: Colors.transparent,
                            ),
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                const Icon(Icons.open_in_new, size: 18),
                                const SizedBox(width: 6),
                                Text(
                                  "Open",
                                  style: TextStyle(
                                    fontFamily: "Plus Jakarta Sans",
                                    fontWeight: FontWeight.w600,
                                    fontSize: 14,
                                    color: Colors.white,
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            );
          },
        );
      } else {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text("Failed to download file")),
        );
      }
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("Error: $e")),
      );
    }
  }



  Widget fileWidget(BuildContext context) {
    final extension = getFileExtension(widget.fileName);
    switch (extension) {
      case 'jpg':
      case 'jpeg':
      case 'png':
      case 'gif':
      case 'bmp':
      case 'webp':
        return _buildImageViewer();

      case 'pdf':
        return _buildPdfViewer();

      case 'doc':
      case 'docx':
      case 'xls':
      case 'xlsx':
      case 'ppt':
      case 'pptx':
        return _buildDocumentViewer();

      default:
        return _buildUnsupportedViewer();
    }
  }

  Widget _buildImageViewer() {
    return PhotoView(
      imageProvider: CachedNetworkImageProvider(widget.fileUrl),
      loadingBuilder: (context, event) => Center(
        child: Container(
          width: 40,
          height: 40,
          child: CircularProgressIndicator(
            value: event == null ? 0 : event.cumulativeBytesLoaded / (event.expectedTotalBytes ?? 1),
          ),
        ),
      ),
      errorBuilder: (context, error, stackTrace) => Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(Icons.error_outline, color: Colors.red, size: 50),
            SizedBox(height: 10),
            Text(
              'Failed to load image',
              style: TextStyle(fontSize: 16, color: Colors.grey),
            ),
          ],
        ),
      ),
      backgroundDecoration: BoxDecoration(color: Colors.white),
      minScale: PhotoViewComputedScale.contained * 0.5,
      maxScale: PhotoViewComputedScale.covered * 4.0,
      initialScale: PhotoViewComputedScale.contained,
      basePosition: Alignment.center,
      scaleStateController: _scaleStateController,
      controller: _photoViewController,
      enableRotation: true,
      gestureDetectorBehavior: HitTestBehavior.deferToChild,
      filterQuality: FilterQuality.high,
    );
  }

  Widget _buildPdfViewer() {
    return SfPdfViewer.network(
      widget.fileUrl,
      key: GlobalKey(),
      canShowScrollHead: true,
      canShowPaginationDialog: true,
      pageLayoutMode: PdfPageLayoutMode.single,
      interactionMode: PdfInteractionMode.pan,
      enableDoubleTapZooming: true,
      enableTextSelection: true,
      onZoomLevelChanged: (PdfZoomDetails details) {
        // Use the correct property name
        //print('Zoom level changed: ${details.zoomLevel}');
      },
    );
  }

  Widget _buildDocumentViewer() {
    return Stack(
      children: [
        InAppWebView(
          key: webViewKey,
          initialUrlRequest: URLRequest(url: WebUri(widget.fileUrl)),
          androidOnGeolocationPermissionsShowPrompt: (
              InAppWebViewController controller,
              String origin,
              ) async {
            return GeolocationPermissionShowPromptResponse(
              origin: origin,
              allow: true,
              retain: true,
            );
          },
          initialOptions: InAppWebViewGroupOptions(
            crossPlatform: InAppWebViewOptions(
              useShouldOverrideUrlLoading: true,
              mediaPlaybackRequiresUserGesture: false,
              javaScriptEnabled: true,
              clearCache: true,
              supportZoom: true,
            ),
            android: AndroidInAppWebViewOptions(
              useWideViewPort: true,
              loadWithOverviewMode: true,
              allowContentAccess: true,
              geolocationEnabled: true,
              allowFileAccess: true,
              databaseEnabled: true,
              domStorageEnabled: true,
              builtInZoomControls: true,
              displayZoomControls: false,
              safeBrowsingEnabled: true,
              clearSessionCache: true,
              supportMultipleWindows: false,
            ),
            ios: IOSInAppWebViewOptions(
              allowsInlineMediaPlayback: true,
              allowsAirPlayForMediaPlayback: true,
              allowsPictureInPictureMediaPlayback: true,
              allowsBackForwardNavigationGestures: true,
              allowsLinkPreview: true,
              isFraudulentWebsiteWarningEnabled: true,
            ),
          ),
          androidOnPermissionRequest: (
              InAppWebViewController controller,
              String origin,
              List<String> resources,
              ) async {
            return PermissionRequestResponse(
              resources: resources,
              action: PermissionRequestResponseAction.GRANT,
            );
          },
          onWebViewCreated: (controller) {
            webViewController = controller;
            _controller.complete(controller);
          },
          pullToRefreshController: pullToRefreshController,
          onLoadStart: (controller, url) {
            setState(() {
              isLoading = true;
            });
          },
          onLoadStop: (controller, url) {
            pullToRefreshController?.endRefreshing();
            setState(() {
              isLoading = false;
            });

            // Enable zooming in WebView
            controller.evaluateJavascript(source: """
              var meta = document.createElement('meta');
              meta.name = 'viewport';
              meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=4.0, user-scalable=yes';
              document.getElementsByTagName('head')[0].appendChild(meta);
            """);
          },
          onReceivedError: (controller, request, error) {
            pullToRefreshController?.endRefreshing();
            setState(() {
              isLoading = false;
            });
          },
          onProgressChanged: (controller, progress) {
            if (progress == 100) {
              pullToRefreshController?.endRefreshing();
            }
          },
          onConsoleMessage: (controller, consoleMessage) {
            if (kDebugMode) {
              debugPrint("consoleMessage: ${consoleMessage.message}");
            }
          },
        ),

        // Loading indicator for documents
        if (isLoading)
          Positioned.fill(
            child: Container(
              color: Colors.black.withOpacity(0.3),
              child: Center(
                child: Container(
                  padding: EdgeInsets.all(20),
                  decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(10),
                    boxShadow: [
                      BoxShadow(
                        color: Colors.black26,
                        blurRadius: 10,
                      ),
                    ],
                  ),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      CircularProgressIndicator(
                        valueColor: AlwaysStoppedAnimation<Color>(AppColors.app_blue),
                      ),
                      SizedBox(height: 10),
                      Text(
                        'Loading Document...',
                        style: TextStyle(
                          fontSize: 14,
                          color: Colors.grey[700],
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
      ],
    );
  }

  Widget _buildUnsupportedViewer() {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(
            Icons.insert_drive_file,
            size: 64,
            color: Colors.grey[400],
          ),
          SizedBox(height: 16),
          Text(
            'Unsupported File Format',
            style: TextStyle(
              fontSize: 18,
              fontWeight: FontWeight.w600,
              color: Colors.grey[600],
            ),
          ),
          SizedBox(height: 8),
          Text(
            'Format: ${getFileExtension(widget.fileName).toUpperCase()}',
            style: TextStyle(
              fontSize: 14,
              color: Colors.grey[500],
            ),
          ),
          SizedBox(height: 16),
          ElevatedButton.icon(
            onPressed: () {
              _launchUrl(widget.fileUrl);
            },
            icon: Icon(Icons.open_in_new),
            label: Text('Open in External App'),
            style: ElevatedButton.styleFrom(
              backgroundColor: AppColors.app_blue,
              foregroundColor: Colors.white,
            ),
          ),
        ],
      ),
    );
  }

  Future<Uint8List?> _loadPdf(String url) async {
    try {
      final response = await http.get(Uri.parse(url));
      if (response.statusCode == 200) {
        return response.bodyBytes;
      }
    } catch (e) {
      print('Error loading PDF: $e');
    }
    return null;
  }
}