<?php
namespace App\Http\Controllers;
use App\Http\Requests\RankingHistoryRequest;use App\Models\{Keyword,SerpCheck};use App\Services\RankingHistoryService;use App\Support\KeywordTargetOptions;use Illuminate\Http\Request;use Illuminate\View\View;
class RankingHistoryController extends Controller{
 public function index(RankingHistoryRequest $r,RankingHistoryService $service):View{$projects=$r->user()->projects()->orderBy('name')->get(['id','ulid','name']);$keywords=Keyword::query()->whereHas('project',fn($q)=>$q->where('user_id',$r->user()->id))->with('project:id,ulid,name,domain')->orderBy('phrase')->get();if($r->filled('project')){$project=$projects->firstWhere('ulid',$r->input('project'));abort_unless($project,404);$keywords=$keywords->where('project_id',$project->id)->values();}$selected=collect($r->input('keywords',[]));if($selected->isNotEmpty()){abort_if($selected->diff($keywords->pluck('ulid'))->isNotEmpty(),404);$keywords=$keywords->whereIn('ulid',$selected)->values();}foreach(['search_engine'=>'engine','country_code'=>'country','language_code'=>'language','device'=>'device'] as $column=>$key)if($r->filled($key))$keywords=$keywords->where($column,$r->input($key))->values();$checks=$service->checksFor($keywords->pluck('id'),now()->parse($r->input('from'))->startOfDay(),now()->parse($r->input('to'))->endOfDay());$rows=$service->rows($checks);if($r->filled('movement'))$rows=$rows->where('movement',$r->input('movement'))->values();$page=max(1,(int)$r->input('page',1));$perPage=25;$paginator=new \Illuminate\Pagination\LengthAwarePaginator($rows->forPage($page,$perPage)->values(),$rows->count(),$perPage,$page,['path'=>$r->url(),'query'=>$r->query()]);$chart=$rows->whereNotNull('rank')->sortBy(fn($x)=>$x['check']->checked_at)->groupBy(fn($x)=>$x['keyword']->ulid)->take(10)->map(fn($series)=>['keyword'=>$series->first()['keyword']->phrase,'project'=>$series->first()['project']->name,'points'=>$series->map(fn($x)=>['date'=>$x['check']->checked_at->toIso8601String(),'rank'=>$x['rank'],'check'=>$x['check']->ulid])->values()])->values();return view('rankings.index',['projects'=>$projects,'keywords'=>$keywords,'rows'=>$paginator,'chart'=>$chart,'summary'=>$service->summary($rows,$keywords->count()),'distribution'=>$service->distribution($rows),'countries'=>KeywordTargetOptions::countries(),'languages'=>KeywordTargetOptions::languages()]);}
 public function keyword(Request $r,Keyword $keyword,RankingHistoryService $service):View{$this->ownedKeyword($r,$keyword);$from=now()->subYears(2);$checks=$service->checksFor(collect([$keyword->id]),$from,now());$rows=$service->rows($checks);$ranked=$rows->whereNotNull('rank');return view('rankings.keyword',['keyword'=>$keyword->load('project'),'rows'=>$rows,'metrics'=>['current'=>$ranked->first()['rank']??null,'previous'=>$ranked->skip(1)->first()['rank']??null,'best'=>$ranked->min('rank'),'worst'=>$ranked->max('rank'),'count'=>$ranked->count(),'top10'=>$ranked->count()?round($ranked->where('rank','<=',10)->count()/$ranked->count()*100):null],'countries'=>KeywordTargetOptions::countries(),'languages'=>KeywordTargetOptions::languages()]);}
 public function check(Request $r,SerpCheck $serpCheck,RankingHistoryService $service):View{abort_unless($serpCheck->keyword()->whereHas('project',fn($q)=>$q->where('user_id',$r->user()->id))->exists(),404);$serpCheck->load(['keyword.project','results'=>fn($q)=>$q->where('result_type','organic')->orderBy('position')->limit(10)]);return view('rankings.check',['check'=>$serpCheck,'rank'=>$serpCheck->results->where('is_project_domain',true)->min('position')]);}
 private function ownedKeyword(Request $r,Keyword $keyword):void{abort_unless($keyword->project()->where('user_id',$r->user()->id)->exists(),404);}
}
