import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:get_it/get_it.dart';
import 'package:mocktail/mocktail.dart';
import 'package:shadcn_ui/shadcn_ui.dart';

import 'package:superport_v2/core/common/models/paginated_result.dart';
import 'package:superport_v2/features/inventory/summary/application/inventory_service.dart';
import 'package:superport_v2/features/inventory/summary/domain/entities/inventory_detail.dart';
import 'package:superport_v2/features/inventory/summary/domain/entities/inventory_event.dart';
import 'package:superport_v2/features/inventory/summary/domain/entities/inventory_product.dart';
import 'package:superport_v2/features/inventory/summary/domain/entities/inventory_summary.dart';
import 'package:superport_v2/features/inventory/summary/domain/entities/inventory_summary_list_result.dart';
import 'package:superport_v2/features/inventory/summary/domain/entities/inventory_vendor.dart';
import 'package:superport_v2/features/inventory/summary/domain/entities/inventory_warehouse.dart';
import 'package:superport_v2/features/inventory/summary/domain/entities/inventory_warehouse_balance.dart';
import 'package:superport_v2/features/inventory/summary/domain/repositories/inventory_repository.dart';
import 'package:superport_v2/features/inventory/summary/domain/entities/inventory_filters.dart';
import 'package:superport_v2/features/inventory/summary/presentation/pages/inventory_summary_page.dart';
import 'package:superport_v2/features/masters/warehouse/domain/entities/warehouse.dart';
import 'package:superport_v2/features/masters/warehouse/domain/repositories/warehouse_repository.dart';

class _MockInventoryRepository extends Mock implements InventoryRepository {}

class _MockWarehouseRepository extends Mock implements WarehouseRepository {}

Widget _buildApp(Widget child) {
  return MaterialApp(
    home: ShadTheme(
      data: ShadThemeData(
        colorScheme: const ShadSlateColorScheme.light(),
        brightness: Brightness.light,
      ),
      child: Scaffold(body: child),
    ),
  );
}

InventorySummaryListResult _buildSummaryResult() {
  final warehouse = InventoryWarehouse(id: 1, code: 'WH-001', name: '본사');
  final summary = InventorySummary(
    product: InventoryProduct(
      id: 10,
      code: 'INV-10',
      name: '테스트 장비',
      vendor: const InventoryVendor(id: 55, name: '테스트 벤더'),
    ),
    totalQuantity: 120,
    warehouseBalances: [
      InventoryWarehouseBalance(warehouse: warehouse, quantity: 80),
      InventoryWarehouseBalance(
        warehouse: InventoryWarehouse(id: 2, code: 'WH-002', name: '보관창고'),
        quantity: 40,
      ),
    ],
    recentEvent: InventoryEvent(
      eventId: 900,
      eventKind: 'receipt',
      eventLabel: '입고',
      deltaQuantity: 30,
      occurredAt: DateTime.utc(2025, 1, 3, 9, 0),
      warehouse: warehouse,
    ),
    updatedAt: DateTime.utc(2025, 1, 3, 9, 15),
    lastRefreshedAt: DateTime.utc(2025, 1, 3, 9, 5),
  );
  return InventorySummaryListResult(
    result: PaginatedResult<InventorySummary>(
      items: [summary],
      page: 1,
      pageSize: 50,
      total: 1,
    ),
    lastRefreshedAt: summary.lastRefreshedAt,
  );
}

InventoryDetail _buildDetail() {
  final warehouse1 = InventoryWarehouse(id: 1, code: 'WH-001', name: '본사');
  final warehouse2 = InventoryWarehouse(id: 2, code: 'WH-002', name: '보관창고');
  return InventoryDetail(
    product: InventoryProduct(
      id: 10,
      code: 'INV-10',
      name: '테스트 장비',
      vendor: const InventoryVendor(id: 55, name: '테스트 벤더'),
    ),
    totalQuantity: 120,
    warehouseBalances: [
      InventoryWarehouseBalance(warehouse: warehouse1, quantity: 80),
      InventoryWarehouseBalance(warehouse: warehouse2, quantity: 40),
    ],
    recentEvents: [
      InventoryEvent(
        eventId: 901,
        eventKind: 'receipt',
        eventLabel: '입고',
        deltaQuantity: 20,
        occurredAt: DateTime.utc(2025, 1, 3, 9, 10),
        warehouse: warehouse1,
      ),
    ],
    updatedAt: DateTime.utc(2025, 1, 3, 9, 20),
    lastRefreshedAt: DateTime.utc(2025, 1, 3, 9, 5),
  );
}

void _registerDependencies({
  required InventoryRepository inventoryRepository,
  required WarehouseRepository warehouseRepository,
}) {
  GetIt.I.registerSingleton<InventoryService>(
    InventoryService(repository: inventoryRepository),
  );
  GetIt.I.registerSingleton<WarehouseRepository>(warehouseRepository);
}

void _stubWarehouseList(_MockWarehouseRepository repository) {
  when(
    () => repository.list(
      page: any(named: 'page'),
      pageSize: any(named: 'pageSize'),
      query: any(named: 'query'),
      isActive: any(named: 'isActive'),
      includeZipcode: any(named: 'includeZipcode'),
    ),
  ).thenAnswer((invocation) async {
    final page = invocation.namedArguments[const Symbol('page')] as int? ?? 1;
    final items = page == 1
        ? [Warehouse(id: 1, warehouseCode: 'WH-001', warehouseName: '본사 창고')]
        : const <Warehouse>[];
    return PaginatedResult<Warehouse>(
      items: items,
      page: page,
      pageSize:
          invocation.namedArguments[const Symbol('pageSize')] as int? ?? 20,
      total: items.length,
    );
  });
}

Future<void> _pumpInventoryPage(WidgetTester tester) async {
  await tester.binding.setSurfaceSize(const Size(1600, 1200));
  await tester.pumpWidget(
    _buildApp(
      InventorySummaryPage(
        routeUri: Uri(path: '/inventory/summary'),
        debugRowHeight: 200,
      ),
    ),
  );
  await tester.pumpAndSettle();
}

void main() {
  final binding = TestWidgetsFlutterBinding.ensureInitialized();

  setUpAll(() {
    registerFallbackValue(const InventorySummaryFilter());
    registerFallbackValue(const InventoryDetailFilter());
  });

  setUp(() async {
    final inventoryRepository = _MockInventoryRepository();
    final warehouseRepository = _MockWarehouseRepository();
    _registerDependencies(
      inventoryRepository: inventoryRepository,
      warehouseRepository: warehouseRepository,
    );
    _stubWarehouseList(warehouseRepository);
    when(
      () => inventoryRepository.listSummaries(filter: any(named: 'filter')),
    ).thenAnswer((_) async => _buildSummaryResult());
    when(
      () =>
          inventoryRepository.fetchDetail(any(), filter: any(named: 'filter')),
    ).thenAnswer((_) async => _buildDetail());
  });

  tearDown(() async {
    await binding.setSurfaceSize(null);
    await GetIt.I.reset();
  });

  testWidgets('Inventory summary page matches golden', (tester) async {
    await _pumpInventoryPage(tester);

    await expectLater(
      find.byType(InventorySummaryPage),
      matchesGoldenFile('goldens/inventory_summary_page_default.png'),
    );
  });

  testWidgets('Inventory detail sheet matches golden', (tester) async {
    await _pumpInventoryPage(tester);
    await tester.tap(find.text('테스트 장비'));
    await tester.pumpAndSettle();

    await expectLater(
      find.byType(InventorySummaryPage),
      matchesGoldenFile('goldens/inventory_summary_detail_sheet.png'),
    );
  });
}
