<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreLeadRequest;
use App\Http\Requests\UpdateLeadRequest;
use App\Models\Lead;
use App\Models\PipelineStage;
use App\Models\User;
use App\Services\LeadService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class LeadController extends Controller
{
    public function __construct(
        private LeadService $leadService
    ) {}

    public function index(Request $request): View
    {
        $this->authorize('viewAny', Lead::class);

        $q = Lead::query()->with(['stage', 'assignee']);

        if ($search = $request->string('q')->toString()) {
            $q->where(function ($query) use ($search) {
                $query->where('name', 'like', '%'.$search.'%')
                    ->orWhere('email', 'like', '%'.$search.'%')
                    ->orWhere('phone', 'like', '%'.$search.'%');
            });
        }

        if ($stage = $request->integer('stage_id')) {
            $q->where('pipeline_stage_id', $stage);
        }

        if ($agent = $request->integer('assigned_to')) {
            $q->where('assigned_to', $agent);
        }

        $leads = $q->latest()->paginate(15)->withQueryString();

        $stages = PipelineStage::orderBy('sort_order')->get();
        $agents = User::orderBy('name')->get();

        return view('leads.index', compact('leads', 'stages', 'agents'));
    }

    public function create(): View
    {
        $this->authorize('create', Lead::class);

        $stages = PipelineStage::orderBy('sort_order')->get();
        $agents = User::orderBy('name')->get();

        return view('leads.create', compact('stages', 'agents'));
    }

    public function store(StoreLeadRequest $request): RedirectResponse
    {
        $this->authorize('create', Lead::class);

        $this->leadService->create($request->validated(), $request->user());

        return redirect()->route('leads.index')->with('success', 'Lead created.');
    }

    public function show(Lead $lead): View
    {
        $this->authorize('view', $lead);

        $lead->load(['stage', 'assignee', 'activities.user', 'customer']);

        return view('leads.show', compact('lead'));
    }

    public function edit(Lead $lead): View
    {
        $this->authorize('update', $lead);

        $stages = PipelineStage::orderBy('sort_order')->get();
        $agents = User::orderBy('name')->get();

        return view('leads.edit', compact('lead', 'stages', 'agents'));
    }

    public function update(UpdateLeadRequest $request, Lead $lead): RedirectResponse
    {
        $this->authorize('update', $lead);

        $this->leadService->update($lead, $request->validated(), $request->user());

        return redirect()->route('leads.show', $lead)->with('success', 'Lead updated.');
    }

    public function destroy(Lead $lead): RedirectResponse
    {
        $this->authorize('delete', $lead);

        $this->leadService->delete($lead, request()->user());

        return redirect()->route('leads.index')->with('success', 'Lead deleted.');
    }

    public function duplicate(Lead $lead): RedirectResponse
    {
        $this->authorize('view', $lead);
        $this->authorize('create', Lead::class);

        $new = $lead->replicate();
        $new->name = $lead->name.' (copy)';
        $new->save();

        $this->leadService->logActivity(
            $new,
            'created',
            'Duplicated from lead #'.$lead->id,
            ['from_lead_id' => $lead->id],
            request()->user()
        );

        return redirect()->route('leads.show', $new)->with('success', 'Lead duplicated.');
    }
}
