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

import '../blocs/wall/wall_bloc.dart';
import '../blocs/wall/wall_event.dart';
import '../blocs/wall/wall_state.dart';
import '../widgets/overview/wall_overview.dart';
import '../widgets/section/section_view.dart';

class MainScreen extends StatefulWidget {
  const MainScreen({super.key});

  @override
  State<MainScreen> createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  String? _selectedSectionId;
  final FocusNode _focusNode = FocusNode();
  WallBloc? _wallBloc;

  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<WallBloc, WallState>(
      builder: (blocContext, state) {
        // Store bloc reference for keyboard handler
        _wallBloc = BlocProvider.of<WallBloc>(blocContext, listen: false);

        return KeyboardListener(
          focusNode: _focusNode,
          autofocus: true,
          onKeyEvent: _handleKeyEvent,
          child: Scaffold(
            backgroundColor: const Color(0xFF0A0E14),
            body: _buildBody(blocContext, state),
          ),
        );
      },
    );
  }

  Widget _buildBody(BuildContext context, WallState state) {
    if (state.isLoading || state.config == null) {
      return const Center(
        child: CircularProgressIndicator(
          color: Color(0xFF00D4FF),
        ),
      );
    }

    // Show section view or wall overview
    if (_selectedSectionId != null) {
      final section = state.config!.sections.firstWhere(
        (s) => s.id == _selectedSectionId,
        orElse: () => state.config!.sections.first,
      );
      return SectionView(
        section: section,
        wallState: state,
        onBack: () => setState(() => _selectedSectionId = null),
        onViewerTap: (viewerId) {
          context.read<WallBloc>().add(SelectViewer(viewerId));
          // Re-request focus for keyboard input after tile tap
          _focusNode.requestFocus();
        },
      );
    }

    return WallOverview(
      config: state.config!,
      wallState: state,
      onSectionTap: (sectionId) {
        setState(() => _selectedSectionId = sectionId);
      },
    );
  }

  void _handleKeyEvent(KeyEvent event) {
    if (event is! KeyDownEvent) return;

    final bloc = _wallBloc;
    if (bloc == null) return;

    final state = bloc.state;
    final key = event.logicalKey;

    // Escape - go back or deselect
    if (key == LogicalKeyboardKey.escape) {
      if (state.selectedViewerId != null) {
        bloc.add(const DeselectViewer());
      } else if (_selectedSectionId != null) {
        setState(() => _selectedSectionId = null);
      }
      return;
    }

    // Only handle camera input when a viewer is selected
    if (state.selectedViewerId == null) return;

    // Digit keys 0-9
    if (key.keyId >= LogicalKeyboardKey.digit0.keyId &&
        key.keyId <= LogicalKeyboardKey.digit9.keyId) {
      final digit = key.keyId - LogicalKeyboardKey.digit0.keyId;
      bloc.add(AddCameraDigit(digit));
      return;
    }

    // Numpad digits
    if (key.keyId >= LogicalKeyboardKey.numpad0.keyId &&
        key.keyId <= LogicalKeyboardKey.numpad9.keyId) {
      final digit = key.keyId - LogicalKeyboardKey.numpad0.keyId;
      bloc.add(AddCameraDigit(digit));
      return;
    }

    // Enter - execute CrossSwitch
    if (key == LogicalKeyboardKey.enter ||
        key == LogicalKeyboardKey.numpadEnter) {
      if (state.canExecuteCrossSwitch) {
        bloc.add(const ExecuteCrossSwitch());
      }
      return;
    }

    // Backspace - remove last digit
    if (key == LogicalKeyboardKey.backspace) {
      bloc.add(const BackspaceCameraDigit());
      return;
    }

    // Delete - cancel edit
    if (key == LogicalKeyboardKey.delete) {
      bloc.add(const CancelCameraEdit());
      return;
    }

    // Escape - cancel edit or deselect
    if (key == LogicalKeyboardKey.escape) {
      if (state.isEditing) {
        bloc.add(const CancelCameraEdit());
      } else {
        bloc.add(const DeselectViewer());
      }
      return;
    }

    // F1-F3 for prefix selection
    if (key == LogicalKeyboardKey.f1) {
      bloc.add(const SetCameraPrefix(500));
      return;
    }
    if (key == LogicalKeyboardKey.f2) {
      bloc.add(const SetCameraPrefix(501));
      return;
    }
    if (key == LogicalKeyboardKey.f3) {
      bloc.add(const SetCameraPrefix(502));
      return;
    }
  }
}
