// lib/remote/remote_models.dart
import 'url_utils.dart';

class RemotePhotoItem {
  final String id;
  final String name;
  final String path;
  final String? thub1, thub2;
  final String? mimeType;
  final int? width, height, sizeBytes;
  final int? rotation;

  /// EXIF/metadata
  final DateTime? takenAtUtc;
  final String? dataExifLegacy;

  /// GPS + location
  final double? lat, lng, alt;
  final RemoteLocation? location;

  /// extra
  final String? user;
  final String? cartella;     // ✅ utile (folder)
  final String? fastHash;     // ✅ utile per link locale<->remoto
  final int? durationMillis;

  /// ✅ Timestamp server-side per sync robusta
  final DateTime? createdAtUtc;
  final DateTime? updatedAtUtc;
  final DateTime? deletedAtUtc; // soft delete

  /// ✅ timestamp file (ms) dal server (per dateModifiedMillis DB)
  final int? mtimeMs;

  RemotePhotoItem({
    required this.id,
    required this.name,
    required this.path,
    this.thub1,
    this.thub2,
    this.mimeType,
    this.width,
    this.height,
    this.rotation,
    this.sizeBytes,
    this.takenAtUtc,
    this.dataExifLegacy,
    this.lat,
    this.lng,
    this.alt,
    this.user,
    this.cartella,
    this.fastHash,
    this.durationMillis,
    this.location,
    this.createdAtUtc,
    this.updatedAtUtc,
    this.deletedAtUtc,
    this.mtimeMs,
  });

  // Costruzione URL assoluto delegata a utility (in base alle impostazioni)
  String absoluteUrl(String baseUrl) => buildAbsoluteUri(baseUrl, path).toString();

  static DateTime? _tryParseIsoUtc(dynamic v) {
    if (v == null) return null;
    try {
      return DateTime.parse(v.toString()).toUtc();
    } catch (_) {
      return null;
    }
  }

  static double? _toDouble(dynamic v) {
    if (v == null) return null;
    if (v is num) return v.toDouble();
    return double.tryParse(v.toString());
  }

  /// Converte secondi→ms se < 1000, altrimenti assume già millisecondi.
  static int? _toMillis(dynamic v) {
    if (v == null) return null;
    final num? n = (v is num) ? v : num.tryParse(v.toString());
    if (n == null) return null;
    return n >= 1000 ? n.toInt() : (n * 1000).toInt();
  }

  static int? _toIntMs(dynamic v) {
    if (v == null) return null;
    final num? n = (v is num) ? v : num.tryParse(v.toString());
    if (n == null) return null;
    // mtimeMs nel tuo esempio è float: 1775724485418.3494
    return n.round();
  }

  /// ✅ helper: soft delete?
  bool get isSoftDeleted => deletedAtUtc != null;

  factory RemotePhotoItem.fromJson(Map<String, dynamic> j) {
    final gps = j['gps'] as Map<String, dynamic>?;
    final loc = j['location'] is Map<String, dynamic>
        ? RemoteLocation.fromJson(j['location'] as Map<String, dynamic>)
        : null;

    return RemotePhotoItem(
      id: (j['id'] ?? j['name']).toString(),
      name: (j['name'] ?? '').toString(),
      path: (j['path'] ?? '').toString(),
      thub1: j['thub1']?.toString(),
      thub2: j['thub2']?.toString(),
      mimeType: j['mime_type']?.toString(),
      width: (j['width'] as num?)?.toInt(),
      height: (j['height'] as num?)?.toInt(),
      rotation: (j['rotation'] as num?)?.toInt(),
      sizeBytes: (j['size_bytes'] as num?)?.toInt(),

      takenAtUtc: _tryParseIsoUtc(j['taken_at']),
      dataExifLegacy: j['data']?.toString(),

      lat: gps != null ? _toDouble(gps['lat']) : null,
      lng: gps != null ? _toDouble(gps['lng']) : null,
      alt: gps != null ? _toDouble(gps['alt']) : null,

      user: j['user']?.toString(),
      cartella: j['cartella']?.toString(),
      fastHash: j['fast_hash']?.toString(),

      // durata: dal server è duration_ms
      durationMillis: _toMillis(j['duration_ms']),

      location: loc,

      // ✅ campi sync
      createdAtUtc: _tryParseIsoUtc(j['created_at']),
      updatedAtUtc: _tryParseIsoUtc(j['updated_at']),
      deletedAtUtc: _tryParseIsoUtc(j['deleted_at']),

      // ✅ per DB dateModifiedMillis
      mtimeMs: _toIntMs(j['mtimeMs']),
    );
  }
}

class RemoteLocation {
  final String? continent;
  final String? country;
  final String? region;
  final String? postcode;
  final String? city;
  final String? countyCode;
  final String? address;
  final String? timezone;
  final String? timeOffset;

  RemoteLocation({
    this.continent,
    this.country,
    this.region,
    this.postcode,
    this.city,
    this.countyCode,
    this.address,
    this.timezone,
    this.timeOffset,
  });

  factory RemoteLocation.fromJson(Map<String, dynamic> j) => RemoteLocation(
        continent: j['continent']?.toString(),
        country: j['country']?.toString(),
        region: j['region']?.toString(),
        postcode: j['postcode']?.toString(),
        city: j['city']?.toString(),
        countyCode: j['county_code']?.toString(),
        address: j['address']?.toString(),
        timezone: j['timezone']?.toString(),
        timeOffset: j['time']?.toString(),
      );
}
