import { Injectable, Inject, NotFoundException } from '@nestjs/common';
import { USER_REPOSITORY, IUserRepository } from '../../domain/repositories/user.repository.interface';

@Injectable()
export class UserProfileService {
  constructor(
    @Inject(USER_REPOSITORY) private readonly userRepo: IUserRepository,
  ) {}

  async getProfile(userId: string) {
    const user = await this.userRepo.findById(userId);
    if (!user) throw new NotFoundException('User not found');
    return {
      id: user.id,
      phone: user.phone,
      email: user.email,
      nickname: user.nickname,
      avatarUrl: user.avatarUrl,
      kycLevel: user.kycLevel,
      walletMode: user.walletMode,
      role: user.role,
      residenceState: user.residenceState,
      nationality: user.nationality,
      createdAt: user.createdAt,
    };
  }

  async updateProfile(userId: string, data: { nickname?: string; avatarUrl?: string; residenceState?: string; nationality?: string }) {
    const user = await this.userRepo.findById(userId);
    if (!user) throw new NotFoundException('User not found');
    return this.userRepo.updateProfile(userId, data);
  }

  async getSettings(userId: string) {
    const user = await this.userRepo.findById(userId);
    if (!user) throw new NotFoundException('User not found');
    return {
      language: user.preferredLanguage || 'zh-CN',
      currency: user.preferredCurrency || 'CNY',
      notificationPrefs: user.notificationPrefs || { trade: true, expiry: true, marketing: false },
    };
  }

  async updateSettings(userId: string, data: { language?: string; currency?: string; notificationPrefs?: { trade?: boolean; expiry?: boolean; marketing?: boolean } }) {
    const user = await this.userRepo.findById(userId);
    if (!user) throw new NotFoundException('User not found');

    const updateData: Record<string, any> = {};
    if (data.language !== undefined) updateData.preferredLanguage = data.language;
    if (data.currency !== undefined) updateData.preferredCurrency = data.currency;
    if (data.notificationPrefs !== undefined) {
      // Merge with existing prefs so partial updates are supported
      const existing = user.notificationPrefs || { trade: true, expiry: true, marketing: false };
      updateData.notificationPrefs = {
        trade: data.notificationPrefs.trade !== undefined ? data.notificationPrefs.trade : existing.trade,
        expiry: data.notificationPrefs.expiry !== undefined ? data.notificationPrefs.expiry : existing.expiry,
        marketing: data.notificationPrefs.marketing !== undefined ? data.notificationPrefs.marketing : existing.marketing,
      };
    }

    await this.userRepo.updateProfile(userId, updateData);

    return this.getSettings(userId);
  }

  async listUsers(page: number, limit: number) {
    const [users, total] = await this.userRepo.findAll(page, limit);
    return {
      items: users.map(u => ({
        id: u.id, phone: u.phone, email: u.email, nickname: u.nickname,
        role: u.role, kycLevel: u.kycLevel, status: u.status, createdAt: u.createdAt,
      })),
      total,
      page,
      limit,
    };
  }

  async freezeUser(userId: string) {
    await this.userRepo.updateStatus(userId, 'frozen');
  }

  async unfreezeUser(userId: string) {
    await this.userRepo.updateStatus(userId, 'active');
  }
}
