import 'dart:developer';

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

import '../../../../../application/table/table_form/table_form_bloc.dart';
import '../../../../../application/table/table_loader/table_loader_bloc.dart';
import '../../../../../common/extension/extension.dart';
import '../../../../../common/theme/theme.dart';
import '../../../../../domain/table/table.dart' as t;
import '../../../../../injection.dart';
import '../../../../components/dialog/table/table_create_dialog.dart';
import '../../../../components/dialog/table/table_transfer_dialog.dart';
import '../../../../components/loader/loader_with_text.dart';
import '../../../../components/toast/flushbar.dart';
import 'widgets/floating_bottom_navbar.dart';
import 'widgets/table_card.dart';

@RoutePage()
class TablePage extends StatefulWidget implements AutoRouteWrapper {
  const TablePage({super.key});

  @override
  State<TablePage> createState() => _TablePageState();

  @override
  Widget wrappedRoute(BuildContext context) => MultiBlocProvider(
    providers: [
      BlocProvider(
        create: (context) =>
            getIt<TableLoaderBloc>()
              ..add(const TableLoaderEvent.fetched(isRefresh: true)),
      ),
    ],
    child: this,
  );
}

class _TablePageState extends State<TablePage>
    with AutomaticKeepAliveClientMixin {
  t.Table? draggingTable;
  Offset? tapPosition;
  bool _isFirstBuild = true;

  @override
  bool get wantKeepAlive => true;

  @override
  void initState() {
    super.initState();
    log('🔥 TablePage initState');
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();

    // Cek apakah tab ini aktif
    final route = ModalRoute.of(context);
    if (route != null && route.isCurrent) {
      if (!_isFirstBuild) {
        log('🔥 TablePage visible again, refresh');
        _refreshTable();
      }
      _isFirstBuild = false;
    }
  }

  void _refreshTable() {
    if (mounted) {
      context.read<TableLoaderBloc>().add(
        const TableLoaderEvent.fetched(isRefresh: true),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    final double mapWidth = context.deviceWidth * 2;
    final double mapHeight = context.deviceHeight * 1.5;

    return MultiBlocListener(
      listeners: [
        BlocListener<TableFormBloc, TableFormState>(
          listenWhen: (previous, current) =>
              previous.failureOrTable != current.failureOrTable,
          listener: (context, state) {
            state.failureOrTable.fold(() {}, (either) {
              either.fold(
                (f) => AppFlushbar.showTableFailureToast(context, f),
                (success) {
                  if (context.mounted) {
                    context.router.maybePop();
                    context.read<TableLoaderBloc>().add(
                      const TableLoaderEvent.fetched(isRefresh: true),
                    );
                  }
                },
              );
            });
          },
        ),
        BlocListener<TableFormBloc, TableFormState>(
          listenWhen: (previous, current) =>
              previous.failureOrTableTransfer != current.failureOrTableTransfer,
          listener: (context, state) {
            state.failureOrTableTransfer.fold(() {}, (either) {
              either.fold(
                (f) => AppFlushbar.showTableFailureToast(context, f),
                (success) {
                  if (context.mounted) {
                    context.router.maybePop();
                    context.read<TableLoaderBloc>().add(
                      const TableLoaderEvent.fetched(isRefresh: true),
                    );
                  }
                },
              );
            });
          },
        ),
      ],
      child: Scaffold(
        backgroundColor: AppColor.background,
        appBar: AppBar(
          title: const Text("Layout Meja"),
          backgroundColor: Colors.white,
          foregroundColor: Colors.black,
          elevation: 0.5,
          actions: [
            IconButton(
              icon: const Icon(Icons.refresh),
              onPressed: () {
                context.read<TableLoaderBloc>().add(
                  const TableLoaderEvent.fetched(isRefresh: true),
                );
              },
            ),
            IconButton(
              icon: const Icon(Icons.add),
              onPressed: () {
                showDialog(
                  context: context,
                  builder: (context) => const TableCreateDialog(),
                );
              },
            ),
          ],
          bottom: PreferredSize(
            preferredSize: const Size.fromHeight(20),
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
              child: Row(
                children: [
                  _buildLegendDot(Colors.blue[200]!, "Available"),
                  const SizedBox(width: 16),
                  _buildLegendDot(Colors.orange[200]!, "Occupied"),
                ],
              ),
            ),
          ),
        ),
        body: BlocBuilder<TableLoaderBloc, TableLoaderState>(
          builder: (context, state) {
            if (state.isFetching) {
              return const Center(child: LoaderWithText());
            }
            return SafeArea(
              child: Stack(
                children: [
                  Row(
                    children: [
                      Expanded(
                        flex: 5,
                        child: InteractiveViewer(
                          panEnabled: true,
                          scaleEnabled: true,
                          constrained: false,
                          boundaryMargin: const EdgeInsets.all(80),
                          minScale: 0.3,
                          maxScale: 3.0,
                          alignment: Alignment.topLeft,
                          child: Container(
                            width: mapWidth,
                            height: mapHeight,
                            decoration: BoxDecoration(
                              color: const Color(0xFFF7F8FA),
                              border: Border.all(
                                color: Colors.grey[300]!,
                                width: 2,
                              ),
                            ),
                            child: Stack(
                              children: [
                                ...List.generate(
                                  20,
                                  (i) => Positioned(
                                    left: i * 100.0,
                                    top: 0,
                                    bottom: 0,
                                    child: Container(
                                      width: 1,
                                      color: Colors.grey[200],
                                    ),
                                  ),
                                ),
                                ...List.generate(
                                  15,
                                  (i) => Positioned(
                                    top: i * 100.0,
                                    left: 0,
                                    right: 0,
                                    child: Container(
                                      height: 1,
                                      color: Colors.grey[200],
                                    ),
                                  ),
                                ),
                                ...state.tables.map((table) {
                                  final isSelected =
                                      state.selectedTable == table;
                                  return Positioned(
                                    left: table.positionX,
                                    top: table.positionY,
                                    child: Draggable<t.Table>(
                                      data: table,
                                      feedback: Material(
                                        color: Colors.transparent,
                                        child: TableCard(
                                          table: table,
                                          isSelected: isSelected,
                                        ),
                                      ),
                                      childWhenDragging: Opacity(
                                        opacity: 0.5,
                                        child: TableCard(
                                          table: table,
                                          isSelected: isSelected,
                                        ),
                                      ),
                                      onDragStarted: () {
                                        setState(() {
                                          draggingTable = table;
                                        });
                                      },
                                      onDraggableCanceled: (velocity, offset) {
                                        setState(() {
                                          draggingTable = null;
                                        });
                                      },
                                      onDragEnd: (details) {
                                        final RenderBox box =
                                            context.findRenderObject()
                                                as RenderBox;
                                        final Offset local = box.globalToLocal(
                                          details.offset,
                                        );

                                        final newX = local.dx.clamp(
                                          0.0,
                                          mapWidth - 120,
                                        );
                                        final newY = local.dy.clamp(
                                          0.0,
                                          mapHeight - 80,
                                        );

                                        setState(() {
                                          draggingTable = null;
                                        });

                                        // Update position locally in bloc state
                                        context.read<TableLoaderBloc>().add(
                                          TableLoaderEvent.updatedPostion(
                                            id: table.id,
                                            position: Offset(newX, newY),
                                          ),
                                        );
                                        context.read<TableFormBloc>().add(
                                          TableFormEvent.updated(
                                            id: table.id,
                                            position: Offset(newX, newY),
                                          ),
                                        );
                                      },
                                      child: GestureDetector(
                                        onTap: () {
                                          context.read<TableLoaderBloc>().add(
                                            TableLoaderEvent.setSelectedTable(
                                              table,
                                            ),
                                          );
                                        },
                                        onTapDown: (details) => tapPosition =
                                            details.globalPosition,
                                        onLongPress: () {
                                          if (table.status.isOccupied) {
                                            context.read<TableLoaderBloc>().add(
                                              const TableLoaderEvent.setSelectedTable(
                                                null,
                                              ),
                                            );
                                            _showPopupMenu(context, table);
                                          }
                                        },
                                        child: TableCard(
                                          table: table,
                                          isSelected: isSelected,
                                        ),
                                      ),
                                    ),
                                  );
                                }),
                              ],
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                  TableFloatingBottomNavbar(selectedTable: state.selectedTable),
                ],
              ),
            );
          },
        ),
      ),
    );
  }

  Widget _buildLegendDot(Color color, String label) {
    return Row(
      children: [
        CircleAvatar(radius: 7, backgroundColor: color),
        const SizedBox(width: 6),
        Text(label, style: const TextStyle(fontSize: 14)),
      ],
    );
  }

  void _showPopupMenu(BuildContext context, t.Table table) {
    final RenderBox overlay =
        Overlay.of(context).context.findRenderObject() as RenderBox;

    showMenu(
      context: context,
      position: RelativeRect.fromRect(
        tapPosition != null
            ? Rect.fromLTWH(tapPosition!.dx, tapPosition!.dy, 0, 0)
            : const Rect.fromLTWH(100, 100, 0, 0),
        Offset.zero & overlay.size,
      ),
      color: AppColor.white,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
      elevation: 1,
      items: [
        PopupMenuItem(
          onTap: () {
            showDialog(
              context: context,
              builder: (context) => TableTransferDialog(fromTable: table),
            );
          },
          child: const Row(
            children: [
              Icon(Icons.swap_horiz),
              SizedBox(width: 8),
              Text('Transfer'),
            ],
          ),
        ),
      ],
    );
  }
}
