namespace TaxBaik.Infrastructure.Repositories; using Dapper; using TaxBaik.Domain.Entities; using TaxBaik.Domain.Interfaces; public class InquiryRepository(IDbConnectionFactory connectionFactory) : BaseRepository(connectionFactory), IInquiryRepository { public async Task CreateAsync(Inquiry inquiry, CancellationToken cancellationToken = default) { using var conn = Conn(); return await conn.QueryFirstAsync( @"INSERT INTO inquiries (name, phone, email, service_type, message, status, ip_address, created_at) VALUES (@Name, @Phone, @Email, @ServiceType, @Message, @Status, @IpAddress, NOW()) RETURNING id", inquiry); } public async Task GetByIdAsync(int id, CancellationToken cancellationToken = default) { using var conn = Conn(); return await conn.QueryFirstOrDefaultAsync( @"SELECT id, name, phone, email, service_type, message, status, ip_address, client_id, admin_memo, created_at, updated_at FROM inquiries WHERE id = @Id", new { Id = id }); } public async Task<(IEnumerable Items, int Total)> GetPagedAsync( int page, int pageSize, string? status = null, CancellationToken cancellationToken = default) { using var conn = Conn(); var offset = (page - 1) * pageSize; using var reader = await conn.QueryMultipleAsync( @"SELECT id, name, phone, email, service_type, message, status, ip_address, client_id, admin_memo, created_at, updated_at FROM inquiries WHERE @Status::text IS NULL OR status = @Status ORDER BY created_at DESC LIMIT @PageSize OFFSET @Offset; SELECT COUNT(*) FROM inquiries WHERE @Status::text IS NULL OR status = @Status;", new { Status = status, PageSize = pageSize, Offset = offset }); var items = (await reader.ReadAsync()).ToList(); var total = await reader.ReadFirstAsync(); return (items, total); } public async Task CountAsync(CancellationToken cancellationToken = default) { using var conn = Conn(); return await conn.ExecuteScalarAsync("SELECT COUNT(*) FROM inquiries"); } public async Task CountThisMonthAsync(CancellationToken cancellationToken = default) { using var conn = Conn(); return await conn.ExecuteScalarAsync( @"SELECT COUNT(*) FROM inquiries WHERE created_at >= date_trunc('month', NOW()) AND created_at < date_trunc('month', NOW()) + INTERVAL '1 month'"); } public async Task CountByStatusAsync(string status, CancellationToken cancellationToken = default) { using var conn = Conn(); return await conn.ExecuteScalarAsync( "SELECT COUNT(*) FROM inquiries WHERE status = @Status", new { Status = status }); } public async Task CountByDateRangeAsync(DateTime startDate, DateTime endDate, CancellationToken cancellationToken = default) { using var conn = Conn(); return await conn.ExecuteScalarAsync( @"SELECT COUNT(*) FROM inquiries WHERE created_at >= @StartDate AND created_at <= @EndDate", new { StartDate = startDate, EndDate = endDate }); } public async Task CountByStatusAndDateAsync(string status, DateTime startDate, DateTime endDate, CancellationToken cancellationToken = default) { using var conn = Conn(); return await conn.ExecuteScalarAsync( @"SELECT COUNT(*) FROM inquiries WHERE status = @Status AND created_at >= @StartDate AND created_at <= @EndDate", new { Status = status, StartDate = startDate, EndDate = endDate }); } public async Task UpdateStatusAsync(int id, string status, CancellationToken cancellationToken = default) { using var conn = Conn(); await conn.ExecuteAsync( "UPDATE inquiries SET status = @Status, updated_at = NOW() WHERE id = @Id", new { Id = id, Status = status }); } public async Task UpdateAdminMemoAsync(int id, string? adminMemo, CancellationToken cancellationToken = default) { using var conn = Conn(); await conn.ExecuteAsync( "UPDATE inquiries SET admin_memo = @AdminMemo, updated_at = NOW() WHERE id = @Id", new { Id = id, AdminMemo = adminMemo }); } public async Task LinkClientAsync(int inquiryId, int clientId, CancellationToken cancellationToken = default) { using var conn = Conn(); await conn.ExecuteAsync( "UPDATE inquiries SET client_id = @ClientId, updated_at = NOW() WHERE id = @Id", new { Id = inquiryId, ClientId = clientId }); } public async Task DeleteAsync(int id, CancellationToken cancellationToken = default) { using var conn = Conn(); await conn.ExecuteAsync("DELETE FROM inquiries WHERE id = @Id", new { Id = id }); } }