content: import 'package:dart_mappable/dart_mappable.dart';
  
  import 'project.dart';
  
  part 'tutorial.mapper.dart';
  
  @MappableClass()
  class TutorialData with TutorialDataMappable implements ProjectDataBase {
    @override
    final String id;
    @override
    final String description;
    final int currentStep;
    final List<TutorialStepConfig> configs;
    final Map<String, TutorialStep> steps;
  
    TutorialData(this.id, this.description, this.currentStep, this.configs, this.steps);
  
    String get currentStepId => configs[currentStep].id;
    TutorialStep get step => steps[currentStepId]!;
  
    @override
    String? get cssFile => step.cssFile;
  
    @override
    Map<String, String> get dartFiles => step.dartFiles;
  
    @override
    Map<String, String> get allDartFiles => step.allDartFiles;
  
    @override
    String? fileContentFor(String key) => step.fileContentFor(key);
  
    @override
    List<String> get fileNames => step.fileNames;
  
    @override
    String? get htmlFile => step.htmlFile;
  
    @override
    bool isDart(String key) => step.isDart(key);
  
    @override
    String get mainDartFile => step.mainDartFile;
  
    @override
    TutorialData updateContent(String key, String? content) {
      return copyWith.steps.get(currentStepId)!.$update((s) => s.updateContent(key, content));
    }
  
    TutorialData toggleSolution() {
      return copyWith.steps.get(currentStepId)!.$update((s) => s.copyWith(showSolution: !s.showSolution));
    }
  
    @override
    TutorialData copy() => copyWith();
  
    static TutorialData fromConfig(TutorialConfig config) {
      return TutorialData(
        'tutorial-${config.id}',
        config.name,
        config.steps.indexWhere((c) => c.id == config.initialStep.id),
        config.steps,
        {config.initialStep.id: config.initialStep},
      );
    }
  }
  
  @MappableClass()
  class TutorialStep with TutorialStepMappable implements ProjectDataBase {
    @override
    final String id;
    final String name;
  
    final String text;
  
    final ProjectData step;
    final ProjectData? solution;
  
    final bool showSolution;
  
    TutorialStep(this.id, this.name, this.text, this.step, this.solution, [this.showSolution = false]);
  
    ProjectData get data => showSolution && solution != null ? solution! : step;
  
    @override
    Map<String, String> get allDartFiles => data.allDartFiles;
  
    @override
    String? get cssFile => data.cssFile;
  
    @override
    Map<String, String> get dartFiles => data.dartFiles;
  
    @override
    String? get description => data.description;
  
    @override
    String? fileContentFor(String key) => data.fileContentFor(key);
  
    @override
    List<String> get fileNames => data.fileNames;
  
    @override
    String? get htmlFile => data.htmlFile;
  
    @override
    bool isDart(String key) => data.isDart(key);
  
    @override
    String get mainDartFile => data.mainDartFile;
  
    @override
    TutorialStep updateContent(String key, String? content) {
      if (showSolution) {
        return copyWith.solution?.$update((s) => s.updateContent(key, content)) ?? copyWith();
      } else {
        return copyWith.step.$update((s) => s.updateContent(key, content));
      }
    }
  
    @override
    TutorialStep copy() => copyWith();
  }
  
  @MappableClass()
  class TutorialResponse with TutorialResponseMappable {
    TutorialConfig? tutorial;
    String? error;
  
    TutorialResponse(this.tutorial, this.error);
  }
  
  @MappableClass()
  class TutorialConfig with TutorialConfigMappable {
    String id;
    String name;
    List<TutorialStepConfig> steps;
    TutorialStep initialStep;
  
    TutorialConfig(this.id, this.name, this.steps, this.initialStep);
  }
  
  @MappableClass()
  class TutorialStepConfig with TutorialStepConfigMappable {
    String id;
    String name;
  
    TutorialStepConfig(this.id, this.name);
  }
  