/// Registration State Provider
///
/// Manages registration state for the Worker application.
/// Handles user registration with role-based validation and verification.
///
/// Uses Riverpod 3.0 with code generation for type-safe state management.
library;

import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:worker/features/auth/domain/entities/user.dart';

part 'register_provider.g.dart';

/// Registration Form Data
///
/// Contains all data needed for user registration.
/// Optional fields are used based on selected role.
class RegistrationData {
  /// Required: Full name of the user
  final String fullName;

  /// Required: Phone number (Vietnamese format)
  final String phoneNumber;

  /// Required: Email address
  final String email;

  /// Required: Password (minimum 6 characters)
  final String password;

  /// Required: User role
  final UserRole role;

  /// Optional: CCCD/ID card number (required for dealer/worker roles)
  final String? cccd;

  /// Optional: Tax code (personal or company)
  final String? taxCode;

  /// Optional: Company/store name
  final String? companyName;

  /// Required: Province/city
  final String? city;

  /// Optional: Attachment file paths (ID card, certificate, license)
  final List<String>? attachments;

  const RegistrationData({
    required this.fullName,
    required this.phoneNumber,
    required this.email,
    required this.password,
    required this.role,
    this.cccd,
    this.taxCode,
    this.companyName,
    this.city,
    this.attachments,
  });

  /// Copy with method for immutability
  RegistrationData copyWith({
    String? fullName,
    String? phoneNumber,
    String? email,
    String? password,
    UserRole? role,
    String? cccd,
    String? taxCode,
    String? companyName,
    String? city,
    List<String>? attachments,
  }) {
    return RegistrationData(
      fullName: fullName ?? this.fullName,
      phoneNumber: phoneNumber ?? this.phoneNumber,
      email: email ?? this.email,
      password: password ?? this.password,
      role: role ?? this.role,
      cccd: cccd ?? this.cccd,
      taxCode: taxCode ?? this.taxCode,
      companyName: companyName ?? this.companyName,
      city: city ?? this.city,
      attachments: attachments ?? this.attachments,
    );
  }
}

/// Registration State Provider
///
/// Main provider for user registration state management.
/// Handles registration process with role-based validation.
///
/// Usage in widgets:
/// ```dart
/// final registerState = ref.watch(registerProvider);
/// registerState.when(
///   data: (user) => SuccessScreen(user),
///   loading: () => LoadingIndicator(),
///   error: (error, stack) => ErrorWidget(error),
/// );
/// ```
@riverpod
class Register extends _$Register {
  /// Initialize with no registration result
  @override
  Future<User?> build() async {
    // No initial registration
    return null;
  }

  /// Register a new user
  ///
  /// Performs user registration with role-based validation.
  /// For dealer/worker roles, requires additional verification documents.
  ///
  /// Parameters:
  /// - [data]: Registration form data containing all required fields
  ///
  /// Returns: Newly created User object on success
  ///
  /// Throws: Exception on validation failure or registration error
  ///
  /// Error messages (Vietnamese):
  /// - "Vui lòng điền đầy đủ thông tin bắt buộc"
  /// - "Số điện thoại không hợp lệ"
  /// - "Email không hợp lệ"
  /// - "Mật khẩu phải có ít nhất 6 ký tự"
  /// - "Vui lòng nhập số CCCD/CMND" (for dealer/worker)
  /// - "Vui lòng tải lên ảnh CCCD/CMND" (for dealer/worker)
  /// - "Vui lòng tải lên ảnh chứng chỉ hành nghề hoặc GPKD" (for dealer/worker)
  /// - "Số điện thoại đã được đăng ký"
  /// - "Email đã được đăng ký"
  Future<void> register(RegistrationData data) async {
    // Set loading state
    state = const AsyncValue.loading();

    // Perform registration with error handling
    state = await AsyncValue.guard(() async {
      // Validate required fields
      if (data.fullName.isEmpty ||
          data.phoneNumber.isEmpty ||
          data.email.isEmpty ||
          data.password.isEmpty ||
          data.city == null ||
          data.city!.isEmpty) {
        throw Exception('Vui lòng điền đầy đủ thông tin bắt buộc');
      }

      // Validate phone number (Vietnamese format: 10 digits starting with 0)
      final phoneRegex = RegExp(r'^0[0-9]{9}$');
      if (!phoneRegex.hasMatch(data.phoneNumber)) {
        throw Exception('Số điện thoại không hợp lệ');
      }

      // Validate email format
      final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
      if (!emailRegex.hasMatch(data.email)) {
        throw Exception('Email không hợp lệ');
      }

      // Validate password length
      if (data.password.length < 6) {
        throw Exception('Mật khẩu phải có ít nhất 6 ký tự');
      }

      // Role-based validation for dealer/worker (requires verification)
      if (data.role == UserRole.customer) {
        // For dealer/worker roles, CCCD and attachments are required
        if (data.cccd == null || data.cccd!.isEmpty) {
          throw Exception('Vui lòng nhập số CCCD/CMND');
        }

        // Validate CCCD format (9 or 12 digits)
        final cccdRegex = RegExp(r'^[0-9]{9}$|^[0-9]{12}$');
        if (!cccdRegex.hasMatch(data.cccd!)) {
          throw Exception('Số CCCD/CMND không hợp lệ (phải có 9 hoặc 12 số)');
        }

        // Validate attachments
        if (data.attachments == null || data.attachments!.isEmpty) {
          throw Exception('Vui lòng tải lên ảnh CCCD/CMND');
        }

        if (data.attachments!.length < 2) {
          throw Exception('Vui lòng tải lên ảnh chứng chỉ hành nghề hoặc GPKD');
        }
      }

      // Simulate API call delay (2 seconds)
      await Future<void>.delayed(const Duration(seconds: 2));

      // TODO: In production, call the registration API here
      // final response = await ref.read(authRepositoryProvider).register(data);

      // Mock: Simulate registration success
      final now = DateTime.now();

      // Determine initial status based on role
      // Dealer/Worker require admin approval (pending status)
      // Other roles are immediately active
      final initialStatus = data.role == UserRole.customer
          ? UserStatus.pending
          : UserStatus.active;

      // Create new user entity
      final newUser = User(
        userId: 'user_${DateTime.now().millisecondsSinceEpoch}',
        phoneNumber: data.phoneNumber,
        fullName: data.fullName,
        email: data.email,
        role: data.role,
        status: initialStatus,
        loyaltyTier: LoyaltyTier.gold, // Default tier for new users
        totalPoints: 0, // New users start with 0 points
        companyInfo: data.companyName != null || data.taxCode != null
            ? CompanyInfo(
                name: data.companyName,
                taxId: data.taxCode,
                businessType: _getBusinessType(data.role),
              )
            : null,
        cccd: data.cccd,
        attachments: data.attachments ?? [],
        address: data.city,
        avatarUrl: null,
        referralCode: 'REF${data.phoneNumber.substring(0, 6)}',
        referredBy: null,
        erpnextCustomerId: null,
        createdAt: now,
        updatedAt: now,
        lastLoginAt: null, // Not logged in yet
      );

      return newUser;
    });
  }

  /// Reset registration state
  ///
  /// Clears the registration result. Useful when navigating away
  /// from success screen or starting a new registration.
  Future<void> reset() async {
    state = const AsyncValue.data(null);
  }

  /// Get business type based on user role
  String _getBusinessType(UserRole role) {
    switch (role) {
      case UserRole.customer:
        return 'Đại lý/Thầu thợ/Kiến trúc sư';
      case UserRole.sales:
        return 'Nhân viên kinh doanh';
      case UserRole.admin:
        return 'Quản trị viên';
      case UserRole.accountant:
        return 'Kế toán';
      case UserRole.designer:
        return 'Thiết kế';
    }
  }

  /// Check if registration is in progress
  bool get isLoading => state.isLoading;

  /// Get registration error if any
  Object? get error => state.error;

  /// Get registered user if successful
  User? get registeredUser => state.value;

  /// Check if registration was successful
  bool get isSuccess => state.hasValue && state.value != null;
}

/// Convenience provider for checking if registration is in progress
///
/// Usage:
/// ```dart
/// final isRegistering = ref.watch(isRegisteringProvider);
/// if (isRegistering) {
///   // Show loading indicator
/// }
/// ```
@riverpod
bool isRegistering(Ref ref) {
  final registerState = ref.watch(registerProvider);
  return registerState.isLoading;
}

/// Convenience provider for checking if registration was successful
///
/// Usage:
/// ```dart
/// final success = ref.watch(registrationSuccessProvider);
/// if (success) {
///   // Navigate to pending approval or OTP screen
/// }
/// ```
@riverpod
bool registrationSuccess(Ref ref) {
  final registerState = ref.watch(registerProvider);
  return registerState.hasValue && registerState.value != null;
}
