<?php

namespace App\Http\Controllers;

use App\Models\Lead;
use App\Models\TicketAgent;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LeadController extends Controller
{
    /**
     * Display a listing of leads
     */
    public function index(Request $request)
    {
        $query = Lead::with(['device', 'assignedAgent', 'ticket'])
            ->where('device_id', session('device_id'));

        // Filter by status
        if ($request->has('status') && $request->status !== 'all') {
            $query->byStatus($request->status);
        }

        // Filter by source
        if ($request->has('source') && $request->source !== 'all') {
            $query->bySource($request->source);
        }

        // Filter by assigned agent
        if ($request->has('assigned_to') && $request->assigned_to !== 'all') {
            if ($request->assigned_to === 'unassigned') {
                $query->unassigned();
            } else {
                $query->where('assigned_to', $request->assigned_to);
            }
        }

        // Filter by lead score
        if ($request->has('min_score')) {
            $query->where('lead_score', '>=', $request->min_score);
        }

        // Search
        if ($request->has('search') && $request->search) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('customer_phone', 'like', "%{$search}%")
                  ->orWhere('customer_name', 'like', "%{$search}%")
                  ->orWhere('customer_email', 'like', "%{$search}%");
            });
        }

        $leads = $query->orderBy('created_at', 'desc')->paginate(20);

        // Get statistics
        $statistics = $this->getStatistics();

        return view('support.leads.index', compact('leads', 'statistics'));
    }

    /**
     * Show the form for creating a new lead
     */
    public function create()
    {
        return view('support.leads.create');
    }

    /**
     * Store a newly created lead
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            'customer_phone' => 'required|string',
            'customer_name' => 'nullable|string',
            'customer_email' => 'nullable|email',
            'source' => 'required|string',
            'lead_score' => 'nullable|integer|min:0|max:100',
            'notes' => 'nullable|string',
            'custom_fields' => 'nullable|array',
        ]);

        $validated['device_id'] = session('device_id');
        $validated['status'] = 'new';
        $validated['lead_score'] = $validated['lead_score'] ?? 50;

        $lead = Lead::create($validated);

        // Add initial note if provided
        if ($request->notes) {
            $lead->addNote($request->notes);
        }

        return redirect()->route('support.leads.show', $lead->id)
            ->with('success', 'Lead created successfully.');
    }

    /**
     * Display the specified lead
     */
    public function show($id)
    {
        $lead = Lead::with(['device', 'assignedAgent', 'ticket'])
            ->where('device_id', session('device_id'))
            ->findOrFail($id);

        // Get available agents for assignment
        $availableAgents = TicketAgent::forDevice($lead->device_id)
            ->with('user')
            ->get();

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

    /**
     * Show the form for editing the specified lead
     */
    public function edit($id)
    {
        $lead = Lead::where('device_id', session('device_id'))->findOrFail($id);
        return view('support.leads.edit', compact('lead'));
    }

    /**
     * Update the specified lead
     */
    public function update(Request $request, $id)
    {
        $lead = Lead::where('device_id', session('device_id'))->findOrFail($id);

        $validated = $request->validate([
            'customer_name' => 'nullable|string|max:255',
            'customer_email' => 'nullable|email|max:255',
            'source' => 'required|string|max:50',
            'status' => 'required|in:new,contacted,qualified,proposal,negotiation,converted,lost',
            'custom_fields' => 'nullable|array',
        ]);

        $lead->update($validated);

        if ($request->has('note') && $request->note) {
            $lead->addNote(htmlspecialchars($request->note, ENT_QUOTES, 'UTF-8'));
        }

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

    /**
     * Remove the specified lead
     */
    public function destroy($id)
    {
        $lead = Lead::where('device_id', session('device_id'))->findOrFail($id);
        $lead->delete();

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

    /**
     * Qualify a lead
     */
    public function qualify($id)
    {
        $lead = Lead::where('device_id', session('device_id'))->findOrFail($id);
        $lead->qualify();

        return back()->with('success', 'Lead qualified successfully.');
    }

    /**
     * Convert a lead
     */
    public function convert(Request $request, $id)
    {
        $request->validate([
            'conversion_note' => 'nullable|string|max:1000',
        ]);

        $lead = Lead::where('device_id', session('device_id'))->findOrFail($id);
        $lead->convert();

        if ($request->conversion_note) {
            $lead->addNote('Conversion note: ' . htmlspecialchars($request->conversion_note, ENT_QUOTES, 'UTF-8'));
        }

        return back()->with('success', 'Lead converted successfully.');
    }

    /**
     * Mark lead as lost
     */
    public function markAsLost(Request $request, $id)
    {
        $request->validate([
            'reason' => 'nullable|string|max:500',
        ]);

        $lead = Lead::where('device_id', session('device_id'))->findOrFail($id);
        $lead->markAsLost($request->reason ? htmlspecialchars($request->reason, ENT_QUOTES, 'UTF-8') : null);

        return back()->with('success', 'Lead marked as lost.');
    }

    /**
     * Assign lead to an agent
     */
    public function assignToAgent(Request $request, $id)
    {
        $request->validate([
            'agent_id' => 'required|exists:users,id',
        ]);

        $lead = Lead::where('device_id', session('device_id'))->findOrFail($id);
        
        // Verify agent belongs to same device
        $agent = TicketAgent::where('user_id', $request->agent_id)
            ->where('device_id', session('device_id'))
            ->firstOrFail();
        
        $lead->assignToAgent($request->agent_id);

        return back()->with('success', 'Lead assigned successfully.');
    }

    /**
     * Update lead score
     */
    public function updateScore(Request $request, $id)
    {
        $request->validate([
            'score_change' => 'required|integer|min:-100|max:100',
        ]);

        $lead = Lead::where('device_id', session('device_id'))->findOrFail($id);
        $lead->updateScore($request->score_change);

        return back()->with('success', 'Lead score updated successfully.');
    }

    /**
     * Add note to lead
     */
    public function addNote(Request $request, $id)
    {
        $request->validate([
            'note' => 'required|string|max:2000',
        ]);

        $lead = Lead::where('device_id', session('device_id'))->findOrFail($id);
        $lead->addNote(htmlspecialchars($request->note, ENT_QUOTES, 'UTF-8'), Auth::id());
        $lead->updateContactDate();

        return back()->with('success', 'Note added successfully.');
    }

    /**
     * Get lead statistics
     */
    private function getStatistics()
    {
        $deviceId = session('device_id');

        return [
            'total' => Lead::where('device_id', $deviceId)->count(),
            'new' => Lead::where('device_id', $deviceId)->new()->count(),
            'qualified' => Lead::where('device_id', $deviceId)->qualified()->count(),
            'converted' => Lead::where('device_id', $deviceId)->converted()->count(),
            'lost' => Lead::where('device_id', $deviceId)->lost()->count(),
            'high_score' => Lead::where('device_id', $deviceId)->highScore(70)->count(),
            'unassigned' => Lead::where('device_id', $deviceId)->unassigned()->count(),
        ];
    }
}
