import 'dart:async';
import 'dart:convert';

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../domain/flyer_import_result.dart';

class FlyerImportSession {
  final int? sessionId;
  final String? fileName;
  final FlyerImportResult? result;
  final Map<int, bool> selected;

  const FlyerImportSession({
    this.sessionId,
    this.fileName,
    this.result,
    this.selected = const {},
  });

  FlyerImportSession copyWith({
    int? sessionId,
    String? fileName,
    FlyerImportResult? result,
    Map<int, bool>? selected,
  }) {
    return FlyerImportSession(
      sessionId: sessionId ?? this.sessionId,
      fileName: fileName ?? this.fileName,
      result: result ?? this.result,
      selected: selected ?? this.selected,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'sessionId': sessionId,
      'fileName': fileName,
      'selected': selected.map((k, v) => MapEntry(k.toString(), v)),
    };
  }

  factory FlyerImportSession.fromJson(Map<String, dynamic> json) {
    final selectedRaw = (json['selected'] as Map<String, dynamic>? ?? {});
    final selected = <int, bool>{};
    for (final entry in selectedRaw.entries) {
      final key = int.tryParse(entry.key);
      if (key == null) continue;
      selected[key] = entry.value == true;
    }

    return FlyerImportSession(
      sessionId: (json['sessionId'] as num?)?.toInt(),
      fileName: json['fileName'] as String?,
      result: null,
      selected: selected,
    );
  }
}

class FlyerImportSessionNotifier extends Notifier<FlyerImportSession?> {
  static const _storageKey = 'flyer_import_session_v1';

  @override
  FlyerImportSession? build() => null;

  Future<void> restore() async {
    final prefs = await SharedPreferences.getInstance();
    final raw = prefs.getString(_storageKey);
    if (raw == null || raw.isEmpty) return;

    try {
      final decoded = jsonDecode(raw);
      if (decoded is Map<String, dynamic>) {
        state = FlyerImportSession.fromJson(decoded);
      }
    } catch (_) {
      await prefs.remove(_storageKey);
    }
  }

  void setImportedResult({
    required FlyerImportResult result,
    required Map<int, bool> selected,
    String? fileName,
  }) {
    state = FlyerImportSession(
      sessionId: result.sessionId,
      fileName: fileName,
      result: result,
      selected: selected,
    );
    unawaited(_persist());
  }

  void setSelected(int index, bool value) {
    if (state == null) return;
    final selected = Map<int, bool>.from(state!.selected)..[index] = value;
    state = state!.copyWith(selected: selected);
    unawaited(_persist());
  }

  void setSelectedForAll(int count, bool value) {
    if (state == null) return;
    final selected = <int, bool>{for (var i = 0; i < count; i++) i: value};
    state = state!.copyWith(selected: selected);
    unawaited(_persist());
  }

  Future<void> clear() async {
    state = null;
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(_storageKey);
  }

  Future<void> _persist() async {
    final prefs = await SharedPreferences.getInstance();
    if (state == null) {
      await prefs.remove(_storageKey);
      return;
    }
    await prefs.setString(_storageKey, jsonEncode(state!.toJson()));
  }
}

final flyerImportSessionProvider =
    NotifierProvider<FlyerImportSessionNotifier, FlyerImportSession?>(
  FlyerImportSessionNotifier.new,
);
