import 'package:pocketbase/pocketbase.dart';
import '../api/pocketbase_client.dart';
import '../../models/platform_admin.dart';
import '../../models/tenant.dart';
import '../../models/user_profile.dart';

class AuthRepository {
  AuthRepository._();
  static final instance = AuthRepository._();

  PocketBase get _pb => PocketBaseClient.instance.pb;
  PocketBaseClient get _client => PocketBaseClient.instance;

  Future<AuthResult> login(
    String email,
    String password, {
    required bool rememberSession,
  }) async {
    await _client.setRememberSession(rememberSession);
    await _pb.collection('users').authWithPassword(email, password);
    return _buildAuthResult();
  }

  Future<void> logout() async {
    _pb.authStore.clear();
  }

  Future<bool> isLoggedIn() async {
    if (!_pb.authStore.isValid) return false;
    try {
      await _pb.collection('users').authRefresh();
      return true;
    } catch (_) {
      _pb.authStore.clear();
      return false;
    }
  }

  Future<AuthResult> register({
    required String email,
    required String password,
    String? firstName,
    String? lastName,
  }) async {
    await _pb.collection('users').create(body: {
      'email': email,
      'password': password,
      'passwordConfirm': password,
      'emailVisibility': true,
      if (firstName != null && firstName.isNotEmpty) 'first_name': firstName,
      if (lastName != null && lastName.isNotEmpty) 'last_name': lastName,
    });
    return login(
      email,
      password,
      rememberSession: _client.rememberSession,
    );
  }

  Future<AuthResult> refreshSession() async {
    try {
      await _pb.collection('users').authRefresh();
    } catch (_) {}
    return _buildAuthResult();
  }

  Future<void> updateUserLanguage(String userId, String languageCode) async {
    await _pb.collection('users').update(userId, body: {
      'preferred_language': languageCode,
    });
  }

  Future<void> updateTenant(
    String id, {
    String? companyName,
    String? defaultCurrency,
    String? companyAddress,
    String? city,
    String? district,
    double? latitude,
    double? longitude,
    List<String>? workflowOverrides,
  }) async {
    final body = <String, dynamic>{};
    if (companyName != null) body['company_name'] = companyName;
    if (defaultCurrency != null) body['default_currency'] = defaultCurrency;
    if (companyAddress != null) body['company_address'] = companyAddress;
    if (city != null) body['city'] = city;
    if (district != null) body['district'] = district;
    if (latitude != null) body['latitude'] = latitude;
    if (longitude != null) body['longitude'] = longitude;
    if (workflowOverrides != null) {
      body['workflow_overrides'] = workflowOverrides;
    }
    if (body.isEmpty) return;
    await _pb.collection('tenants').update(id, body: body);
  }

  Future<AuthResult> _buildAuthResult() async {
    final record = _pb.authStore.record!;
    final user = UserProfile.fromJson(record.toJson());
    List<TenantMembership> tenants = [];
    List<PlatformMembership> platformMemberships = [];
    try {
      tenants = await _fetchUserTenants(record.id);
    } catch (_) {}
    try {
      platformMemberships = await _fetchPlatformMemberships(record.id);
    } catch (_) {}
    return AuthResult(
      user: user,
      tenants: tenants,
      platformMemberships: platformMemberships,
    );
  }

  Future<List<TenantMembership>> _fetchUserTenants(String userId) async {
    final result = await _pb.collection('tenant_members').getList(
          filter: 'user_id = "$userId"',
          expand: 'tenant_id',
          perPage: 50,
        );
    return result.items
        .map((r) => TenantMembership.fromJson(r.toJson()))
        .toList();
  }

  Future<List<PlatformMembership>> _fetchPlatformMemberships(
    String userId,
  ) async {
    final result = await _pb.collection('platform_memberships').getList(
          filter: 'user_id = "$userId"',
          perPage: 20,
        );
    return result.items
        .map((r) => PlatformMembership.fromJson(r.toJson()))
        .toList();
  }
}

class AuthResult {
  const AuthResult({
    required this.user,
    required this.tenants,
    this.platformMemberships = const [],
  });
  final UserProfile user;
  final List<TenantMembership> tenants;
  final List<PlatformMembership> platformMemberships;
}
