<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Resources\Api\TicketResource;
use App\Http\Resources\Api\TicketDetailResource;
use App\Models\Ticket;
use App\Models\TicketStatus;
use App\Services\TicketService;
use Illuminate\Http\Request;

class TicketApiController extends Controller
{
    public function __construct(private TicketService $service) {}

    public function index(Request $request) {
        $user  = $request->user();
        $query = Ticket::with(['status','priority','category','type','requester','assignee','department'])->withCount('comments');
        if ($user->hasRole('usuario'))     $query->where('requester_id', $user->id);
        elseif ($user->hasRole('agente'))  $query->where(fn($q) => $q->where('assignee_id',$user->id)->orWhereNull('assignee_id'));
        $query
            ->when($request->status,   fn($q) => $q->where('status_id',   $request->status))
            ->when($request->priority, fn($q) => $q->where('priority_id', $request->priority))
            ->when($request->category, fn($q) => $q->where('category_id', $request->category))
            ->when($request->assignee, fn($q) => $q->where('assignee_id', $request->assignee))
            ->when($request->q, fn($q) => $q->where(fn($s) => $s->where('title','like','%'.$request->q.'%')->orWhere('number','like','%'.$request->q.'%')))
            ->when($request->from, fn($q) => $q->whereDate('created_at','>=',$request->from))
            ->when($request->to,   fn($q) => $q->whereDate('created_at','<=',$request->to));
        $sort = in_array($request->sort,['created_at','updated_at','priority_id','status_id']) ? $request->sort : 'created_at';
        $query->orderBy($sort, $request->direction==='asc'?'asc':'desc');
        return TicketResource::collection($query->paginate(min((int)($request->per_page??20),100)))->additional(['success'=>true]);
    }

    public function store(Request $request) {
        $data = $request->validate(['title'=>'required|string|max:255','description'=>'required|string','priority_id'=>'required|exists:ticket_priorities,id','category_id'=>'nullable|exists:ticket_categories,id','type_id'=>'nullable|exists:ticket_types,id','asset_id'=>'nullable|exists:assets,id']);
        $ticket = $this->service->create($data, $request->user()->id);
        $ticket->load(['status','priority','category','type','requester','assignee','comments','history']);
        return response()->json(['success'=>true,'message'=>'Ticket creado.','data'=>new TicketDetailResource($ticket)], 201);
    }

    public function show(Request $request, Ticket $ticket) {
        $user = $request->user();
        if ($user->hasRole('usuario') && $ticket->requester_id !== $user->id)
            return response()->json(['success'=>false,'message'=>'No autorizado.'], 403);
        $ticket->load(['status','priority','category','type','requester','assignee','department','asset','comments.user','history.user']);
        return response()->json(['success'=>true,'data'=>new TicketDetailResource($ticket)]);
    }

    public function update(Request $request, Ticket $ticket) {
        abort_unless($request->user()->hasAnyRole(['agente','jefe_soporte','admin','superadmin']), 403);
        $data = $request->validate(['status_id'=>'sometimes|exists:ticket_statuses,id','priority_id'=>'sometimes|exists:ticket_priorities,id','assignee_id'=>'sometimes|nullable|exists:users,id','category_id'=>'sometimes|nullable|exists:ticket_categories,id']);
        if (isset($data['status_id']) && $data['status_id'] != $ticket->status_id) {
            $this->service->changeStatus($ticket, $data['status_id'], $request->comment);
            unset($data['status_id']);
        }
        if (array_key_exists('assignee_id', $data)) { $this->service->assign($ticket, $data['assignee_id']); unset($data['assignee_id']); }
        if (!empty($data)) $ticket->update($data);
        return response()->json(['success'=>true,'message'=>'Ticket actualizado.','data'=>new TicketResource($ticket->fresh(['status','priority','category','assignee','requester']))]);
    }

    public function addComment(Request $request, Ticket $ticket) {
        $user = $request->user();
        if ($user->hasRole('usuario') && $ticket->requester_id !== $user->id)
            return response()->json(['success'=>false,'message'=>'No autorizado.'], 403);
        $data = $request->validate(['body'=>'required|string','is_internal'=>'boolean']);
        if ($user->hasRole('usuario')) $data['is_internal'] = false;
        $c = $ticket->comments()->create(['user_id'=>$user->id,'body'=>$data['body'],'is_internal'=>$data['is_internal']??false]);
        return response()->json(['success'=>true,'message'=>'Comentario agregado.','data'=>['id'=>$c->id,'body'=>$c->body,'is_internal'=>$c->is_internal,'user'=>['id'=>$user->id,'name'=>$user->name],'created_at'=>$c->created_at->toIso8601String()]], 201);
    }

    public function stats(Request $request) {
        abort_unless($request->user()->hasAnyRole(['agente','jefe_soporte','admin','superadmin']), 403);
        $statuses = TicketStatus::active()->withCount(['tickets'=>fn($q)=>$q->open()])->get();
        return response()->json(['success'=>true,'data'=>[
            'by_status'    => $statuses->map(fn($s) => ['id'=>$s->id,'name'=>$s->name,'color'=>$s->color,'count'=>$s->tickets_count]),
            'sla_breached' => Ticket::open()->where('sla_resolution_breached',true)->count(),
            'unassigned'   => Ticket::open()->whereNull('assignee_id')->count(),
            'total_open'   => Ticket::open()->count(),
        ]]);
    }
}
