import 'dart:convert';

import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:http/testing.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:tdc114plus/src/features/auth/data/auth_session_store.dart';
import 'package:tdc114plus/src/features/auth/domain/auth_models.dart';
import 'package:tdc114plus/src/features/directory/data/profile_image_api_client.dart';
import 'package:tdc114plus/src/features/directory/domain/employee.dart';

void main() {
  setUp(() {
    SharedPreferences.setMockInitialValues({});
  });

  test('keeps explicit profileImageUrl without auth lookup', () async {
    var requestCount = 0;
    final client = ProfileImageApiClient(
      httpClient: MockClient((request) async {
        requestCount += 1;
        return http.Response('{}', 500);
      }),
      baseUri: Uri.parse('https://114-auth.hmac.kr'),
      sessionStore: const AuthSessionStore(),
    );

    const employee = Employee(
      id: 'user-1',
      name: '강경훈',
      phoneNumber: '01012345678',
      email: 'khkang@samaneng.com',
      tenantId: 'tenant-1',
      tenantName: '삼안',
      tenantSlug: 'saman',
      profileImageUrl: 'https://cdn.example.test/khkang.jpg',
    );

    final imageUrl = await client.resolveImageUrl(employee);

    expect(imageUrl, 'https://cdn.example.test/khkang.jpg');
    expect(requestCount, 0);
  });

  test('uses auth profile-image endpoint when explicit profile image is absent', () async {
    const store = AuthSessionStore();
    await store.save(
      PhoneLoginResponse(
        status: 'ok',
        token: 'app-session-token',
        expiresAt: DateTime.now().toUtc().add(const Duration(hours: 1)),
        user: const LoginUser(
          id: 'user-1',
          name: '강경훈',
          phoneNumber: '01012345678',
          tenantId: 'tenant-1',
          tenantName: '삼안',
          tenantSlug: 'saman',
        ),
      ),
    );

    final client = ProfileImageApiClient(
      httpClient: MockClient((request) async {
        expect(request.url.host, '114-auth.hmac.kr');
        expect(request.url.path, '/api/v1/profile-image');
        expect(request.url.queryParameters['comp'], 'SAMAN');
        expect(request.url.queryParameters['email'], 'khkang@samaneng.com');
        expect(request.headers['Authorization'], 'Bearer app-session-token');
        return http.Response(
          jsonEncode({
            'found': true,
            'source': 'BARON_UUID_R2',
            'imageUrl':
                'https://baroncs.co.kr/employee_img/bebb832c-052e-493d-b5a9-732518d67685.jpg',
          }),
          200,
          headers: {'content-type': 'application/json'},
        );
      }),
      baseUri: Uri.parse('https://114-auth.hmac.kr'),
      sessionStore: store,
    );

    const employee = Employee(
      id: 'bebb832c-052e-493d-b5a9-732518d67685',
      name: '강경훈',
      phoneNumber: '01012345678',
      email: 'khkang@samaneng.com',
      tenantId: 'tenant-1',
      tenantName: '삼안',
      tenantSlug: 'saman',
    );

    final imageUrl = await client.resolveImageUrl(employee);

    expect(
      imageUrl,
      'https://baroncs.co.kr/employee_img/bebb832c-052e-493d-b5a9-732518d67685.jpg',
    );
  });

  test('returns null when employee email is missing', () async {
    final client = ProfileImageApiClient(
      httpClient: MockClient((request) async {
        fail('auth lookup should not be sent without email');
      }),
      baseUri: Uri.parse('https://114-auth.hmac.kr'),
      sessionStore: const AuthSessionStore(),
    );

    const employee = Employee(
      id: 'user-2',
      name: '직원',
      phoneNumber: '01000000000',
      tenantId: 'tenant-2',
      tenantName: '한맥',
      tenantSlug: 'hanmac',
    );

    expect(await client.resolveImageUrl(employee), isNull);
  });

  test('falls back to public uuid image when employee email is missing', () async {
    final client = ProfileImageApiClient(
      httpClient: MockClient((request) async {
        fail('auth lookup should not be sent without email');
      }),
      baseUri: Uri.parse('https://114-auth.hmac.kr'),
      sessionStore: const AuthSessionStore(),
    );

    const employee = Employee(
      id: 'bebb832c-052e-493d-b5a9-732518d67685',
      name: '강경훈',
      phoneNumber: '01012345678',
      tenantId: 'tenant-1',
      tenantName: '삼안',
      tenantSlug: 'saman',
    );

    expect(
      await client.resolveImageUrl(employee),
      'https://baroncs.co.kr/employee_img/bebb832c-052e-493d-b5a9-732518d67685.jpg',
    );
  });

  test('allows auth lookup without company code when tenant mapping is unknown', () async {
    const store = AuthSessionStore();
    await store.save(
      PhoneLoginResponse(
        status: 'ok',
        token: 'app-session-token',
        expiresAt: DateTime.now().toUtc().add(const Duration(hours: 1)),
        user: const LoginUser(
          id: 'user-3',
          name: '직원',
          phoneNumber: '01011112222',
          tenantId: 'tenant-3',
          tenantName: 'Unknown',
          tenantSlug: 'unknown',
        ),
      ),
    );

    final client = ProfileImageApiClient(
      httpClient: MockClient((request) async {
        expect(request.url.queryParameters['comp'], isNull);
        expect(request.url.queryParameters['email'], 'person@example.com');
        return http.Response(
          jsonEncode({'found': false, 'source': 'DEFAULT'}),
          200,
          headers: {'content-type': 'application/json'},
        );
      }),
      baseUri: Uri.parse('https://114-auth.hmac.kr'),
      sessionStore: store,
    );

    const employee = Employee(
      id: 'user-3',
      name: '직원',
      phoneNumber: '01011112222',
      email: 'person@example.com',
      tenantId: 'tenant-3',
      tenantName: 'Unknown',
      tenantSlug: 'unknown',
    );

    expect(await client.resolveImageUrl(employee), isNull);
  });

  test('falls back to public uuid image when auth lookup returns not found', () async {
    const store = AuthSessionStore();
    await store.save(
      PhoneLoginResponse(
        status: 'ok',
        token: 'app-session-token',
        expiresAt: DateTime.now().toUtc().add(const Duration(hours: 1)),
        user: const LoginUser(
          id: 'user-4',
          name: '강경훈',
          phoneNumber: '01012345678',
          tenantId: 'tenant-1',
          tenantName: '삼안',
          tenantSlug: 'saman',
        ),
      ),
    );

    final client = ProfileImageApiClient(
      httpClient: MockClient((request) async {
        return http.Response(
          jsonEncode({'found': false, 'source': 'DEFAULT'}),
          200,
          headers: {'content-type': 'application/json'},
        );
      }),
      baseUri: Uri.parse('https://114-auth.hmac.kr'),
      sessionStore: store,
    );

    const employee = Employee(
      id: 'bebb832c-052e-493d-b5a9-732518d67685',
      name: '강경훈',
      phoneNumber: '01012345678',
      email: 'khkang@samaneng.com',
      tenantId: 'tenant-1',
      tenantName: '삼안',
      tenantSlug: 'saman',
    );

    expect(
      await client.resolveImageUrl(employee),
      'https://baroncs.co.kr/employee_img/bebb832c-052e-493d-b5a9-732518d67685.jpg',
    );
  });

  test('uses uuid fallback even when auth not-found result is cached', () async {
    const store = AuthSessionStore();
    await store.save(
      PhoneLoginResponse(
        status: 'ok',
        token: 'app-session-token',
        expiresAt: DateTime.now().toUtc().add(const Duration(hours: 1)),
        user: const LoginUser(
          id: 'user-5',
          name: '직원',
          phoneNumber: '01012345678',
          tenantId: 'tenant-1',
          tenantName: '삼안',
          tenantSlug: 'saman',
        ),
      ),
    );

    var requestCount = 0;
    final client = ProfileImageApiClient(
      httpClient: MockClient((request) async {
        requestCount += 1;
        return http.Response(
          jsonEncode({'found': false, 'source': 'DEFAULT'}),
          200,
          headers: {'content-type': 'application/json'},
        );
      }),
      baseUri: Uri.parse('https://114-auth.hmac.kr'),
      sessionStore: store,
    );

    const firstEmployee = Employee(
      id: 'legacy-user-id',
      name: '직원',
      phoneNumber: '01012345678',
      email: 'cached-null@example.com',
      tenantId: 'tenant-1',
      tenantName: '삼안',
      tenantSlug: 'saman',
    );
    const secondEmployee = Employee(
      id: 'bebb832c-052e-493d-b5a9-732518d67685',
      name: '직원',
      phoneNumber: '01012345678',
      email: 'cached-null@example.com',
      tenantId: 'tenant-1',
      tenantName: '삼안',
      tenantSlug: 'saman',
    );

    expect(await client.resolveImageUrl(firstEmployee), isNull);
    expect(
      await client.resolveImageUrl(secondEmployee),
      'https://baroncs.co.kr/employee_img/bebb832c-052e-493d-b5a9-732518d67685.jpg',
    );
    expect(requestCount, 1);
  });
}
