<?php

namespace App\Http\Controllers;

use App\Http\Requests\{{modelName}}StoreRequest;
use App\Http\Requests\{{modelName}}UpdateRequest;
use App\Http\Resources\{{modelName}}Resource;
use App\Http\Resources\{{modelName}}Collection;
use App\Services\Interfaces\{{modelName}}ServiceInterface;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Exception;

class {{modelName}}Controller extends Controller
{
    protected ${{camelCaseModel}}Service;

    public function __construct({{modelName}}ServiceInterface ${{camelCaseModel}}Service)
    {
        $this->{{camelCaseModel}}Service = ${{camelCaseModel}}Service;
    }

    /**
     * Display a listing of the resource.
     */
    public function index(Request $request): JsonResponse
    {
        try {
            $withPagination = $request->has('page');
            $relations = array_filter(explode(',', $request->input('with', '')));
            
            ${{pluralCamelCase}} = $this->{{camelCaseModel}}Service->getAll{{modelName}}s($withPagination, $relations);
            
            if ($withPagination) {
                return response()->json(new {{modelName}}Collection(${{pluralCamelCase}}));
            }
            
            return response()->json([
                'data' => {{modelName}}Resource::collection(${{pluralCamelCase}})
            ]);
        } catch (Exception $e) {
            return response()->json([
                'message' => 'Error retrieving {{pluralCamelCase}}',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store({{modelName}}StoreRequest $request): JsonResponse
    {
        try {
            $data = $request->validated();
            
            // Handle polymorphic relationship
            if (isset($data['{{morphName}}_type']) && isset($data['{{morphName}}_id'])) {
                // Convert type string to fully qualified class name if needed
                $morphType = $data['{{morphName}}_type'];
                if (!str_contains($morphType, '\\')) {
                    $data['{{morphName}}_type'] = "App\\Models\\{$morphType}";
                }
            }
            
            ${{camelCaseModel}} = $this->{{camelCaseModel}}Service->create{{modelName}}($data);
            
            return response()->json([
                'message' => '{{modelName}} created successfully',
                'data' => new {{modelName}}Resource(${{camelCaseModel}})
            ], 201);
        } catch (Exception $e) {
            return response()->json([
                'message' => 'Error creating {{camelCaseModel}}',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Display the specified resource.
     */
    public function show(Request $request, int $id): JsonResponse
    {
        try {
            $relations = array_filter(explode(',', $request->input('with', '')));
            ${{camelCaseModel}} = $this->{{camelCaseModel}}Service->get{{modelName}}ById($id, $relations);
            
            if (!${{camelCaseModel}}) {
                return response()->json([
                    'message' => '{{modelName}} not found'
                ], 404);
            }
            
            return response()->json([
                'data' => new {{modelName}}Resource(${{camelCaseModel}})
            ]);
        } catch (Exception $e) {
            return response()->json([
                'message' => 'Error retrieving {{camelCaseModel}}',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Update the specified resource in storage.
     */
    public function update({{modelName}}UpdateRequest $request, int $id): JsonResponse
    {
        try {
            $data = $request->validated();
            
            // Handle polymorphic relationship
            if (isset($data['{{morphName}}_type']) && isset($data['{{morphName}}_id'])) {
                // Convert type string to fully qualified class name if needed
                $morphType = $data['{{morphName}}_type'];
                if (!str_contains($morphType, '\\')) {
                    $data['{{morphName}}_type'] = "App\\Models\\{$morphType}";
                }
            }
            
            ${{camelCaseModel}} = $this->{{camelCaseModel}}Service->update{{modelName}}($id, $data);
            
            if (!${{camelCaseModel}}) {
                return response()->json([
                    'message' => '{{modelName}} not found'
                ], 404);
            }
            
            return response()->json([
                'message' => '{{modelName}} updated successfully',
                'data' => new {{modelName}}Resource(${{camelCaseModel}})
            ]);
        } catch (Exception $e) {
            return response()->json([
                'message' => 'Error updating {{camelCaseModel}}',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(int $id): JsonResponse
    {
        try {
            $result = $this->{{camelCaseModel}}Service->delete{{modelName}}($id);
            
            if (!$result) {
                return response()->json([
                    'message' => '{{modelName}} not found'
                ], 404);
            }
            
            return response()->json([
                'message' => '{{modelName}} deleted successfully'
            ]);
        } catch (Exception $e) {
            return response()->json([
                'message' => 'Error deleting {{camelCaseModel}}',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Search for {{pluralCamelCase}} based on query parameters.
     */
    public function search(Request $request): JsonResponse
    {
        try {
            $query = $request->input('q');
            $fields = $request->input('fields') ? explode(',', $request->input('fields')) : [];
            
            ${{pluralCamelCase}} = $this->{{camelCaseModel}}Service->search{{modelName}}s($query, $fields);
            
            return response()->json([
                'data' => {{modelName}}Resource::collection(${{pluralCamelCase}})
            ]);
        } catch (Exception $e) {
            return response()->json([
                'message' => 'Error searching {{pluralCamelCase}}',
                'error' => $e->getMessage()
            ], 500);
        }
    }
}