using GreenHome.Application; using GreenHome.Infrastructure.Data; using GreenHome.Sms.Ippanel; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; namespace GreenHome.Infrastructure.Services.Device; public sealed class DeviceTokenService : IDeviceTokenService { private readonly GreenHomeDbContext _dbContext; private readonly ISmsService _smsService; private readonly ILogger _logger; public DeviceTokenService( GreenHomeDbContext dbContext, ISmsService smsService, ILogger logger) { _dbContext = dbContext; _smsService = smsService; _logger = logger; } public async Task GetUploadIntervalAsync( GetUploadIntervalRequest request, CancellationToken cancellationToken) { try { Domain.DeviceSettings? settings = null; if (request.DeviceId.HasValue) { settings = await _dbContext.DeviceSettings .AsNoTracking() .FirstOrDefaultAsync(ds => ds.DeviceId == request.DeviceId.Value, cancellationToken); } else if (!string.IsNullOrWhiteSpace(request.DevicePhoneNumber)) { settings = await _dbContext.DeviceSettings .AsNoTracking() .FirstOrDefaultAsync(ds => ds.DevicePhoneNumber == request.DevicePhoneNumber, cancellationToken); } if (settings == null) { return new GetUploadIntervalResponse { Success = false, Message = "دستگاه یافت نشد" }; } return new GetUploadIntervalResponse { Success = true, UploadIntervalMin = settings.UploadIntervalMin }; } catch (Exception ex) { _logger.LogError(ex, "Error getting upload interval for device"); return new GetUploadIntervalResponse { Success = false, Message = "خطا در دریافت اطلاعات" }; } } public async Task RequestDeviceTokenAsync( RequestDeviceTokenRequest request, CancellationToken cancellationToken) { try { var settings = await _dbContext.DeviceSettings .FirstOrDefaultAsync(ds => ds.DevicePhoneNumber == request.DevicePhoneNumber, cancellationToken); if (settings == null) { return new RequestDeviceTokenResponse { Success = false, Message = "دستگاه با این شماره تلفن یافت نشد" }; } var random = new Random(); var tokenCode = random.Next(10000, 99999).ToString(); var verificationCode = ((int.Parse(tokenCode) * 7 + 12345) % 100000).ToString("D5"); settings.TokenCode = tokenCode; settings.VerificationCode = verificationCode; settings.TokenExpiresAt = DateTime.UtcNow.AddMinutes(30); settings.UpdatedAt = DateTime.UtcNow; await _dbContext.SaveChangesAsync(cancellationToken); try { await _smsService.SendPatternSmsAsync(new PatternSmsRequest { Recipients = new List { request.DevicePhoneNumber }, PatternCode = "gfukab9r0nca0pt", Variables = new Dictionary { { "tel", "09192530212" }, { "verifyCode", verificationCode } } }, cancellationToken); } catch (Exception smsEx) { _logger.LogError(smsEx, "Error sending token SMS to {PhoneNumber}", request.DevicePhoneNumber); return new RequestDeviceTokenResponse { Success = false, Message = "خطا در ارسال پیامک" }; } _logger.LogInformation("Token requested for device phone {PhoneNumber}", request.DevicePhoneNumber); return new RequestDeviceTokenResponse { Success = true, Message = "کد تایید با موفقیت ارسال شد", TokenCode = $"0911925302120#{tokenCode}" }; } catch (Exception ex) { _logger.LogError(ex, "Error requesting device token"); return new RequestDeviceTokenResponse { Success = false, Message = "خطا در درخواست توکن" }; } } public async Task VerifyDeviceTokenAsync( VerifyDeviceTokenRequest request, CancellationToken cancellationToken) { try { var settings = await _dbContext.DeviceSettings .Include(ds => ds.Device) .FirstOrDefaultAsync(ds => ds.DevicePhoneNumber == request.DevicePhoneNumber, cancellationToken); if (settings == null) { return new VerifyDeviceTokenResponse { Success = false, Message = "دستگاه با این شماره تلفن یافت نشد" }; } if (settings.TokenExpiresAt == null || settings.TokenExpiresAt < DateTime.UtcNow) { return new VerifyDeviceTokenResponse { Success = false, Message = "کد تایید منقضی شده است" }; } if (settings.VerificationCode != request.VerificationCode) { return new VerifyDeviceTokenResponse { Success = false, Message = "کد تایید نادرست است" }; } var rnd = new Random(); var deviceId = settings.Device.Id + "01"; var uploadInterval = rnd.Next(1, 9) + "" + settings.UploadIntervalMin; var smsInterval = settings.MinimumSmsIntervalMinutes > 0 ? "1" + settings.MinimumSmsIntervalMinutes : "0" + rnd.Next(1, 9); var sysNumber = rnd.Next(139, 97654); var simType = rnd.Next(1, 9).ToString() + ((int?)settings.SimCardType)?.ToString() ?? "1"; try { await _smsService.SendPatternSmsAsync(new PatternSmsRequest { Recipients = new List { request.DevicePhoneNumber }, PatternCode = "kx3kfqri7g09r02", Variables = new Dictionary { { "deviceId", deviceId }, { "uploadInterval", uploadInterval }, { "smsInterval", smsInterval.ToString() }, { "SysNumber", sysNumber.ToString() }, { "SimType", simType } } }, cancellationToken); } catch (Exception smsEx) { _logger.LogError(smsEx, "Error sending settings SMS to {PhoneNumber}", request.DevicePhoneNumber); return new VerifyDeviceTokenResponse { Success = false, Message = "خطا در ارسال پیامک" }; } settings.TokenCode = null; settings.VerificationCode = null; settings.TokenExpiresAt = null; settings.UpdatedAt = DateTime.UtcNow; await _dbContext.SaveChangesAsync(cancellationToken); _logger.LogInformation("Device token verified for {PhoneNumber}", request.DevicePhoneNumber); return new VerifyDeviceTokenResponse { Success = true, Message = "تنظیمات با موفقیت ارسال شد", EncodedSettings = null }; } catch (Exception ex) { _logger.LogError(ex, "Error verifying device token"); return new VerifyDeviceTokenResponse { Success = false, Message = "خطا در تایید توکن" }; } } }