import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:screen_retriever/screen_retriever.dart';

/// Persists and restores window position and size.
class WindowPersistence {
  static File get _configFile {
    String dir;
    if (Platform.isWindows) {
      dir = '${Platform.environment['APPDATA'] ?? Platform.environment['USERPROFILE'] ?? '.'}/imajviewer';
    } else {
      dir = '${Platform.environment['HOME'] ?? '/tmp'}/.config/imajviewer';
    }
    return File('$dir/window.json');
  }

  /// Save window rect synchronously (safe to call before destroy).
  static void saveSync({
    required Offset position,
    required Size size,
  }) {
    final file = _configFile;
    file.parent.createSync(recursive: true);
    file.writeAsStringSync(jsonEncode({
      'x': position.dx.toInt(),
      'y': position.dy.toInt(),
      'width': size.width.toInt(),
      'height': size.height.toInt(),
    }));
  }

  /// Restore saved window rect. Returns null if no saved config.
  static ({Offset position, Size size})? restore() {
    final file = _configFile;
    if (!file.existsSync()) return null;

    try {
      final data = jsonDecode(file.readAsStringSync()) as Map<String, dynamic>;
      final x = (data['x'] as num?)?.toDouble() ?? 0;
      final y = (data['y'] as num?)?.toDouble() ?? 0;
      final w = (data['width'] as num?)?.toDouble() ?? 1280;
      final h = (data['height'] as num?)?.toDouble() ?? 800;

      if (w < 200 || h < 200 || x < -1000 || y < -1000) return null;

      return (
        position: Offset(x, y),
        size: Size(w, h),
      );
    } catch (_) {
      return null;
    }
  }

  /// Cascade: place new window to the right of the previous one.
  /// Falls to the next row (row start) when it would overflow the screen,
  /// and wraps to the top-left if the next row also overflows.
  static Future<Offset> cascadePosition({
    required Offset previousPosition,
    required Size previousSize,
  }) async {
    try {
      final displays = await screenRetriever.getAllDisplays();

      // Önceki pencerenin bulunduğu monitörü bul (çoklu monitör desteği)
      Display display = await screenRetriever.getPrimaryDisplay();
      for (final d in displays) {
        final pos = d.visiblePosition;
        final size = d.visibleSize ?? d.size;
        if (pos != null &&
            previousPosition.dx >= pos.dx &&
            previousPosition.dx < pos.dx + size.width &&
            previousPosition.dy >= pos.dy &&
            previousPosition.dy < pos.dy + size.height) {
          display = d;
          break;
        }
      }

      final workLeft = display.visiblePosition?.dx ?? 0;
      final workTop = display.visiblePosition?.dy ?? 0;
      final workWidth = display.visibleSize?.width ?? display.size.width;
      final workHeight = display.visibleSize?.height ?? display.size.height;

      var x = previousPosition.dx + previousSize.width;
      var y = previousPosition.dy;

      if (x + previousSize.width > workLeft + workWidth) {
        x = workLeft;
        y = previousPosition.dy + previousSize.height;
      }

      if (y + previousSize.height > workTop + workHeight) {
        x = workLeft;
        y = workTop;
      }

      return Offset(x, y);
    } catch (_) {
      // Fallback: keep previous position if screen info is unavailable.
      return previousPosition;
    }
  }
}
