using Microsoft.EntityFrameworkCore;
using MktZaloService.Domain.AggregatesModel.CustomerAggregate;
using MktZaloService.Domain.SeedWork;

namespace MktZaloService.Infrastructure.Repositories;

/// <summary>
/// EN: Repository implementation for ZaloCustomer aggregate.
/// VI: Repository implementation cho ZaloCustomer aggregate.
/// </summary>
public class CustomerRepository : ICustomerRepository
{
    private readonly MktZaloServiceContext _context;

    public IUnitOfWork UnitOfWork => _context;

    public CustomerRepository(MktZaloServiceContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    /// <summary>
    /// EN: Get customer by ID.
    /// VI: Lấy khách hàng theo ID.
    /// </summary>
    public async Task<ZaloCustomer?> GetByIdAsync(Guid id, CancellationToken ct = default)
    {
        return await _context.ZaloCustomers
            .Include(c => c.Tags)
            .FirstOrDefaultAsync(c => c.Id == id, ct);
    }

    /// <summary>
    /// EN: Find customer by Zalo user ID.
    /// VI: Tìm khách hàng theo Zalo user ID.
    /// </summary>
    public async Task<ZaloCustomer?> FindByZaloUserIdAsync(
        string zaloUserId,
        CancellationToken ct = default)
    {
        return await _context.ZaloCustomers
            .Include(c => c.Tags)
            .FirstOrDefaultAsync(c => c.ZaloUserId == zaloUserId, ct);
    }

    /// <summary>
    /// EN: Get or create customer by Zalo user info.
    /// VI: Lấy hoặc tạo khách hàng theo thông tin Zalo user.
    /// </summary>
    public async Task<ZaloCustomer> GetOrCreateAsync(
        string zaloUserId,
        string displayName,
        string? avatarUrl = null,
        CancellationToken ct = default)
    {
        var existing = await FindByZaloUserIdAsync(zaloUserId, ct);

        if (existing != null)
        {
            // EN: Update last interaction time
            // VI: Cập nhật thời gian tương tác cuối
            existing.RecordInteraction();
            return existing;
        }

        // EN: Create new customer
        // VI: Tạo khách hàng mới
        var customer = new ZaloCustomer(zaloUserId, displayName, avatarUrl);
        return Add(customer);
    }

    /// <summary>
    /// EN: Add a new customer.
    /// VI: Thêm khách hàng mới.
    /// </summary>
    public ZaloCustomer Add(ZaloCustomer customer)
    {
        return _context.ZaloCustomers.Add(customer).Entity;
    }

    /// <summary>
    /// EN: Update an existing customer.
    /// VI: Cập nhật khách hàng hiện có.
    /// </summary>
    public void Update(ZaloCustomer customer)
    {
        _context.Entry(customer).State = EntityState.Modified;
    }
}
