class HistoryResponse {
  final Map<String, HistoryItem> items;

  HistoryResponse({required this.items});

  factory HistoryResponse.fromJson(Map<String, dynamic> json) {
    return HistoryResponse(
      items:
          json.map((key, value) => MapEntry(key, HistoryItem.fromJson(value))),
    );
  }
}

class HistoryItem {
  final Prompt prompt;
  final Outputs outputs;
  final Status status;
  final Map<String, Meta> meta;

  HistoryItem({
    required this.prompt,
    required this.outputs,
    required this.status,
    required this.meta,
  });

  factory HistoryItem.fromJson(Map<String, dynamic> json) {
    return HistoryItem(
      prompt: Prompt.fromJson(json['prompt']),
      outputs: Outputs.fromJson(json['outputs']),
      status: Status.fromJson(json['status']),
      meta: (json['meta'] as Map<String, dynamic>).map(
        (key, value) => MapEntry(key, Meta.fromJson(value)),
      ),
    );
  }
}

class Prompt {
  final int id;
  final String promptId;
  final Map<String, Node> nodes;
  final ExtraPngInfo extraPngInfo;

  Prompt({
    required this.id,
    required this.promptId,
    required this.nodes,
    required this.extraPngInfo,
  });

  factory Prompt.fromJson(List<dynamic> json) {
    return Prompt(
      id: json[0] as int,
      promptId: json[1] as String,
      nodes: (json[2] as Map<String, dynamic>).map(
        (key, value) => MapEntry(key, Node.fromJson(value)),
      ),
      extraPngInfo: ExtraPngInfo.fromJson(json[3]['extra_pnginfo']),
    );
  }
}

class Node {
  final Map<String, dynamic> inputs;
  final String classType;
  final Meta meta;

  Node({
    required this.inputs,
    required this.classType,
    required this.meta,
  });

  factory Node.fromJson(Map<String, dynamic> json) {
    return Node(
      inputs: json['inputs'] as Map<String, dynamic>,
      classType: json['class_type'] as String,
      meta: Meta.fromJson(json['_meta']),
    );
  }
}

class ExtraPngInfo {
  final Workflow workflow;

  ExtraPngInfo({required this.workflow});

  factory ExtraPngInfo.fromJson(Map<String, dynamic> json) {
    return ExtraPngInfo(
      workflow: Workflow.fromJson(json['workflow']),
    );
  }
}

class Workflow {
  final List<NodeInfo> nodes;
  final List<Link> links;

  Workflow({
    required this.nodes,
    required this.links,
  });

  factory Workflow.fromJson(Map<String, dynamic> json) {
    return Workflow(
      nodes: (json['nodes'] as List<dynamic>)
          .map((e) => NodeInfo.fromJson(e))
          .toList(),
      links: (json['links'] as List<dynamic>)
          .map((e) => Link.fromJson(e))
          .toList(),
    );
  }
}

class NodeInfo {
  final int id;
  final String type;

  NodeInfo({
    required this.id,
    required this.type,
  });

  factory NodeInfo.fromJson(Map<String, dynamic> json) {
    return NodeInfo(
      id: json['id'] as int,
      type: json['type'] as String,
    );
  }
}

class Link {
  final int id;
  final int sourceNodeId;
  final int targetNodeId;

  Link({
    required this.id,
    required this.sourceNodeId,
    required this.targetNodeId,
  });

  factory Link.fromJson(List<dynamic> json) {
    return Link(
      id: json[0] as int,
      sourceNodeId: json[1] as int,
      targetNodeId: json[2] as int,
    );
  }
}

class Outputs {
  final Map<String, OutputNode> nodes;

  Outputs({required this.nodes});

  factory Outputs.fromJson(Map<String, dynamic> json) {
    return Outputs(
      nodes:
          json.map((key, value) => MapEntry(key, OutputNode.fromJson(value))),
    );
  }
}

class OutputNode {
  final List<Image> images;

  OutputNode({required this.images});

  factory OutputNode.fromJson(Map<String, dynamic> json) {
    return OutputNode(
      images: (json['images'] as List<dynamic>)
          .map((e) => Image.fromJson(e))
          .toList(),
    );
  }
}

class Image {
  final String filename;
  final String subfolder;
  final String type;

  Image({
    required this.filename,
    required this.subfolder,
    required this.type,
  });

  factory Image.fromJson(Map<String, dynamic> json) {
    return Image(
      filename: json['filename'] as String,
      subfolder: json['subfolder'] as String,
      type: json['type'] as String,
    );
  }
}

class Status {
  final String statusStr;
  final bool completed;

  Status({
    required this.statusStr,
    required this.completed,
  });

  factory Status.fromJson(Map<String, dynamic> json) {
    return Status(
      statusStr: json['status_str'] as String,
      completed: json['completed'] as bool,
    );
  }
}

class Meta {
  final String? nodeId;

  Meta({this.nodeId});

  factory Meta.fromJson(Map<String, dynamic> json) {
    return Meta(
      nodeId: json['node_id'] as String?,
    );
  }
}
