import 'package:equatable/equatable.dart';

/// Configuration for a physical monitor that can display 1-4 viewers
class PhysicalMonitor extends Equatable {
  final int id;
  final String? name;
  final List<int> viewerIds; // 1-4 viewer IDs in this physical monitor
  final bool isQuadView;
  final int row; // Grid row position (1-based)
  final int col; // Grid column position (1-based)
  final int rowSpan; // How many rows this monitor spans
  final int colSpan; // How many columns this monitor spans

  const PhysicalMonitor({
    required this.id,
    this.name,
    required this.viewerIds,
    this.isQuadView = false,
    this.row = 1,
    this.col = 1,
    this.rowSpan = 1,
    this.colSpan = 1,
  });

  /// Whether this monitor has multiple viewers (quad view)
  bool get hasMultipleViewers => viewerIds.length > 1;

  /// Get the primary viewer ID (first one)
  int get primaryViewerId => viewerIds.isNotEmpty ? viewerIds.first : 0;

  factory PhysicalMonitor.fromJson(Map<String, dynamic> json) {
    final viewers = json['viewer_ids'] as List<dynamic>?;
    return PhysicalMonitor(
      id: json['id'] as int,
      name: json['name'] as String?,
      viewerIds: viewers?.map((v) => v as int).toList() ?? [],
      isQuadView: json['is_quad_view'] as bool? ?? false,
      row: json['row'] as int? ?? 1,
      col: json['col'] as int? ?? 1,
      rowSpan: json['row_span'] as int? ?? 1,
      colSpan: json['col_span'] as int? ?? 1,
    );
  }

  Map<String, dynamic> toJson() => {
        'id': id,
        'name': name,
        'viewer_ids': viewerIds,
        'is_quad_view': isQuadView,
        'row': row,
        'col': col,
        'row_span': rowSpan,
        'col_span': colSpan,
      };

  @override
  List<Object?> get props => [id, name, viewerIds, isQuadView, row, col, rowSpan, colSpan];
}

/// A section of the video wall (e.g., "Vrchní část", "Pravá část")
class WallSection extends Equatable {
  final String id;
  final String name;
  final List<PhysicalMonitor> monitors;
  final int columns; // Grid layout columns for this section
  final int rows; // Grid layout rows for this section

  const WallSection({
    required this.id,
    required this.name,
    required this.monitors,
    this.columns = 8,
    this.rows = 4,
  });

  factory WallSection.fromJson(Map<String, dynamic> json) {
    final monitors = json['monitors'] as List<dynamic>?;
    return WallSection(
      id: json['id'] as String,
      name: json['name'] as String,
      monitors: monitors
              ?.map((m) => PhysicalMonitor.fromJson(m as Map<String, dynamic>))
              .toList() ??
          [],
      columns: json['columns'] as int? ?? 8,
      rows: json['rows'] as int? ?? 4,
    );
  }

  Map<String, dynamic> toJson() => {
        'id': id,
        'name': name,
        'monitors': monitors.map((m) => m.toJson()).toList(),
        'columns': columns,
        'rows': rows,
      };

  @override
  List<Object?> get props => [id, name, monitors, columns, rows];
}

/// Complete wall configuration with all sections
class WallConfig extends Equatable {
  final String id;
  final String name;
  final List<WallSection> sections;
  final List<int> alarmMonitorIds; // Monitor IDs designated for alarms

  const WallConfig({
    required this.id,
    required this.name,
    required this.sections,
    this.alarmMonitorIds = const [],
  });

  /// Get all viewer IDs across all sections
  List<int> get allViewerIds {
    final ids = <int>[];
    for (final section in sections) {
      for (final monitor in section.monitors) {
        ids.addAll(monitor.viewerIds);
      }
    }
    return ids;
  }

  /// Get all physical monitors across all sections
  List<PhysicalMonitor> get allMonitors {
    final monitors = <PhysicalMonitor>[];
    for (final section in sections) {
      monitors.addAll(section.monitors);
    }
    return monitors;
  }

  /// Find physical monitor containing a viewer ID
  PhysicalMonitor? findMonitorByViewerId(int viewerId) {
    for (final section in sections) {
      for (final monitor in section.monitors) {
        if (monitor.viewerIds.contains(viewerId)) {
          return monitor;
        }
      }
    }
    return null;
  }

  /// Find section containing a viewer ID
  WallSection? findSectionByViewerId(int viewerId) {
    for (final section in sections) {
      for (final monitor in section.monitors) {
        if (monitor.viewerIds.contains(viewerId)) {
          return section;
        }
      }
    }
    return null;
  }

  factory WallConfig.fromJson(Map<String, dynamic> json) {
    final sections = json['sections'] as List<dynamic>?;
    final alarmIds = json['alarm_monitor_ids'] as List<dynamic>?;
    return WallConfig(
      id: json['id'] as String,
      name: json['name'] as String,
      sections: sections
              ?.map((s) => WallSection.fromJson(s as Map<String, dynamic>))
              .toList() ??
          [],
      alarmMonitorIds: alarmIds?.map((i) => i as int).toList() ?? [],
    );
  }

  Map<String, dynamic> toJson() => {
        'id': id,
        'name': name,
        'sections': sections.map((s) => s.toJson()).toList(),
        'alarm_monitor_ids': alarmMonitorIds,
      };

  /// Create sample wall config matching D6 app structure
  factory WallConfig.sample() {
    return WallConfig(
      id: 'wall_1',
      name: 'Hlavní videostěna',
      sections: [
        // Vrchní část - 8 columns x 4 rows irregular grid
        WallSection(
          id: 'top',
          name: 'Vrchní část',
          columns: 8,
          rows: 4,
          monitors: [
            // Row 1-2: Three quad monitors
            PhysicalMonitor(
              id: 1,
              viewerIds: [210, 211, 212, 213],
              isQuadView: true,
              row: 1, col: 1, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 2,
              viewerIds: [214, 215, 216, 217],
              isQuadView: true,
              row: 1, col: 3, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 3,
              viewerIds: [1001, 1002, 1003, 1004],
              isQuadView: true,
              row: 1, col: 5, rowSpan: 2, colSpan: 2,
            ),
            // Row 4: Single monitor
            PhysicalMonitor(
              id: 4,
              viewerIds: [222],
              row: 4, col: 2, rowSpan: 1, colSpan: 1,
            ),
            // Row 3-4: Three quad monitors
            PhysicalMonitor(
              id: 5,
              viewerIds: [223, 224, 225, 226],
              isQuadView: true,
              row: 3, col: 3, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 6,
              viewerIds: [227, 228, 229, 230],
              isQuadView: true,
              row: 3, col: 5, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 7,
              viewerIds: [231, 232, 233, 234],
              isQuadView: true,
              row: 3, col: 7, rowSpan: 2, colSpan: 2,
            ),
          ],
        ),
        // Levá část - 7 columns x 6 rows
        WallSection(
          id: 'left',
          name: 'Levá část',
          columns: 7,
          rows: 6,
          monitors: [
            // Row 1-2: 3x2 monitor + two 2x2 quads
            PhysicalMonitor(
              id: 8,
              viewerIds: [88, 89, 90, 91, 92, 93],
              row: 1, col: 1, rowSpan: 2, colSpan: 3,
            ),
            PhysicalMonitor(
              id: 9,
              viewerIds: [40, 41, 42, 43],
              isQuadView: true,
              row: 1, col: 4, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 10,
              viewerIds: [44, 45, 46, 47],
              isQuadView: true,
              row: 1, col: 6, rowSpan: 2, colSpan: 2,
            ),
            // Row 3-4: Two 2x2 quads
            PhysicalMonitor(
              id: 11,
              viewerIds: [48, 49, 50, 51],
              isQuadView: true,
              row: 3, col: 4, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 12,
              viewerIds: [52, 53, 54, 55],
              isQuadView: true,
              row: 3, col: 6, rowSpan: 2, colSpan: 2,
            ),
            // Row 5-6: Two 2x2 quads
            PhysicalMonitor(
              id: 13,
              viewerIds: [56, 57, 58, 59],
              isQuadView: true,
              row: 5, col: 4, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 14,
              viewerIds: [60, 61, 62, 63],
              isQuadView: true,
              row: 5, col: 6, rowSpan: 2, colSpan: 2,
            ),
          ],
        ),
        // Střed stěny - 8 columns x 4 rows
        WallSection(
          id: 'center',
          name: 'Střed stěny',
          columns: 8,
          rows: 4,
          monitors: [
            // Row 1-2: Quad + 4 tall single monitors
            PhysicalMonitor(
              id: 15,
              viewerIds: [14, 15, 16, 17],
              isQuadView: true,
              row: 1, col: 2, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(id: 16, viewerIds: [18], row: 1, col: 4, rowSpan: 2, colSpan: 1),
            PhysicalMonitor(id: 17, viewerIds: [19], row: 1, col: 5, rowSpan: 2, colSpan: 1),
            PhysicalMonitor(id: 18, viewerIds: [20], row: 1, col: 6, rowSpan: 2, colSpan: 1),
            PhysicalMonitor(id: 19, viewerIds: [21], row: 1, col: 7, rowSpan: 2, colSpan: 1),
            // Row 3-4: Four 2x2 quads
            PhysicalMonitor(
              id: 20,
              viewerIds: [24, 25, 32, 33],
              isQuadView: true,
              row: 3, col: 1, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 21,
              viewerIds: [26, 27, 34, 35],
              isQuadView: true,
              row: 3, col: 3, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 22,
              viewerIds: [28, 29, 36, 37],
              isQuadView: true,
              row: 3, col: 5, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 23,
              viewerIds: [30, 31, 38, 39],
              isQuadView: true,
              row: 3, col: 7, rowSpan: 2, colSpan: 2,
            ),
          ],
        ),
        // Pravá část - 7 columns x 6 rows
        WallSection(
          id: 'right',
          name: 'Pravá část',
          columns: 7,
          rows: 6,
          monitors: [
            // Row 1-2: Two 2x2 quads + 3x2 monitor
            PhysicalMonitor(
              id: 24,
              viewerIds: [64, 65, 66, 67],
              isQuadView: true,
              row: 1, col: 1, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 25,
              viewerIds: [68, 69, 70, 71],
              isQuadView: true,
              row: 1, col: 3, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 26,
              viewerIds: [94, 95, 96, 97, 98, 99],
              row: 1, col: 5, rowSpan: 2, colSpan: 3,
            ),
            // Row 3-4: Two 2x2 quads
            PhysicalMonitor(
              id: 27,
              viewerIds: [72, 73, 74, 75],
              isQuadView: true,
              row: 3, col: 1, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 28,
              viewerIds: [76, 77, 78, 79],
              isQuadView: true,
              row: 3, col: 3, rowSpan: 2, colSpan: 2,
            ),
            // Row 5-6: Two 2x2 quads
            PhysicalMonitor(
              id: 29,
              viewerIds: [80, 81, 82, 83],
              isQuadView: true,
              row: 5, col: 1, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 30,
              viewerIds: [84, 85, 86, 87],
              isQuadView: true,
              row: 5, col: 3, rowSpan: 2, colSpan: 2,
            ),
          ],
        ),
        // Stupínek - 8 columns x 4 rows
        WallSection(
          id: 'bottom',
          name: 'Stupínek',
          columns: 8,
          rows: 4,
          monitors: [
            // Row 1-2: Three 2x2 quads
            PhysicalMonitor(
              id: 31,
              viewerIds: [183, 184, 185, 186],
              isQuadView: true,
              row: 1, col: 1, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 32,
              viewerIds: [187, 188, 189, 190],
              isQuadView: true,
              row: 1, col: 3, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 33,
              viewerIds: [191, 192, 193, 194],
              isQuadView: true,
              row: 1, col: 5, rowSpan: 2, colSpan: 2,
            ),
            // Row 3-4: Two 2x2 quads
            PhysicalMonitor(
              id: 34,
              viewerIds: [195, 196, 197, 198],
              isQuadView: true,
              row: 3, col: 5, rowSpan: 2, colSpan: 2,
            ),
            PhysicalMonitor(
              id: 35,
              viewerIds: [199, 200, 201, 202],
              isQuadView: true,
              row: 3, col: 7, rowSpan: 2, colSpan: 2,
            ),
          ],
        ),
      ],
      alarmMonitorIds: [222, 223, 224], // Example alarm monitors
    );
  }

  @override
  List<Object?> get props => [id, name, sections, alarmMonitorIds];
}
