import 'package:flutter/widgets.dart' show Locale;
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pocketbase/pocketbase.dart';
import '../auth/auth_repository.dart';
import '../services/notification_service.dart';
import '../../models/platform_admin.dart';
import '../../models/tenant.dart';
import '../../models/user_profile.dart';
import '../../features/shared/tenant_location_data.dart';
import 'locale_provider.dart';

class AuthState {
  const AuthState({
    this.profile,
    this.activeTenant,
    this.memberships = const [],
    this.platformMemberships = const [],
    this.isLoading = true,
    this.error,
  });

  final UserProfile? profile;
  final TenantMembership? activeTenant;
  final List<TenantMembership> memberships;
  final List<PlatformMembership> platformMemberships;
  final bool isLoading;
  final String? error;

  bool get isAuthenticated => profile != null;
  bool get isSuperAdmin => platformMemberships.any((m) => m.isSuperAdmin);
  PlatformMembership? get primaryPlatformMembership {
    for (final membership in platformMemberships) {
      if (membership.isActive) return membership;
    }
    return null;
  }

  AuthState copyWith({
    UserProfile? profile,
    TenantMembership? activeTenant,
    List<TenantMembership>? memberships,
    List<PlatformMembership>? platformMemberships,
    bool? isLoading,
    String? error,
    bool clearError = false,
  }) =>
      AuthState(
        profile: profile ?? this.profile,
        activeTenant: activeTenant ?? this.activeTenant,
        memberships: memberships ?? this.memberships,
        platformMemberships: platformMemberships ?? this.platformMemberships,
        isLoading: isLoading ?? this.isLoading,
        error: clearError ? null : (error ?? this.error),
      );
}

class AuthNotifier extends StateNotifier<AuthState> {
  AuthNotifier({this.onLocaleLoaded}) : super(const AuthState()) {
    _init();
  }

  final void Function(String languageCode)? onLocaleLoaded;
  final _repo = AuthRepository.instance;

  Future<void> _init() async {
    final loggedIn = await _repo.isLoggedIn();
    if (!loggedIn) {
      state = const AuthState(isLoading: false);
      return;
    }
    try {
      final result = await _repo.refreshSession();
      state = AuthState(
        profile: result.user,
        memberships: result.tenants,
        platformMemberships: result.platformMemberships,
        activeTenant: result.tenants.isEmpty ? null : result.tenants.first,
        isLoading: false,
      );
      final isLab =
          result.tenants.isNotEmpty && result.tenants.first.tenant.isLab;
      NotificationService.loginUser(result.user.id, isLab: isLab);
      _applyLocale(result.user.preferredLanguage);
    } catch (_) {
      state = const AuthState(isLoading: false);
    }
  }

  void _applyLocale(String? code) {
    if (code != null && code.isNotEmpty) {
      onLocaleLoaded?.call(code);
    }
  }

  Future<void> signIn(
    String email,
    String password, {
    required bool rememberSession,
  }) async {
    state = state.copyWith(isLoading: true, clearError: true);
    try {
      final result = await _repo.login(
        email,
        password,
        rememberSession: rememberSession,
      );
      state = AuthState(
        profile: result.user,
        memberships: result.tenants,
        platformMemberships: result.platformMemberships,
        activeTenant: result.tenants.isEmpty ? null : result.tenants.first,
        isLoading: false,
      );
      final isLab =
          result.tenants.isNotEmpty && result.tenants.first.tenant.isLab;
      NotificationService.loginUser(result.user.id, isLab: isLab);
      _applyLocale(result.user.preferredLanguage);
    } catch (e) {
      state = state.copyWith(isLoading: false, error: _parseError(e));
    }
  }

  Future<void> register({
    required String email,
    required String password,
    String? firstName,
    String? lastName,
  }) async {
    state = state.copyWith(isLoading: true, clearError: true);
    try {
      final result = await _repo.register(
        email: email,
        password: password,
        firstName: firstName,
        lastName: lastName,
      );
      state = AuthState(
        profile: result.user,
        memberships: result.tenants,
        platformMemberships: result.platformMemberships,
        activeTenant: result.tenants.isEmpty ? null : result.tenants.first,
        isLoading: false,
      );
    } catch (e) {
      state = state.copyWith(isLoading: false, error: _parseError(e));
      rethrow;
    }
  }

  Future<void> signOut() async {
    await _repo.logout();
    await NotificationService.logoutUser();
    state = const AuthState(isLoading: false);
  }

  void setActiveTenant(TenantMembership membership) {
    state = state.copyWith(activeTenant: membership);
  }

  Future<void> refresh() async {
    try {
      final result = await _repo.refreshSession();
      final currentId = state.activeTenant?.tenant.id;
      final newActive = currentId != null
          ? result.tenants.firstWhere(
              (m) => m.tenant.id == currentId,
              orElse: () => result.tenants.isNotEmpty
                  ? result.tenants.first
                  : state.activeTenant!,
            )
          : (result.tenants.isNotEmpty ? result.tenants.first : null);
      state = state.copyWith(
        profile: result.user,
        memberships: result.tenants,
        platformMemberships: result.platformMemberships,
        activeTenant: newActive,
      );
    } catch (_) {}
  }

  Future<void> updateLanguage(String languageCode) async {
    final userId = state.profile?.id;
    if (userId == null) return;
    await _repo.updateUserLanguage(userId, languageCode);
  }

  Future<void> updateTenantInfo({
    required String tenantId,
    required String companyName,
    String? defaultCurrency,
    TenantLocationData? location,
    List<String>? workflowOverrides,
  }) async {
    await _repo.updateTenant(
      tenantId,
      companyName: companyName,
      defaultCurrency: defaultCurrency,
      companyAddress: location?.address,
      city: location?.city,
      district: location?.district,
      latitude: location?.latitude,
      longitude: location?.longitude,
      workflowOverrides: workflowOverrides,
    );
    await refresh();
  }

  String _parseError(Object e) {
    if (e is ClientException) {
      final code = e.statusCode;
      if (code == 400 || code == 401 || code == 403) {
        return 'E-posta veya şifre hatalı.';
      }
      final msg = e.response['message'] as String? ?? '';
      if (msg.isNotEmpty) return msg;
    }
    return 'Bağlantı hatası. Lütfen tekrar deneyin.';
  }
}

final authProvider = StateNotifierProvider<AuthNotifier, AuthState>((ref) {
  return AuthNotifier(
    onLocaleLoaded: (code) =>
        ref.read(localeProvider.notifier).setLocale(Locale(code)),
  );
});
