<?php
namespace App\Services;
use App\Models\{User,Project,Attachment};
use Illuminate\Support\Facades\{DB,Storage};
use Illuminate\Http\UploadedFile;
class PrivateFiles {
 public function store(UploadedFile $file,int $userId,?int $projectId,string $context,?int $contextId=null):Attachment {
  return DB::transaction(function()use($file,$userId,$projectId,$context,$contextId){
   User::whereKey($userId)->lockForUpdate()->firstOrFail();
   if($projectId)Project::whereKey($projectId)->lockForUpdate()->firstOrFail();
   abort_if(Attachment::where('user_id',$userId)->sum('size')+$file->getSize()>Settings::get('user_storage_mb',2048)*1048576,422,'فضای حساب برای دریافت این فایل کافی نیست.');
   if($projectId)abort_if(Attachment::where('project_id',$projectId)->sum('size')+$file->getSize()>Settings::get('project_storage_mb',1024)*1048576,422,'فضای پروژه برای دریافت این فایل کافی نیست.');
   $path=$file->store('uploads/'.now()->format('Y/m'),'private');
   try{return Attachment::create(['user_id'=>$userId,'project_id'=>$projectId,'context'=>$context,'context_id'=>$contextId,'path'=>$path,'name'=>mb_substr(basename($file->getClientOriginalName()),0,180),'mime'=>$file->getMimeType(),'size'=>$file->getSize()]);}catch(\Throwable $e){Storage::disk('private')->delete($path);throw $e;}
  },3);
 }
}
