import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:matrix/matrix.dart';
import 'package:pyramid/core/app_state.dart';
import 'package:pyramid/core/matrix_client.dart';
import 'package:pyramid/core/theme.dart';
import 'package:pyramid/features/rooms/rooms_provider.dart';
import 'package:pyramid/widgets/create_join_dialog.dart';
import 'package:pyramid/widgets/mxc_image.dart';
import 'package:pyramid/widgets/pyramid_logo.dart';

class SpacesRail extends ConsumerWidget {
  const SpacesRail({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final pt = PyramidTheme.of(context);
    final spaces = ref.watch(spacesProvider).valueOrNull ?? [];
    final activeSpaceId = ref.watch(activeSpaceIdProvider);
    final forceJoined = ref.watch(forceJoinedSpacesProvider);

    final dmUnread = ref.watch(dmUnreadCountProvider).valueOrNull ?? 0;

    void selectSpace(String? id) {
      // Save current room for the space we're leaving
      final currentRoom = ref.read(activeRoomIdProvider);
      final currentSpace = ref.read(activeSpaceIdProvider);
      if (currentRoom != null) {
        final updated = Map<String?, String?>.from(ref.read(lastRoomPerSpaceProvider));
        updated[currentSpace] = currentRoom;
        ref.read(lastRoomPerSpaceProvider.notifier).state = updated;
      }
      // Switch space and restore last visited room for the new space
      ref.read(activeSpaceIdProvider.notifier).state = id;
      ref.read(activeRoomIdProvider.notifier).state =
          ref.read(lastRoomPerSpaceProvider)[id];
      final scaffold = Scaffold.maybeOf(context);
      if (scaffold != null && scaffold.isDrawerOpen) {
        scaffold.closeDrawer();
      }
    }

    return Container(
      width: 72,
      color: pt.bg0,
      child: Column(
        children: [
          const SizedBox(height: 12),
          _HomeButton(
            pt: pt,
            active: activeSpaceId == 'dms' || activeSpaceId == null,
            unreadCount: dmUnread,
            onTap: () => selectSpace('dms'),
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 8),
            child: Container(
              width: 32,
              height: 2,
              decoration: BoxDecoration(
                color: pt.border,
                borderRadius: BorderRadius.circular(2),
              ),
            ),
          ),
          Expanded(
            child: ListView(
              padding: EdgeInsets.zero,
              children: [
                _VirtualSpaceItem(
                  id: 'rooms',
                  label: 'R',
                  color: const Color(0xFFF59E0B),
                  name: 'Rooms',
                  active: activeSpaceId == 'rooms',
                  unread: 0,
                  pt: pt,
                  onTap: () => selectSpace('rooms'),
                ),
                ...spaces.map((space) => Padding(
                  padding: const EdgeInsets.only(top: 6),
                  child: _SpaceItem(
                    space: space,
                    active: activeSpaceId == space.id,
                    isInvite: space.membership == Membership.invite &&
                        !forceJoined.contains(space.id),
                    pt: pt,
                    onTap: () => selectSpace(space.id),
                  ),
                )),
                const SizedBox(height: 8),
                _AddButton(pt: pt),
                const SizedBox(height: 8),
              ],
            ),
          ),
          const SizedBox(height: 8),
          _SettingsButton(pt: pt),
          const SizedBox(height: 12),
        ],
      ),
    );
  }
}

class _SettingsButton extends ConsumerWidget {
  final PyramidTheme pt;
  const _SettingsButton({required this.pt});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Center(
      child: IconButton(
        icon: Icon(Icons.settings_outlined, color: pt.fgDim),
        onPressed: () {
          ref.read(activeModalProvider.notifier).state = ModalKind.settings;
          final scaffold = Scaffold.maybeOf(context);
          if (scaffold != null && scaffold.isDrawerOpen) {
            scaffold.closeDrawer();
          }
        },
      ),
    );
  }
}

class _HomeButton extends StatefulWidget {
  final PyramidTheme pt;
  final bool active;
  final int unreadCount;
  final VoidCallback onTap;

  const _HomeButton({
    required this.pt,
    required this.active,
    required this.unreadCount,
    required this.onTap,
  });

  @override
  State<_HomeButton> createState() => _HomeButtonState();
}

class _HomeButtonState extends State<_HomeButton> {
  bool _hovered = false;

  @override
  Widget build(BuildContext context) {
    final pt = widget.pt;
    return Stack(
      clipBehavior: Clip.none,
      children: [
        if (widget.active)
          Positioned(
            left: -12,
            top: 10,
            child: Container(
              width: 4,
              height: 28,
              decoration: BoxDecoration(
                color: pt.accent,
                borderRadius: const BorderRadius.only(
                  topRight: Radius.circular(3),
                  bottomRight: Radius.circular(3),
                ),
              ),
            ),
          ),
        MouseRegion(
          cursor: SystemMouseCursors.click,
          onEnter: (_) => setState(() => _hovered = true),
          onExit: (_) => setState(() => _hovered = false),
          child: GestureDetector(
            onTap: widget.onTap,
            child: AnimatedContainer(
              duration: const Duration(milliseconds: 250),
              curve: Curves.easeOutBack,
              transform: _hovered
                  ? (Matrix4.translationValues(0, -2, 0)..rotateZ(-0.05))
                  : Matrix4.identity(),
              child: Tooltip(
                message: 'Direct Messages',
                waitDuration: const Duration(milliseconds: 400),
                preferBelow: false,
                child: Stack(
                  clipBehavior: Clip.none,
                  children: [
                    Container(
                      width: 48,
                      height: 48,
                      decoration: BoxDecoration(
                        gradient: LinearGradient(
                          begin: Alignment.topLeft,
                          end: Alignment.bottomRight,
                          colors: [pt.accent, Color.fromARGB(255,
                            (pt.accent.r * 255 * 0.85).round().clamp(0, 255),
                            (pt.accent.g * 255 * 0.85).round().clamp(0, 255),
                            (pt.accent.b * 255 * 0.7).round().clamp(0, 255),
                          )],
                        ),
                        borderRadius: BorderRadius.circular(
                          widget.active ? pt.rLg * 0.6 : pt.rLg,
                        ),
                        boxShadow: widget.active
                            ? [BoxShadow(color: pt.accentGlow, blurRadius: 16, offset: const Offset(0, 4))]
                            : null,
                      ),
                      child: Center(child: PyramidLogo(size: 28, color: Colors.white)),
                    ),
                    if (widget.unreadCount > 0)
                      Positioned(
                        right: -4,
                        top: -4,
                        child: Container(
                          padding: const EdgeInsets.symmetric(horizontal: 5),
                          constraints: const BoxConstraints(minWidth: 18, minHeight: 18),
                          decoration: BoxDecoration(
                            color: pt.danger,
                            borderRadius: BorderRadius.circular(999),
                            border: Border.all(color: pt.bg0, width: 1.5),
                          ),
                          child: Center(
                            child: Text(
                              widget.unreadCount > 99 ? '99+' : '${widget.unreadCount}',
                              style: const TextStyle(color: Colors.white, fontSize: 10, fontWeight: FontWeight.w700),
                            ),
                          ),
                        ),
                      ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ],
    );
  }
}

class _VirtualSpaceItem extends StatefulWidget {
  final String id;
  final String label;
  final Color color;
  final String name;
  final bool active;
  final int unread;
  final PyramidTheme pt;
  final VoidCallback onTap;

  const _VirtualSpaceItem({
    required this.id,
    required this.label,
    required this.color,
    required this.name,
    required this.active,
    required this.unread,
    required this.pt,
    required this.onTap,
  });

  @override
  State<_VirtualSpaceItem> createState() => _VirtualSpaceItemState();
}

class _VirtualSpaceItemState extends State<_VirtualSpaceItem> {
  bool _hovered = false;

  @override
  Widget build(BuildContext context) {
    final pt = widget.pt;
    final active = widget.active;
    final radius = active
        ? pt.rLg * 0.6
        : _hovered ? pt.rLg * 0.7 : pt.rLg;

    return Center(
      child: MouseRegion(
        cursor: SystemMouseCursors.click,
        onEnter: (_) => setState(() => _hovered = true),
        onExit: (_) => setState(() => _hovered = false),
        child: GestureDetector(
          onTap: widget.onTap,
          child: Stack(
            clipBehavior: Clip.none,
            children: [
              // Active indicator
              if (active)
                Positioned(
                  left: -18,
                  top: 10,
                  child: Container(
                    width: 4,
                    height: 28,
                    decoration: BoxDecoration(
                      color: pt.accent,
                      borderRadius: const BorderRadius.only(
                        topRight: Radius.circular(3),
                        bottomRight: Radius.circular(3),
                      ),
                    ),
                  ),
                ),
              Tooltip(
                message: widget.name,
                waitDuration: const Duration(milliseconds: 400),
                preferBelow: false,
                child: AnimatedContainer(
                  duration: const Duration(milliseconds: 250),
                  curve: Curves.easeOutBack,
                  width: 48,
                  height: 48,
                  decoration: BoxDecoration(
                    color: _hovered ? pt.bg3 : pt.bg2,
                    borderRadius: BorderRadius.circular(radius),
                  ),
                  child: Center(
                    child: PyramidGlyph(
                      size: 30,
                      color: widget.color,
                      label: widget.label,
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _SpaceItem extends ConsumerStatefulWidget {
  final Room space;
  final bool active;
  final bool isInvite;
  final PyramidTheme pt;
  final VoidCallback onTap;

  const _SpaceItem({
    required this.space,
    required this.active,
    this.isInvite = false,
    required this.pt,
    required this.onTap,
  });

  @override
  ConsumerState<_SpaceItem> createState() => _SpaceItemState();
}

class _SpaceItemState extends ConsumerState<_SpaceItem> {
  bool _hovered = false;

  @override
  Widget build(BuildContext context) {
    final pt = widget.pt;
    final active = widget.active;
    final name = widget.space.getLocalizedDisplayname();
    final letter = name.isNotEmpty ? name[0].toUpperCase() : '?';
    final radius = active ? pt.rLg * 0.6 : _hovered ? pt.rLg * 0.7 : pt.rLg;
    final client = ref.watch(matrixClientProvider).valueOrNull;
    final avatarUri = widget.space.avatar;

    Widget avatarChild;
    if (client != null && avatarUri != null) {
      avatarChild = MxcAvatar(
        mxcUri: avatarUri,
        client: client,
        size: 48,
        borderRadius: BorderRadius.circular(radius),
        placeholder: (_) => _SpaceInitial(letter: letter, pt: pt, radius: radius),
      );
    } else {
      avatarChild = _SpaceInitial(letter: letter, pt: pt, radius: radius);
    }

    return Center(
      child: MouseRegion(
        cursor: SystemMouseCursors.click,
        onEnter: (_) => setState(() => _hovered = true),
        onExit: (_) => setState(() => _hovered = false),
        child: GestureDetector(
          onTap: widget.onTap,
          onSecondaryTap: widget.isInvite
              ? null
              : () => showDialog(
                    context: context,
                    builder: (_) => SpaceEditDialog(space: widget.space),
                  ),
          onLongPress: widget.isInvite
              ? null
              : () => showDialog(
                    context: context,
                    builder: (_) => SpaceEditDialog(space: widget.space),
                  ),
          child: Stack(
            clipBehavior: Clip.none,
            children: [
              if (active)
                Positioned(
                  left: -18,
                  top: 10,
                  child: Container(
                    width: 4,
                    height: 28,
                    decoration: BoxDecoration(
                      color: pt.accent,
                      borderRadius: const BorderRadius.only(
                        topRight: Radius.circular(3),
                        bottomRight: Radius.circular(3),
                      ),
                    ),
                  ),
                ),
              Tooltip(
                message: name,
                waitDuration: const Duration(milliseconds: 400),
                preferBelow: false,
                child: AnimatedContainer(
                  duration: const Duration(milliseconds: 250),
                  curve: Curves.easeOutBack,
                  width: 48,
                  height: 48,
                  decoration: BoxDecoration(
                    color: _hovered ? pt.bg3 : pt.bg2,
                    borderRadius: BorderRadius.circular(radius),
                  ),
                  child: ClipRRect(
                    borderRadius: BorderRadius.circular(radius),
                    child: avatarChild,
                  ),
                ),
              ),
              if (widget.isInvite)
                Positioned(
                  right: -2,
                  top: -2,
                  child: Container(
                    padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1),
                    decoration: BoxDecoration(
                      color: pt.accent,
                      borderRadius: BorderRadius.circular(999),
                      border: Border.all(color: pt.bg0, width: 1.5),
                    ),
                    child: const Text(
                      'NEU',
                      style: TextStyle(
                          color: Colors.white,
                          fontSize: 8,
                          fontWeight: FontWeight.w800,
                          letterSpacing: 0.3),
                    ),
                  ),
                ),
            ],
          ),
        ),
      ),
    );
  }
}

class _SpaceInitial extends StatelessWidget {
  final String letter;
  final PyramidTheme pt;
  final double radius;
  const _SpaceInitial({required this.letter, required this.pt, required this.radius});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(letter, style: TextStyle(color: pt.fg, fontSize: 16, fontWeight: FontWeight.w700)),
    );
  }
}

class _AddButton extends StatefulWidget {
  final PyramidTheme pt;
  const _AddButton({required this.pt});

  @override
  State<_AddButton> createState() => _AddButtonState();
}

class _AddButtonState extends State<_AddButton> {
  bool _hovered = false;

  @override
  Widget build(BuildContext context) {
    final pt = widget.pt;
    return Center(
      child: MouseRegion(
        cursor: SystemMouseCursors.click,
        onEnter: (_) => setState(() => _hovered = true),
        onExit: (_) => setState(() => _hovered = false),
        child: GestureDetector(
          onTap: () => showDialog(
            context: context,
            builder: (_) => const CreateJoinDialog(),
          ),
          child: Tooltip(
            message: 'Create · Join · Discover',
            waitDuration: const Duration(milliseconds: 400),
            preferBelow: false,
            child: AnimatedContainer(
              duration: const Duration(milliseconds: 250),
              curve: Curves.easeOutBack,
              width: 48,
              height: 48,
              decoration: BoxDecoration(
                color: _hovered ? pt.accentSoft : pt.bg2,
                borderRadius: BorderRadius.circular(_hovered ? pt.rLg * 0.7 : pt.rLg),
                border: Border.all(
                  color: _hovered ? pt.accent : pt.borderStrong,
                  width: 1.5,
                  style: BorderStyle.solid,
                ),
              ),
              child: Center(
                child: AnimatedRotation(
                  turns: _hovered ? 0.25 : 0,
                  duration: const Duration(milliseconds: 250),
                  curve: Curves.easeOutBack,
                  child: Icon(Icons.add, color: pt.accent, size: 22),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
