part of 'json_bloc.dart';

typedef JsonStateIndexedEventCreator = JsonEvent Function(int index);
typedef JsonStateStringEventCreator = JsonEvent Function(String value);

enum UIType { list, input }

/// Состояние по умолчанию
@immutable
class JsonState {
  final String title;
  final Key key;
  final List<OptionData> options;
  final String? urlPath;
  final bool? isLive;
  final int? initialIndex;
  final int? currentIndex;
  final JsonState? parent;
  final bool isFinal;
  final UIType uiType;
  final JsonStateIndexedEventCreator? createIndexedEvent;
  final JsonStateStringEventCreator? createStringEvent;

  const JsonState({
    required this.title,
    required this.key,
    this.options = const [],
    this.urlPath,
    this.isLive,
    this.initialIndex,
    this.currentIndex,
    this.parent,
    this.isFinal = false,
    required this.uiType,
    this.createIndexedEvent,
    this.createStringEvent
  });

  factory JsonState.create() {
    return JsonState(
      title: '1. Выберите способ получения конфига',
      key: const Key('ChooseWayToGetConfigListID'),
      options: const [
        OptionData(key: Key('ListElementConfigLinkID'), title: 'Ссылка на конфиг'),
        OptionData(key: Key('ListElementFirebaseID'), title: 'Firebase')
      ],
      uiType: UIType.list,
      createIndexedEvent: (index) => ChooseWayToGetConfigEvent(index),
    );
  }
}

/// Состояние, когда выбран пункт "Ссылка на конфиг"
class ConfigLinkChosenOptionState extends JsonState {
  const ConfigLinkChosenOptionState(
      String title,
      Key key,
      List<OptionData> options,
      int? initialIndex,
      JsonState? parent,
      UIType uiType,
      JsonStateIndexedEventCreator? createIndexedEvent
  ): super(
      title: title,
      key: key,
      options: options,
      initialIndex: initialIndex,
      parent: parent,
      uiType: uiType,
      createIndexedEvent: createIndexedEvent
  );

  factory ConfigLinkChosenOptionState.create(JsonState? parent) {
    return ConfigLinkChosenOptionState(
        '2. Выберите способ получения ссылки',
        const Key('ChooseWayToGetUrlListID'),
        const [
          OptionData(key: Key('ListElementUseUrlExampleID'), title: 'Использовать пример ссылки'),
          OptionData(key: Key('ListElementUseOwnUrlID'), title: 'Указать свою')
        ],
        0,
        parent,
        UIType.list,
        (index) => ChooseWayToGetLinkEvent(index)
    );
  }
}

/// Состояние, когда выбран пункт "Firebase"
class FirebaseChosenOptionState extends JsonState {
  const FirebaseChosenOptionState(
      String title,
      Key key,
      List<OptionData> options,
      String? urlPath,
      bool? isLive,
      int? initialIndex,
      int? currentIndex,
      JsonState? parent,
      bool isFinal,
      UIType uiType,
      JsonStateIndexedEventCreator? createIndexedEvent
  ): super(
      title: title,
      key: key,
      urlPath: urlPath,
      isLive: isLive,
      options: options,
      initialIndex: initialIndex,
      currentIndex: currentIndex,
      parent: parent,
      isFinal: isFinal,
      uiType: uiType,
      createIndexedEvent: createIndexedEvent
  );

  factory FirebaseChosenOptionState.create(JsonState? parent, List<OptionData> options, int? selectedIndex) {
    final String? currentUrlPath;
    if (selectedIndex != null) {
      currentUrlPath = options[selectedIndex].value;
    } else {
      currentUrlPath = null;
    }

    return FirebaseChosenOptionState(
        '2. Выберите файл конфига',
        const Key('ChooseFirebasebConfigListID'),
        options,
        currentUrlPath,
        false,
        1,
        selectedIndex,
        parent,
        selectedIndex != null,
        UIType.list,
        (index) => ChooseFirebaseConfigEvent(index)
    );
  }
}

/// Состояние, когда выбран пункт "Использовать пример ссылки"
class UseLinkExampleState extends JsonState {
  const UseLinkExampleState(
      String title,
      Key key,
      String? urlPath,
      List<OptionData> options,
      int? initialIndex,
      int? currentIndex,
      JsonState? parent,
      bool isFinal,
      UIType uiType,
      JsonStateIndexedEventCreator? createIndexedEvent
  ): super(
      title: title,
      key: key,
      urlPath: urlPath,
      options: options,
      initialIndex: initialIndex,
      currentIndex: currentIndex,
      parent: parent,
      isFinal: isFinal,
      uiType: uiType,
      createIndexedEvent: createIndexedEvent
  );

  factory UseLinkExampleState.create({JsonState? parent, int? selectedIndex}) {
    var options = const [
      OptionData(key: Key('ListElementUrl1ID'), title: 'Статистика (GET)', value: 'http://chest-101.gc.nut.team:8000/play/opt/5edd1215b2e34a3eb70654a117ea2935'),
      OptionData(key: Key('ListElementUrl2ID'), title: 'Статистика (POST)', value: 'http://chest-101.gc.nut.team:8000/play/opt/5edd1215b2e34a3eb70654a117ea2937'),
      OptionData(key: Key('ListElementUrl3ID'), title: 'Субтитры (SRT)', value: 'http://chest-101.gc.nut.team:8000/play/opt/e1dc888381e04b4290924dd9ec7b33ed'),
    ];

    final String? currentUrlPath;
    if (selectedIndex != null) {
      currentUrlPath = options[selectedIndex].value;
    } else {
      currentUrlPath = null;
    }

    return UseLinkExampleState(
        '3. Выберите пример ссылки',
        const Key('ChooseUrlExampleListID'),
        currentUrlPath,
        options,
        0,
        selectedIndex,
        parent,
        selectedIndex != null,
        UIType.list,
        (index) => ChooseExampleLinkEvent(index)
    );
  }
}

/// Состояние, когда выбран пункт "Указать свою"
class UseJsonOwnLinkState extends JsonState {
  const UseJsonOwnLinkState(
      String title,
      Key key,
      String? urlPath,
      bool? isLive,
      int? initialIndex,
      JsonState? parent,
      bool isFinal,
      UIType uiType,
      JsonStateStringEventCreator? createStringEvent
  ): super(
      title: title,
      key: key,
      urlPath: urlPath,
      isLive: isLive,
      initialIndex: initialIndex,
      parent: parent,
      isFinal: isFinal,
      uiType: uiType,
      createStringEvent: createStringEvent
  );

  factory UseJsonOwnLinkState.create({JsonState? parent, String? urlPath, bool? isLive}) {
    var finalUrlPath = urlPath ?? '';
    return UseJsonOwnLinkState(
        '3. Укажите ссылку',
        const Key('TypeOwnUrlViewID'),
        finalUrlPath,
        isLive,
        1,
        parent,
        finalUrlPath.isNotEmpty,
        UIType.input,
        (value) => TypeOwnLinkEvent(value, isLive)
    );
  }
}