<?php

namespace App\Http\Controllers;

use App\Enums\ProjectStatus;
use App\Http\Requests\StoreProjectRequest;
use App\Http\Requests\UpdateProjectRequest;
use App\Models\Project;
use App\Services\ProjectUrlNormalizer;
use Illuminate\Database\QueryException;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;

class ProjectController extends Controller
{
    public function index(Request $request): View
    {
        $this->authorize('viewAny', Project::class);
        $archived = $request->string('filter')->toString() === 'archived';
        $projects = $request->user()->projects()
            ->where('status', $archived ? ProjectStatus::Archived : ProjectStatus::Active)
            ->withCount(['keywords' => fn ($query) => $query->active()])
            ->orderByDesc('id')->paginate(15)->withQueryString();
        return view('projects.index', compact('projects', 'archived'));
    }

    public function create(): View
    {
        $this->authorize('create', Project::class);
        return view('projects.create');
    }

    public function store(StoreProjectRequest $request, ProjectUrlNormalizer $normalizer): RedirectResponse
    {
        $normalized = $normalizer->normalize($request->string('website_url')->toString());
        try {
            $project = $request->user()->projects()->create([
                'name' => $request->string('name')->trim()->toString(),
                'domain' => $normalized->domain,
                'url' => $normalized->url,
            ]);
        } catch (QueryException $exception) {
            $this->throwDuplicateValidation($exception);
        }
        return redirect()->route('projects.show', $project)->with('status', 'Proje oluşturuldu.');
    }

    public function show(Project $customerProject): View
    {
        $this->authorize('view', $customerProject);
        $customerProject->load(['keywords' => fn ($q) => $q->active()->orderBy('phrase'), 'keywords.serpChecks' => fn ($q) => $q->where('status', 'completed')->latest('checked_at')->with(['results' => fn ($r) => $r->where('is_project_domain', true)->orderBy('position')])]);
        $rows = $customerProject->keywords->map(function ($keyword) { $checks=$keyword->serpChecks->filter(fn($c)=>$c->results->isNotEmpty())->values();$current=$checks->get(0);$previous=$checks->get(1);$rank=$current?->results->min('position');$prior=$previous?->results->min('position');return ['current'=>$rank,'change'=>($rank&&$prior)?$prior-$rank:null,'checked_at'=>$current?->checked_at]; });
        $measured=$rows->whereNotNull('current');
        return view('projects.show', ['project'=>$customerProject,'summary'=>['keywords'=>$customerProject->keywords->count(),'last_check'=>$rows->max('checked_at'),'average'=>$measured->isNotEmpty()?round($measured->avg('current'),1):null,'top10'=>$measured->where('current','<=',10)->count(),'winners'=>$rows->where('change','>',0)->count(),'losers'=>$rows->where('change','<',0)->count()]]);
    }

    public function edit(Project $customerProject): View
    {
        $this->authorize('update', $customerProject);
        return view('projects.edit', ['project' => $customerProject]);
    }

    public function update(UpdateProjectRequest $request, Project $customerProject, ProjectUrlNormalizer $normalizer): RedirectResponse
    {
        $normalized = $normalizer->normalize($request->string('website_url')->toString());
        try {
            $customerProject->update([
                'name' => $request->string('name')->trim()->toString(),
                'domain' => $normalized->domain,
                'url' => $normalized->url,
            ]);
        } catch (QueryException $exception) {
            $this->throwDuplicateValidation($exception);
        }
        return redirect()->route('projects.show', $customerProject)->with('status', 'Proje güncellendi.');
    }

    public function archive(Project $customerProject): RedirectResponse
    {
        $this->authorize('archive', $customerProject);
        $customerProject->archive();
        return redirect()->route('projects.index')->with('status', 'Proje arşivlendi.');
    }

    public function restore(Project $customerProject): RedirectResponse
    {
        $this->authorize('restore', $customerProject);
        $customerProject->restoreProject();
        return redirect()->route('projects.show', $customerProject)->with('status', 'Proje yeniden etkinleştirildi.');
    }

    private function throwDuplicateValidation(QueryException $exception): never
    {
        if (! in_array((string) $exception->getCode(), ['23000', '19'], true)) throw $exception;
        throw ValidationException::withMessages(['website_url' => 'Bu alan adı hesabınızda zaten kayıtlı.']);
    }
}
