// lib/widgets/cast/cast_controller.dart
// NUOVA VERSIONE MODULARE
// - Orchestratore leggero
// - Nessuna logica Google/DLNA/FAST
// - Delega tutto ai backend specializzati

import 'package:flutter/material.dart';
import 'package:aves/model/entry/entry.dart';

import 'backends/google_cast_backend.dart';
import 'backends/fast_cast_backend.dart';
import 'backends/dlna_cast_backend.dart';

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

enum CastBackend { google, fast, dlna }
enum CastIconState { idle, connecting, connected }

class CastController {
  CastController._();
  static final CastController instance = CastController._();

  static const _prefBackend = 'cast_backend';

  // Stato UI unificato (rimane qui)
  final castIconState = ValueNotifier(CastIconState.idle);
  final isCastingNotifier = ValueNotifier(false);
  final currentIndexNotifier = ValueNotifier(0);

  final isPlayingNotifier = ValueNotifier(false);
  final isBufferingNotifier = ValueNotifier(false);
  final positionNotifier = ValueNotifier(Duration.zero);
  final durationNotifier = ValueNotifier(Duration.zero);

  final volumeNotifier = ValueNotifier(1.0);
  final isMutedNotifier = ValueNotifier(false);

  // Backend selezionato (persistenza opzionale)
  final backendNotifier = ValueNotifier(CastBackend.google);

  // Backend attivo
  late CastBackendBase backend;

  // ------------------------------------------------------------
  // SELEZIONE BACKEND
  // ------------------------------------------------------------
  Future<void> setBackend(CastBackend type) async {
    backendNotifier.value = type;

    // Persistenza
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(_prefBackend, type.name);

    // Ricrea backend
    switch (type) {
      case CastBackend.google:
        backend = GoogleCastBackend(this);
        GoogleCastController.instance.activateMethodChannelHandler();
        break;

      case CastBackend.fast:
        backend = FastCastBackend(this);
        // FAST non deve toccare il MethodChannel Google
        break;

      case CastBackend.dlna:
        backend = DlnaCastBackend(this);
        // DLNA non deve toccare il MethodChannel Google
        break;
    }

    // Reset stato icona
    castIconState.value = CastIconState.idle;
    isCastingNotifier.value = false;
  }

  Future<void> loadSavedBackend() async {
    final prefs = await SharedPreferences.getInstance();
    final saved = prefs.getString(_prefBackend);

    CastBackend type;

    switch (saved) {
      case 'google':
        type = CastBackend.google;
        break;
      case 'fast':
        type = CastBackend.fast;
        break;
      case 'dlna':
        type = CastBackend.dlna;
        break;
      default:
        type = CastBackend.google;
    }

    await setBackend(type);
  }

  // ------------------------------------------------------------
  // API UNIFICATA (DELEGA AI BACKEND)
  // ------------------------------------------------------------

  Future<void> startCast(List<AvesEntry> entries, int index) =>
      backend.startCast(entries, index);

  Future<void> startFullscreen(List<AvesEntry> entries, int index) =>
      backend.startFullscreen(entries, index);

  Future<void> startSlideshow(List<AvesEntry> entries, int index) =>
      backend.startSlideshow(entries, index);

  Future<void> startManualQueue(List<AvesEntry> entries, int index) =>
      backend.startManualQueue(entries, index);

  Future<void> nextManual() => backend.nextManual();

  Future<void> prevManual() => backend.prevManual();

  Future<void> stopCast() => backend.stopCast();

  // ------------------------------------------------------------
  // Accesso diretto al controller Google Cast (per dialog Android)
  // ------------------------------------------------------------
  GoogleCastController get google => GoogleCastController.instance;
}

// ------------------------------------------------------------
// CLASSE BASE PER TUTTI I BACKEND
// ------------------------------------------------------------
abstract class CastBackendBase {
  final CastController controller;
  CastBackendBase(this.controller);

  Future<void> startCast(List<AvesEntry> entries, int index);
  Future<void> startFullscreen(List<AvesEntry> entries, int index);
  Future<void> startSlideshow(List<AvesEntry> entries, int index);
  Future<void> startManualQueue(List<AvesEntry> entries, int index);

  Future<void> nextManual();
  Future<void> prevManual();
  Future<void> stopCast();

  // PATCH: ogni backend decide il delay dello slideshow
  Duration? getNextDelay(AvesEntry entry);
}
