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

import 'package:superport_v2/core/config/environment.dart';
import 'package:superport_v2/core/common/models/paginated_result.dart';
import 'package:superport_v2/core/network/api_error.dart';
import 'package:superport_v2/features/masters/warehouse/domain/entities/warehouse.dart';
import 'package:superport_v2/features/masters/warehouse/domain/repositories/warehouse_repository.dart';
import 'package:superport_v2/features/inventory/lookups/domain/entities/lookup_item.dart';
import 'package:superport_v2/features/inventory/lookups/domain/repositories/inventory_lookup_repository.dart';
import 'package:superport_v2/features/reporting/domain/entities/report_download_result.dart';
import 'package:superport_v2/features/reporting/domain/entities/report_export_format.dart';
import 'package:superport_v2/features/reporting/domain/entities/report_export_request.dart';
import 'package:superport_v2/features/reporting/domain/repositories/reporting_repository.dart';
import 'package:superport_v2/features/reporting/presentation/pages/reporting_page.dart';
import '../../helpers/test_app.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  setUpAll(() async {
    await Environment.initialize();
  });

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

  testWidgets('보고서 화면은 창고 목록 재시도 흐름을 제공한다', (tester) async {
    final repo = _FlakyWarehouseRepository();
    GetIt.I.registerSingleton<WarehouseRepository>(repo);
    GetIt.I.registerSingleton<InventoryLookupRepository>(
      _StubLookupRepository(),
    );
    GetIt.I.registerSingleton<ReportingRepository>(_FakeReportingRepository());

    final view = tester.view;
    view.physicalSize = const Size(1280, 800);
    view.devicePixelRatio = 1.0;
    addTearDown(() {
      view.resetPhysicalSize();
      view.resetDevicePixelRatio();
    });

    await tester.pumpWidget(buildTestApp(const ReportingPage()));
    await tester.pumpAndSettle();

    expect(repo.attempts, 1);
    expect(find.text('창고 목록을 불러오지 못했습니다. 잠시 후 다시 시도하세요.'), findsWidgets);

    await tester.tap(find.widgetWithText(ShadButton, '재시도'));
    await tester.pumpAndSettle();
    await tester.pump(const Duration(seconds: 4));

    expect(repo.attempts, 2);
  });
}

class _FlakyWarehouseRepository implements WarehouseRepository {
  int attempts = 0;

  @override
  Future<PaginatedResult<Warehouse>> list({
    int page = 1,
    int pageSize = 20,
    String? query,
    bool? isActive,
    bool includeZipcode = true,
  }) async {
    attempts += 1;
    if (attempts == 1) {
      throw const ApiException(
        code: ApiErrorCode.network,
        message: '창고 목록을 불러오지 못했습니다. 잠시 후 다시 시도하세요.',
      );
    }
    return PaginatedResult<Warehouse>(
      items: [
        Warehouse(
          id: 1,
          warehouseCode: 'WH-A',
          warehouseName: '창고 A',
          isActive: true,
          isDeleted: false,
        ),
      ],
      page: 1,
      pageSize: 20,
      total: 1,
    );
  }

  @override
  Future<Warehouse> create(WarehouseInput input) {
    throw UnimplementedError();
  }

  @override
  Future<void> delete(int id) {
    throw UnimplementedError();
  }

  @override
  Future<Warehouse> restore(int id) {
    throw UnimplementedError();
  }

  @override
  Future<Warehouse> update(int id, WarehouseInput input) {
    throw UnimplementedError();
  }
}

class _StubLookupRepository implements InventoryLookupRepository {
  @override
  Future<List<LookupItem>> fetchTransactionTypes({
    bool activeOnly = true,
  }) async {
    return [
      LookupItem(id: 1, name: '입고'),
      LookupItem(id: 2, name: '출고'),
      LookupItem(id: 3, name: '대여'),
    ];
  }

  @override
  Future<List<LookupItem>> fetchTransactionStatuses({
    bool activeOnly = true,
  }) async {
    return [
      LookupItem(id: 11, name: '작성중'),
      LookupItem(id: 12, name: '완료'),
      LookupItem(id: 13, name: '취소'),
    ];
  }

  @override
  Future<List<LookupItem>> fetchApprovalStatuses({
    bool activeOnly = true,
  }) async {
    return [
      LookupItem(id: 21, name: '진행중'),
      LookupItem(id: 22, name: '완료'),
      LookupItem(id: 23, name: '취소'),
    ];
  }

  @override
  Future<List<LookupItem>> fetchApprovalActions({
    bool activeOnly = true,
  }) async {
    return const [];
  }
}

class _FakeReportingRepository implements ReportingRepository {
  ReportExportRequest? lastRequest;
  ReportExportFormat? lastFormat;

  @override
  Future<ReportDownloadResult> exportApprovals(
    ReportExportRequest request,
  ) async {
    lastRequest = request;
    lastFormat = request.format;
    return ReportDownloadResult(
      downloadUrl: Uri.parse('https://example.com/approvals.pdf'),
      filename: 'approvals.pdf',
      mimeType: 'application/pdf',
    );
  }

  @override
  Future<ReportDownloadResult> exportTransactions(
    ReportExportRequest request,
  ) async {
    lastRequest = request;
    lastFormat = request.format;
    return ReportDownloadResult(
      downloadUrl: Uri.parse('https://example.com/transactions.xlsx'),
      filename: 'transactions.xlsx',
      mimeType:
          'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    );
  }
}
