import 'dart:math';

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

import '../../focus/focusable_text_field.dart';
import '../../models/companion_remote/remote_command.dart';
import '../../models/companion_remote/remote_session.dart';
import '../../i18n/strings.g.dart';
import '../../mixins/controller_disposer_mixin.dart';
import '../../providers/companion_remote_provider.dart';
import '../../utils/platform_detector.dart';
import '../../theme/mono_tokens.dart';
import '../../utils/app_logger.dart';
import '../../utils/dialogs.dart';
import '../../widgets/companion_remote/discovery_view.dart';
import '../../widgets/overlay_sheet.dart';
import '../../widgets/pill_input_decoration.dart';

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

  @override
  State<MobileRemoteScreen> createState() => _MobileRemoteScreenState();
}

class _MobileRemoteScreenState extends State<MobileRemoteScreen> {
  @override
  Widget build(BuildContext context) {
    return OverlaySheetHost(
      child: Scaffold(
        appBar: AppBar(
          title: Text(t.companionRemote.title),
          actions: [
            Consumer<CompanionRemoteProvider>(
              builder: (context, provider, child) {
                if (provider.isConnected) {
                  return IconButton(
                    icon: const Icon(Icons.link_off),
                    onPressed: () async {
                      final confirmed = await showConfirmDialog(
                        context,
                        title: t.common.disconnect,
                        message: t.companionRemote.remote.disconnectConfirm,
                        confirmText: t.common.disconnect,
                        isDestructive: true,
                      );

                      if (confirmed && context.mounted) {
                        await context.read<CompanionRemoteProvider>().leaveSession();
                      }
                    },
                    tooltip: t.common.disconnect,
                  );
                }
                return const SizedBox.shrink();
              },
            ),
          ],
        ),
        body: Consumer<CompanionRemoteProvider>(
          builder: (context, provider, child) {
            if (provider.status == RemoteSessionStatus.reconnecting) {
              return Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    const CircularProgressIndicator(),
                    const SizedBox(height: 24),
                    Text(t.companionRemote.remote.reconnecting, style: Theme.of(context).textTheme.titleLarge),
                    const SizedBox(height: 8),
                    Text(
                      t.companionRemote.remote.attemptOf(current: provider.reconnectAttempts),
                      style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.grey),
                    ),
                    const SizedBox(height: 32),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        OutlinedButton(onPressed: () => provider.cancelReconnect(), child: Text(t.common.cancel)),
                        const SizedBox(width: 16),
                        FilledButton(
                          onPressed: () => provider.retryReconnectNow(),
                          child: Text(t.companionRemote.remote.retryNow),
                        ),
                      ],
                    ),
                  ],
                ),
              );
            }

            if (!provider.isConnected) {
              return const DiscoveryView();
            }

            return const _RemoteControlLayout();
          },
        ),
      ),
    );
  }
}

class _RemoteControlLayout extends StatelessWidget {
  const _RemoteControlLayout();

  @override
  Widget build(BuildContext context) {
    if (PlatformDetector.isDesktop(context)) {
      return Center(
        child: ConstrainedBox(constraints: const BoxConstraints(maxWidth: 400), child: const _RemoteControlContent()),
      );
    }

    return const _RemoteControlContent();
  }
}

class _RemoteControlContent extends StatefulWidget {
  const _RemoteControlContent();

  @override
  State<_RemoteControlContent> createState() => _RemoteControlContentState();
}

class _RemoteControlContentState extends State<_RemoteControlContent> {
  int _selectedTab = 0;

  void _showSearchSheet({bool switchToSearchTab = false}) {
    if (switchToSearchTab) {
      _sendCommand(RemoteCommandType.tabSearch);
    }
    final provider = context.read<CompanionRemoteProvider>();
    OverlaySheetController.of(context).show(builder: (_) => _SearchBottomSheet(provider: provider));
  }

  void _sendCommand(RemoteCommandType type) {
    HapticFeedback.lightImpact();
    appLogger.d('MobileRemoteScreen: Sending command: $type');
    final provider = context.read<CompanionRemoteProvider>();
    provider.sendCommand(type);
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Consumer<CompanionRemoteProvider>(
          builder: (context, provider, child) {
            final device = provider.connectedDevice;
            if (device == null) return const SizedBox.shrink();

            return Container(
              padding: const EdgeInsets.all(16),
              color: Theme.of(context).colorScheme.primaryContainer,
              child: Row(
                children: [
                  Icon(Icons.computer, color: Theme.of(context).colorScheme.onPrimaryContainer),
                  const SizedBox(width: 12),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          device.name,
                          style: Theme.of(
                            context,
                          ).textTheme.titleMedium?.copyWith(color: Theme.of(context).colorScheme.onPrimaryContainer),
                        ),
                        Text(
                          device.platform,
                          style: Theme.of(
                            context,
                          ).textTheme.bodySmall?.copyWith(color: Theme.of(context).colorScheme.onPrimaryContainer),
                        ),
                      ],
                    ),
                  ),
                  Container(
                    width: 8,
                    height: 8,
                    decoration: const BoxDecoration(color: Colors.green, shape: BoxShape.circle),
                  ),
                ],
              ),
            );
          },
        ),
        Expanded(
          child: ListView(
            padding: const EdgeInsets.all(16),
            children: [
              SegmentedButton<int>(
                showSelectedIcon: false,
                segments: [
                  ButtonSegment(
                    value: 0,
                    label: Text(t.companionRemote.remote.tabRemote),
                    icon: const Icon(Icons.navigation),
                  ),
                  ButtonSegment(
                    value: 1,
                    label: Text(t.companionRemote.remote.tabPlay),
                    icon: const Icon(Icons.play_arrow),
                  ),
                  ButtonSegment(
                    value: 2,
                    label: Text(t.companionRemote.remote.tabMore),
                    icon: const Icon(Icons.flash_on),
                  ),
                ],
                selected: {_selectedTab},
                onSelectionChanged: (Set<int> selection) {
                  setState(() {
                    _selectedTab = selection.first;
                  });
                },
              ),
              const SizedBox(height: 24),
              if (_selectedTab == 0) _buildNavigationTab(),
              if (_selectedTab == 1) _buildPlaybackTab(),
              if (_selectedTab == 2) _buildQuickActionsTab(),
            ],
          ),
        ),
      ],
    );
  }

  Widget _buildNavigationTab() {
    final isPlayerActive = context.watch<CompanionRemoteProvider>().isPlayerActive;

    return Column(
      children: [
        const SizedBox(height: 16),
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            _RemoteButton(
              icon: Icons.home,
              label: t.common.home,
              onPressed: () => _sendCommand(RemoteCommandType.home),
            ),
            _RemoteButton(
              icon: Icons.arrow_back,
              label: t.common.back,
              onPressed: () => _sendCommand(RemoteCommandType.back),
            ),
            _RemoteButton(
              icon: Icons.menu,
              label: t.companionRemote.remote.menu,
              onPressed: () => _sendCommand(RemoteCommandType.contextMenu),
            ),
          ],
        ),
        const SizedBox(height: 32),
        Center(child: _DPad(onCommand: _sendCommand)),
        if (!isPlayerActive) ...[
          const SizedBox(height: 32),
          Text(t.companionRemote.remote.tabNavigation, style: Theme.of(context).textTheme.titleMedium),
          const SizedBox(height: 16),
          Wrap(
            spacing: 8,
            runSpacing: 8,
            alignment: WrapAlignment.center,
            children: [
              _RemoteChip(
                icon: Icons.explore,
                label: t.companionRemote.remote.tabDiscover,
                onPressed: () => _sendCommand(RemoteCommandType.tabDiscover),
              ),
              _RemoteChip(
                icon: Icons.video_library,
                label: t.companionRemote.remote.tabLibraries,
                onPressed: () => _sendCommand(RemoteCommandType.tabLibraries),
              ),
              _RemoteChip(
                icon: Icons.search,
                label: t.companionRemote.remote.tabSearch,
                onPressed: () => _showSearchSheet(switchToSearchTab: true),
              ),
              _RemoteChip(
                icon: Icons.download,
                label: t.companionRemote.remote.tabDownloads,
                onPressed: () => _sendCommand(RemoteCommandType.tabDownloads),
              ),
              _RemoteChip(
                icon: Icons.settings,
                label: t.companionRemote.remote.tabSettings,
                onPressed: () => _sendCommand(RemoteCommandType.tabSettings),
              ),
            ],
          ),
        ],
      ],
    );
  }

  Widget _buildPlaybackTab() {
    return Column(
      children: [
        const SizedBox(height: 16),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            _RemoteButton(
              icon: Icons.skip_previous,
              label: t.companionRemote.remote.previous,
              onPressed: () => _sendCommand(RemoteCommandType.previousTrack),
            ),
            const SizedBox(width: 16),
            _RemoteButton(
              icon: Icons.play_arrow,
              label: t.companionRemote.remote.playPause,
              size: 64,
              iconSize: 36,
              onPressed: () => _sendCommand(RemoteCommandType.playPause),
            ),
            const SizedBox(width: 16),
            _RemoteButton(
              icon: Icons.skip_next,
              label: t.companionRemote.remote.next,
              onPressed: () => _sendCommand(RemoteCommandType.nextTrack),
            ),
          ],
        ),
        const SizedBox(height: 24),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            _RemoteButton(
              icon: Icons.replay_10,
              label: t.companionRemote.remote.seekBack,
              onPressed: () => _sendCommand(RemoteCommandType.seekBackward),
            ),
            const SizedBox(width: 16),
            _RemoteButton(
              icon: Icons.stop,
              label: t.companionRemote.remote.stop,
              onPressed: () => _sendCommand(RemoteCommandType.stop),
            ),
            const SizedBox(width: 16),
            _RemoteButton(
              icon: Icons.forward_10,
              label: t.companionRemote.remote.seekForward,
              onPressed: () => _sendCommand(RemoteCommandType.seekForward),
            ),
          ],
        ),
        const SizedBox(height: 32),
        Text(t.companionRemote.remote.volume, style: Theme.of(context).textTheme.titleMedium),
        const SizedBox(height: 16),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            _RemoteButton(
              icon: Icons.volume_off,
              label: t.common.mute,
              onPressed: () => _sendCommand(RemoteCommandType.volumeMute),
            ),
            const SizedBox(width: 16),
            _RemoteButton(
              icon: Icons.volume_down,
              label: t.companionRemote.remote.volumeDown,
              onPressed: () => _sendCommand(RemoteCommandType.volumeDown),
            ),
            const SizedBox(width: 16),
            _RemoteButton(
              icon: Icons.volume_up,
              label: t.companionRemote.remote.volumeUp,
              onPressed: () => _sendCommand(RemoteCommandType.volumeUp),
            ),
          ],
        ),
      ],
    );
  }

  Widget _buildQuickActionsTab() {
    final isPlayerActive = context.watch<CompanionRemoteProvider>().isPlayerActive;

    return Column(
      children: [
        const SizedBox(height: 16),
        Wrap(
          spacing: 12,
          runSpacing: 12,
          alignment: WrapAlignment.center,
          children: [
            if (!isPlayerActive) _RemoteCard(icon: Icons.search, label: t.common.search, onPressed: _showSearchSheet),
            if (isPlayerActive) ...[
              _RemoteCard(
                icon: Icons.fullscreen,
                label: t.companionRemote.remote.fullscreen,
                onPressed: () => _sendCommand(RemoteCommandType.fullscreen),
              ),
              _RemoteCard(
                icon: Icons.subtitles,
                label: t.companionRemote.remote.subtitles,
                onPressed: () => _sendCommand(RemoteCommandType.subtitles),
              ),
              _RemoteCard(
                icon: Icons.audiotrack,
                label: t.companionRemote.remote.audio,
                onPressed: () => _sendCommand(RemoteCommandType.audioTracks),
              ),
            ],
          ],
        ),
      ],
    );
  }
}

class _DPad extends StatelessWidget {
  final Function(RemoteCommandType) onCommand;

  const _DPad({required this.onCommand});

  static const _diameter = 220.0;
  static const _centerSize = 80.0;
  static const _gapWidth = 3.0;

  @override
  Widget build(BuildContext context) {
    final colors = Theme.of(context).colorScheme;

    return SizedBox(
      width: _diameter,
      height: _diameter,
      child: ClipOval(
        child: Stack(
          children: [
            Container(
              decoration: BoxDecoration(shape: BoxShape.circle, color: colors.surface),
            ),
            _DPadZone(
              startAngle: -135,
              icon: Icons.keyboard_arrow_up,
              onTap: () => onCommand(RemoteCommandType.dpadUp),
            ),
            _DPadZone(
              startAngle: -45,
              icon: Icons.keyboard_arrow_right,
              onTap: () => onCommand(RemoteCommandType.dpadRight),
            ),
            _DPadZone(
              startAngle: 45,
              icon: Icons.keyboard_arrow_down,
              onTap: () => onCommand(RemoteCommandType.dpadDown),
            ),
            _DPadZone(
              startAngle: 135,
              icon: Icons.keyboard_arrow_left,
              onTap: () => onCommand(RemoteCommandType.dpadLeft),
            ),
            Center(child: _DPadCenter(onTap: () => onCommand(RemoteCommandType.select))),
          ],
        ),
      ),
    );
  }
}

class _DPadZone extends StatefulWidget {
  final double startAngle;
  final IconData icon;
  final VoidCallback onTap;

  const _DPadZone({required this.startAngle, required this.icon, required this.onTap});

  Alignment get iconAlignment {
    final midRad = (startAngle + 45) * pi / 180;
    const r = 0.78;
    return Alignment(r * cos(midRad), r * sin(midRad));
  }

  @override
  State<_DPadZone> createState() => _DPadZoneState();
}

class _DPadZoneState extends State<_DPadZone> {
  bool _pressed = false;

  @override
  Widget build(BuildContext context) {
    final colors = Theme.of(context).colorScheme;

    return Positioned.fill(
      child: ClipPath(
        clipper: _SectorClipper(
          startAngle: widget.startAngle,
          innerRadius: _DPad._centerSize / 2 + _DPad._gapWidth,
          gapWidth: _DPad._gapWidth,
        ),
        child: GestureDetector(
          behavior: HitTestBehavior.opaque,
          onTapDown: (_) => setState(() => _pressed = true),
          onTapUp: (_) => setState(() => _pressed = false),
          onTapCancel: () => setState(() => _pressed = false),
          onTap: () {
            HapticFeedback.lightImpact();
            widget.onTap();
          },
          child: AnimatedContainer(
            duration: tokens(context).fast,
            color: _pressed ? colors.primary.withValues(alpha: 0.8) : colors.primary,
            alignment: widget.iconAlignment,
            child: Icon(widget.icon, size: 28, color: colors.onPrimary),
          ),
        ),
      ),
    );
  }
}

class _DPadCenter extends StatefulWidget {
  final VoidCallback onTap;

  const _DPadCenter({required this.onTap});

  @override
  State<_DPadCenter> createState() => _DPadCenterState();
}

class _DPadCenterState extends State<_DPadCenter> {
  bool _pressed = false;

  @override
  Widget build(BuildContext context) {
    final colors = Theme.of(context).colorScheme;

    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTapDown: (_) => setState(() => _pressed = true),
      onTapUp: (_) => setState(() => _pressed = false),
      onTapCancel: () => setState(() => _pressed = false),
      onTap: () {
        HapticFeedback.lightImpact();
        widget.onTap();
      },
      child: AnimatedContainer(
        duration: tokens(context).fast,
        width: _DPad._centerSize,
        height: _DPad._centerSize,
        decoration: BoxDecoration(
          shape: BoxShape.circle,
          color: _pressed ? colors.primary.withValues(alpha: 0.8) : colors.primary,
        ),
        child: const SizedBox.shrink(),
      ),
    );
  }
}

class _SectorClipper extends CustomClipper<Path> {
  final double startAngle;
  final double innerRadius;
  final double gapWidth;

  const _SectorClipper({required this.startAngle, required this.innerRadius, required this.gapWidth});

  @override
  Path getClip(Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final outerRadius = size.width / 2;
    final halfGap = gapWidth / 2;
    final startRad = startAngle * pi / 180;
    final endRad = startRad + pi / 2;

    // Use arcsin to compute angular offset at each radius for constant-width gap
    final innerOffset = asin(halfGap / innerRadius);
    final outerOffset = asin(halfGap / outerRadius);

    final innerStart = startRad + innerOffset;
    final outerStart = startRad + outerOffset;
    final outerEnd = endRad - outerOffset;
    final innerEnd = endRad - innerOffset;

    return Path()
      ..moveTo(center.dx + innerRadius * cos(innerStart), center.dy + innerRadius * sin(innerStart))
      ..lineTo(center.dx + outerRadius * cos(outerStart), center.dy + outerRadius * sin(outerStart))
      ..arcTo(Rect.fromCircle(center: center, radius: outerRadius), outerStart, outerEnd - outerStart, false)
      ..lineTo(center.dx + innerRadius * cos(innerEnd), center.dy + innerRadius * sin(innerEnd))
      ..arcTo(Rect.fromCircle(center: center, radius: innerRadius), innerEnd, innerStart - innerEnd, false)
      ..close();
  }

  @override
  bool shouldReclip(covariant _SectorClipper oldClipper) =>
      startAngle != oldClipper.startAngle || innerRadius != oldClipper.innerRadius || gapWidth != oldClipper.gapWidth;
}

class _RemoteButton extends StatelessWidget {
  final IconData icon;
  final String label;
  final VoidCallback onPressed;
  final double size;
  final double iconSize;

  const _RemoteButton({
    required this.icon,
    required this.label,
    required this.onPressed,
    this.size = 56,
    this.iconSize = 24,
  });

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        SizedBox(
          width: size,
          height: size,
          child: FilledButton(
            onPressed: () {
              HapticFeedback.lightImpact();
              onPressed();
            },
            style: FilledButton.styleFrom(padding: EdgeInsets.zero, shape: const CircleBorder()),
            child: Icon(icon, size: iconSize),
          ),
        ),
        const SizedBox(height: 4),
        Text(label, style: Theme.of(context).textTheme.bodySmall, textAlign: TextAlign.center),
      ],
    );
  }
}

class _RemoteChip extends StatelessWidget {
  final IconData icon;
  final String label;
  final VoidCallback onPressed;

  const _RemoteChip({required this.icon, required this.label, required this.onPressed});

  @override
  Widget build(BuildContext context) {
    return FilledButton.icon(
      onPressed: () {
        HapticFeedback.lightImpact();
        onPressed();
      },
      icon: Icon(icon, size: 18),
      label: Text(label),
    );
  }
}

class _SearchBottomSheet extends StatefulWidget {
  final CompanionRemoteProvider provider;

  const _SearchBottomSheet({required this.provider});

  @override
  State<_SearchBottomSheet> createState() => _SearchBottomSheetState();
}

class _SearchBottomSheetState extends State<_SearchBottomSheet> with ControllerDisposerMixin {
  late final _controller = createTextEditingController();

  void _submit(String text) {
    final trimmed = text.trim();
    if (trimmed.isNotEmpty) {
      widget.provider.sendCommand(RemoteCommandType.search, data: {'query': trimmed});
    }
    OverlaySheetController.of(context).close();
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(bottom: MediaQuery.viewInsetsOf(context).bottom, left: 16, right: 16, top: 16),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          FocusableTextField(
            controller: _controller,
            autofocus: true,
            decoration: pillInputDecoration(
              context,
              hintText: t.companionRemote.remote.searchHint,
              prefixIcon: const Icon(Icons.search),
              suffixIcon: IconButton(icon: const Icon(Icons.send), onPressed: () => _submit(_controller.text)),
            ),
            onSubmitted: _submit,
          ),
          const SizedBox(height: 16),
        ],
      ),
    );
  }
}

class _RemoteCard extends StatelessWidget {
  final IconData icon;
  final String label;
  final VoidCallback onPressed;

  const _RemoteCard({required this.icon, required this.label, required this.onPressed});

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: 100,
      height: 100,
      child: Card(
        child: InkWell(
          onTap: () {
            HapticFeedback.lightImpact();
            onPressed();
          },
          borderRadius: const BorderRadius.all(Radius.circular(12)),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Icon(icon, size: 32),
              const SizedBox(height: 8),
              Text(label, style: Theme.of(context).textTheme.bodySmall, textAlign: TextAlign.center),
            ],
          ),
        ),
      ),
    );
  }
}
