<?php
namespace App\Services;
use App\Models\NotificationDeliveryAttempt;
use App\Models\NotificationPreference;
use App\Models\User;
use App\Notifications\LifecycleStatusNotification;
use Illuminate\Support\Collection;

class CrmNotificationService {
 public function send(iterable $recipients,string $event,string $title,string $message,string $url,string $entityType,int $entityId,string $status):void{
  foreach(collect($recipients)->filter()->unique('id') as $user){$pref=NotificationPreference::withoutGlobalScopes()->where('user_id',$user->id)->where('event',$event)->first();foreach(['database'=>'in_app','mail'=>'email'] as $channel=>$setting)if($pref?->{$setting}??true)$this->deliver($user,$event,$channel,compact('title','message','url','entityType','entityId','status'));}
 }
 public function assignment(User $user,object $entity,string $label,string $url):void{$this->send([$user],'assignment',$label.' assigned',"You have been assigned {$label} #{$entity->id}.",$url,$label,$entity->id,'assigned');}
 public function retry(NotificationDeliveryAttempt $attempt):void{$user=$attempt->user;$payload=$attempt->payload;$this->deliver($user,$attempt->event,$attempt->channel,$payload,$attempt->attempt+1);}
 private function deliver(User $user,string $event,string $channel,array $p,int $number=1):void{
  $attempt=NotificationDeliveryAttempt::withoutGlobalScopes()->create(['business_id'=>$user->business_id,'user_id'=>$user->id,'event'=>$event,'channel'=>$channel,'status'=>'pending','attempt'=>$number,'payload'=>$p,'attempted_at'=>now()]);
  try{$before=$user->notifications()->latest()->value('id');$user->notify(new LifecycleStatusNotification($p['title'],$p['message'],$p['url'],$p['entityType'],$p['entityId'],$p['status'],[$channel]));$after=$channel==='database'?$user->notifications()->latest()->value('id'):null;$attempt->update(['notification_id'=>$after&&$after!==$before?$after:null,'status'=>'sent','succeeded_at'=>now()]);}
  catch(\Throwable $e){$attempt->update(['status'=>'failed','error'=>$e->getMessage()]);report($e);}
 }
}
