import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import '../../../domain/entities/wall_config.dart';
import '../../blocs/wall/wall_bloc.dart';
import '../../blocs/wall/wall_event.dart';
import '../../blocs/wall/wall_state.dart';

/// Full section view matching D6 app design
class SectionView extends StatelessWidget {
  final WallSection section;
  final WallState wallState;
  final VoidCallback onBack;
  final Function(int viewerId) onViewerTap;

  const SectionView({
    super.key,
    required this.section,
    required this.wallState,
    required this.onBack,
    required this.onViewerTap,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      color: const Color(0xFF555555), // D6 background color
      child: Column(
        children: [
          // Header bar
          _HeaderBar(
            section: section,
            wallState: wallState,
          ),
          // Monitors grid - takes all available space
          Expanded(
            child: _MonitorsGrid(
              section: section,
              wallState: wallState,
              onViewerTap: onViewerTap,
            ),
          ),
          // Bottom toolbar with circular icons
          _BottomIconBar(
            wallState: wallState,
            onSegmentsTap: onBack,
          ),
        ],
      ),
    );
  }
}

class _HeaderBar extends StatelessWidget {
  final WallSection section;
  final WallState wallState;

  const _HeaderBar({
    required this.section,
    required this.wallState,
  });

  @override
  Widget build(BuildContext context) {
    // Get section number from id
    final sectionNum = _getSectionNumber(section.id);

    return Container(
      height: 44,
      padding: const EdgeInsets.symmetric(horizontal: 8),
      color: const Color(0xFF555555),
      child: Row(
        children: [
          // Video camera icon (matching D6 app)
          const Icon(
            Icons.videocam,
            color: Colors.white,
            size: 24,
          ),
          const SizedBox(width: 8),
          // Section name
          Text(
            '$sectionNum | ${section.name}',
            style: const TextStyle(
              color: Colors.white,
              fontSize: 20,
              fontWeight: FontWeight.w500,
            ),
          ),
          const Spacer(),
          // Status message (red when server unavailable)
          const Text(
            'Aplikační server není dostupný, některé funkce nejsou k dispozici',
            style: TextStyle(
              color: Color(0xFFFF4444),
              fontSize: 18,
              fontWeight: FontWeight.w500,
            ),
          ),
          const SizedBox(width: 8),
          // Status icons
          const Icon(Icons.dns, color: Color(0xFFFF4444), size: 28),
          const SizedBox(width: 6),
          const Icon(Icons.lan, color: Color(0xFF24FF00), size: 28),
        ],
      ),
    );
  }

  int _getSectionNumber(String id) {
    switch (id) {
      case 'left': return 1;
      case 'center': return 2;
      case 'right': return 3;
      case 'top': return 4;
      case 'bottom': return 5;
      default: return 0;
    }
  }
}

class _MonitorsGrid extends StatelessWidget {
  final WallSection section;
  final WallState wallState;
  final Function(int viewerId) onViewerTap;

  const _MonitorsGrid({
    required this.section,
    required this.wallState,
    required this.onViewerTap,
  });

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        final monitors = section.monitors;
        final gridCols = section.columns;
        final gridRows = section.rows;

        // Calculate cell dimensions based on grid size
        final cellWidth = constraints.maxWidth / gridCols;
        final cellHeight = constraints.maxHeight / gridRows;

        // Build a map of which physical monitor each grid cell belongs to
        final cellToMonitor = <String, PhysicalMonitor>{};
        for (final monitor in monitors) {
          for (int r = 0; r < monitor.rowSpan; r++) {
            for (int c = 0; c < monitor.colSpan; c++) {
              final gridRow = monitor.row - 1 + r;
              final gridCol = monitor.col - 1 + c;
              cellToMonitor['$gridRow,$gridCol'] = monitor;
            }
          }
        }

        // Position monitors using their explicit row/col values
        return Stack(
          children: [
            // First layer: monitor content without borders
            ...monitors.map((monitor) {
              final row = monitor.row - 1;
              final col = monitor.col - 1;

              return Positioned(
                left: col * cellWidth,
                top: row * cellHeight,
                width: monitor.colSpan * cellWidth,
                height: monitor.rowSpan * cellHeight,
                child: _PhysicalMonitorContent(
                  monitor: monitor,
                  wallState: wallState,
                  onViewerTap: onViewerTap,
                ),
              );
            }),
            // Second layer: border overlay
            Positioned.fill(
              child: IgnorePointer(
                child: CustomPaint(
                  painter: _GridBorderPainter(
                    monitors: monitors,
                    gridCols: gridCols,
                    gridRows: gridRows,
                    cellToMonitor: cellToMonitor,
                  ),
                ),
              ),
            ),
          ],
        );
      },
    );
  }
}


/// Custom painter that draws all grid borders with correct colors
class _GridBorderPainter extends CustomPainter {
  final List<PhysicalMonitor> monitors;
  final int gridCols;
  final int gridRows;
  final Map<String, PhysicalMonitor> cellToMonitor;

  static const _borderWidth = 2.0;
  static const _cyanColor = Color(0xFF00BFFF);
  static const _darkColor = Color(0xFF4A4A4A);

  _GridBorderPainter({
    required this.monitors,
    required this.gridCols,
    required this.gridRows,
    required this.cellToMonitor,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final cellWidth = size.width / gridCols;
    final cellHeight = size.height / gridRows;

    final cyanPaint = Paint()
      ..color = _cyanColor
      ..strokeWidth = _borderWidth
      ..style = PaintingStyle.stroke;

    final darkPaint = Paint()
      ..color = _darkColor
      ..strokeWidth = _borderWidth
      ..style = PaintingStyle.stroke;

    // Collect all border segments, draw dark first then cyan on top
    final darkLines = <_LineSegment>[];
    final cyanLines = <_LineSegment>[];

    // Collect horizontal lines
    for (int row = 0; row <= gridRows; row++) {
      for (int col = 0; col < gridCols; col++) {
        final x1 = col * cellWidth;
        final x2 = (col + 1) * cellWidth;
        final y = row * cellHeight;

        final cellAbove = row > 0 ? cellToMonitor['${row - 1},$col'] : null;
        final cellBelow = row < gridRows ? cellToMonitor['$row,$col'] : null;

        // Only draw border if at least one side has a physical monitor
        if (cellAbove == null && cellBelow == null) continue;

        // Cyan if: edge of physical monitor (one side empty or different monitor)
        final isCyan = cellAbove == null || cellBelow == null ||
                       cellAbove.id != cellBelow.id;

        // Skip internal borders for single-viewer monitors
        if (!isCyan && cellAbove != null && cellAbove.viewerIds.length == 1) {
          continue;
        }

        final segment = _LineSegment(Offset(x1, y), Offset(x2, y));
        if (isCyan) {
          cyanLines.add(segment);
        } else {
          darkLines.add(segment);
        }
      }
    }

    // Collect vertical lines
    for (int col = 0; col <= gridCols; col++) {
      for (int row = 0; row < gridRows; row++) {
        final x = col * cellWidth;
        final y1 = row * cellHeight;
        final y2 = (row + 1) * cellHeight;

        final cellLeft = col > 0 ? cellToMonitor['$row,${col - 1}'] : null;
        final cellRight = col < gridCols ? cellToMonitor['$row,$col'] : null;

        // Only draw border if at least one side has a physical monitor
        if (cellLeft == null && cellRight == null) continue;

        // Cyan if: edge of physical monitor (one side empty or different monitor)
        final isCyan = cellLeft == null || cellRight == null ||
                       cellLeft.id != cellRight.id;

        // Skip internal borders for single-viewer monitors
        if (!isCyan && cellLeft != null && cellLeft.viewerIds.length == 1) {
          continue;
        }

        final segment = _LineSegment(Offset(x, y1), Offset(x, y2));
        if (isCyan) {
          cyanLines.add(segment);
        } else {
          darkLines.add(segment);
        }
      }
    }

    // Draw dark borders first (behind)
    for (final line in darkLines) {
      canvas.drawLine(line.start, line.end, darkPaint);
    }

    // Draw cyan borders on top (in front)
    for (final line in cyanLines) {
      canvas.drawLine(line.start, line.end, cyanPaint);
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

class _LineSegment {
  final Offset start;
  final Offset end;
  _LineSegment(this.start, this.end);
}

/// Physical monitor content without borders (borders drawn by overlay)
class _PhysicalMonitorContent extends StatelessWidget {
  final PhysicalMonitor monitor;
  final WallState wallState;
  final Function(int viewerId) onViewerTap;

  const _PhysicalMonitorContent({
    required this.monitor,
    required this.wallState,
    required this.onViewerTap,
  });

  @override
  Widget build(BuildContext context) {
    final viewers = monitor.viewerIds;

    // Single viewer fills entire monitor space
    if (viewers.length == 1) {
      final viewerId = viewers.first;
      final isSelected = wallState.isViewerSelected(viewerId);
      return _ViewerTile(
        viewerId: viewerId,
        viewerState: wallState.getViewerState(viewerId),
        isSelected: isSelected,
        cameraInputDisplay: isSelected ? wallState.cameraInputDisplay : null,
        onTap: () => onViewerTap(viewerId),
      );
    }

    // Multiple viewers: determine grid based on viewer count and monitor shape
    final gridCols = monitor.colSpan;
    final gridRows = monitor.rowSpan;

    return Column(
      children: List.generate(gridRows, (row) {
        return Expanded(
          child: Row(
            children: List.generate(gridCols, (col) {
              final index = row * gridCols + col;

              if (index >= viewers.length) {
                return Expanded(
                  child: Container(
                    color: const Color(0xFF6A6A6A),
                  ),
                );
              }

              final viewerId = viewers[index];
              final isSelected = wallState.isViewerSelected(viewerId);
              return Expanded(
                child: _ViewerTile(
                  viewerId: viewerId,
                  viewerState: wallState.getViewerState(viewerId),
                  isSelected: isSelected,
                  cameraInputDisplay: isSelected ? wallState.cameraInputDisplay : null,
                  onTap: () => onViewerTap(viewerId),
                ),
              );
            }),
          ),
        );
      }),
    );
  }
}

class _ViewerTile extends StatelessWidget {
  final int viewerId;
  final ViewerState viewerState;
  final bool isSelected;
  final String? cameraInputDisplay;
  final VoidCallback onTap;

  const _ViewerTile({
    required this.viewerId,
    required this.viewerState,
    required this.isSelected,
    this.cameraInputDisplay,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    // D6 style: selected = cyan fill, alarm = red, normal = gray
    Color bgColor;
    if (isSelected) {
      bgColor = const Color(0xFF00D4FF); // Cyan fill for selected
    } else if (viewerState.hasAlarm) {
      bgColor = const Color(0xFFDC2626); // Red for alarm
    } else {
      bgColor = const Color(0xFF6A6A6A); // Gray for normal
    }

    return GestureDetector(
      onTap: onTap,
      child: Container(
        color: bgColor,
        child: Padding(
          padding: const EdgeInsets.only(top: 8),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              // Viewer ID at top (smaller)
              Text(
                '$viewerId',
                style: TextStyle(
                  color: isSelected ? Colors.white : Colors.white,
                  fontSize: 14,
                  fontWeight: FontWeight.w400,
                ),
              ),
              // Camera number - large white text, matching D6 style
              if (isSelected && cameraInputDisplay != null)
                Padding(
                  padding: const EdgeInsets.only(top: 2),
                  child: Text(
                    cameraInputDisplay!,
                    style: const TextStyle(
                      color: Colors.white,
                      fontSize: 28,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
            ],
          ),
        ),
      ),
    );
  }
}

class _ViewerTileWithBorder extends StatelessWidget {
  final int viewerId;
  final ViewerState viewerState;
  final bool isSelected;
  final String? cameraInputDisplay;
  final VoidCallback onTap;
  final Border border;

  const _ViewerTileWithBorder({
    required this.viewerId,
    required this.viewerState,
    required this.isSelected,
    this.cameraInputDisplay,
    required this.onTap,
    required this.border,
  });

  @override
  Widget build(BuildContext context) {
    // D6 style: selected = cyan fill, alarm = red, normal = gray
    Color bgColor;
    if (isSelected) {
      bgColor = const Color(0xFF00D4FF); // Cyan fill for selected
    } else if (viewerState.hasAlarm) {
      bgColor = const Color(0xFFDC2626); // Red for alarm
    } else {
      bgColor = const Color(0xFF6A6A6A); // Gray for normal
    }

    return GestureDetector(
      onTap: onTap,
      child: Container(
        decoration: BoxDecoration(
          color: bgColor,
          border: border,
        ),
        child: Padding(
          padding: const EdgeInsets.only(top: 8),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              // Viewer ID at top (smaller)
              Text(
                '$viewerId',
                style: const TextStyle(
                  color: Colors.white,
                  fontSize: 14,
                  fontWeight: FontWeight.w400,
                ),
              ),
              // Camera number - large white text, matching D6 style
              if (isSelected && cameraInputDisplay != null)
                Padding(
                  padding: const EdgeInsets.only(top: 2),
                  child: Text(
                    cameraInputDisplay!,
                    style: const TextStyle(
                      color: Colors.white,
                      fontSize: 28,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
            ],
          ),
        ),
      ),
    );
  }
}

class _BottomIconBar extends StatelessWidget {
  final WallState wallState;
  final VoidCallback onSegmentsTap;

  const _BottomIconBar({
    required this.wallState,
    required this.onSegmentsTap,
  });

  @override
  Widget build(BuildContext context) {
    final hasSelection = wallState.selectedViewerId != null;

    return Container(
      height: 86,
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
      color: const Color(0xFF555555),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          // Search
          _CircleIconButton(
            icon: Icons.search,
            isActive: hasSelection,
            onTap: () {},
          ),
          // Lock
          _CircleIconButton(
            icon: Icons.lock_outline,
            onTap: () {},
          ),
          // Quad view
          _CircleIconButton(
            icon: Icons.grid_view,
            onTap: () {},
          ),
          // Segments - navigate to overview
          _CircleIconButton(
            icon: Icons.apps,
            isActive: true,
            onTap: onSegmentsTap,
          ),
          // Image/Camera
          _CircleIconButton(
            icon: Icons.image_outlined,
            onTap: () {},
          ),
          // Alarm (red)
          _CircleIconButton(
            icon: Icons.notification_important,
            iconColor: const Color(0xFFCC4444),
            onTap: () {},
          ),
          // History
          _CircleIconButton(
            icon: Icons.history,
            onTap: () {},
          ),
          // Monitor
          _CircleIconButton(
            icon: Icons.tv,
            onTap: () {},
          ),
          // Prefix selector
          _PrefixButton(
            prefix: wallState.cameraPrefix,
            onTap: () {
              // Cycle through prefixes
              final nextPrefix = wallState.cameraPrefix == 500 ? 501
                  : wallState.cameraPrefix == 501 ? 502 : 500;
              context.read<WallBloc>().add(SetCameraPrefix(nextPrefix));
            },
          ),
        ],
      ),
    );
  }
}

class _CircleIconButton extends StatelessWidget {
  final IconData icon;
  final bool isActive;
  final Color? iconColor;
  final VoidCallback onTap;

  const _CircleIconButton({
    required this.icon,
    this.isActive = false,
    this.iconColor,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
        width: 64,
        height: 64,
        decoration: BoxDecoration(
          shape: BoxShape.circle,
          border: Border.all(
            color: isActive ? Colors.white : Colors.white38,
            width: 2,
          ),
          color: isActive ? const Color(0xFF333333) : Colors.transparent,
        ),
        child: Icon(
          icon,
          color: iconColor ?? (isActive ? Colors.white : Colors.white60),
          size: 38,
        ),
      ),
    );
  }
}

class _PrefixButton extends StatelessWidget {
  final int prefix;
  final VoidCallback onTap;

  const _PrefixButton({
    required this.prefix,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
        width: 64,
        height: 64,
        decoration: BoxDecoration(
          shape: BoxShape.circle,
          border: Border.all(color: Colors.white, width: 2),
          color: const Color(0xFF333333),
        ),
        child: Center(
          child: Text(
            '$prefix',
            style: const TextStyle(
              color: Colors.white,
              fontSize: 20,
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
      ),
    );
  }
}
