<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Models\Policy;
use App\Traits\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use OpenApi\Attributes as OA;

class PolicyController extends Controller
{
    use ApiResponse;

    /**
     * Get quote for a policy
     */
    #[OA\Post(
        path: '/api/v1/policies/quote',
        summary: 'Get policy quote',
        description: 'Get an insurance quote for a specific vehicle and product type',
        tags: ['Policies'],
        security: [['sanctum' => []]],
        requestBody: new OA\RequestBody(
            required: true,
            content: new OA\JsonContent(
                required: ['product_type', 'vehicle_id'],
                properties: [
                    new OA\Property(property: 'product_type', type: 'string', enum: ['PAYG', '30D', 'ANN'], example: 'PAYG'),
                    new OA\Property(property: 'vehicle_id', type: 'integer', example: 1),
                ]
            )
        ),
        responses: [
            new OA\Response(
                response: 200,
                description: 'Quote generated successfully',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: true),
                        new OA\Property(property: 'data', type: 'object', properties: [
                            new OA\Property(property: 'product_type', type: 'string', example: 'PAYG'),
                            new OA\Property(property: 'vehicle_id', type: 'integer', example: 1),
                            new OA\Property(property: 'premium_amount', type: 'number', example: 1.20),
                        ]),
                        new OA\Property(property: 'message', type: 'string', example: 'Quote generated successfully'),
                    ]
                )
            ),
            new OA\Response(
                response: 422,
                description: 'Validation error',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: false),
                        new OA\Property(property: 'message', type: 'string', example: 'Validation failed'),
                        new OA\Property(property: 'errors', type: 'object'),
                    ]
                )
            ),
        ]
    )]
    public function getQuote(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'product_type' => 'required|in:PAYG,30D,ANN',
            'vehicle_id' => 'required|exists:vehicles,id',
        ]);

        if ($validator->fails()) {
            return $this->validationErrorResponse($validator->errors());
        }

        // TODO: Calculate actual quote based on vehicle and product type
        // For now, return placeholder quote
        $quote = [
            'product_type' => $request->product_type,
            'vehicle_id' => $request->vehicle_id,
            'premium_amount' => match($request->product_type) {
                'PAYG' => 1.20, // Per hour
                '30D' => 150.00,
                'ANN' => 1200.00,
                default => 0,
            },
            'coverage_details' => [],
        ];

        return $this->successResponse($quote, 'Quote generated successfully');
    }

    /**
     * Display a listing of policies
     */
    #[OA\Get(
        path: '/api/v1/policies',
        summary: 'List all policies',
        description: 'Retrieve all policies belonging to the authenticated user',
        tags: ['Policies'],
        security: [['sanctum' => []]],
        responses: [
            new OA\Response(
                response: 200,
                description: 'Policies retrieved successfully',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: true),
                        new OA\Property(property: 'data', type: 'array', items: new OA\Items(type: 'object')),
                        new OA\Property(property: 'message', type: 'string', example: 'Policies retrieved successfully'),
                    ]
                )
            ),
        ]
    )]
    public function index(Request $request): JsonResponse
    {
        $policies = $request->user()->policies()->with(['vehicle'])->get();
        return $this->successResponse($policies, 'Policies retrieved successfully');
    }

    /**
     * Store a newly created policy
     */
    #[OA\Post(
        path: '/api/v1/policies',
        summary: 'Create a new policy',
        description: 'Create a new insurance policy. KYC verification is required.',
        tags: ['Policies'],
        security: [['sanctum' => []]],
        requestBody: new OA\RequestBody(
            required: true,
            content: new OA\JsonContent(
                required: ['product_type', 'vehicle_id'],
                properties: [
                    new OA\Property(property: 'product_type', type: 'string', enum: ['PAYG', '30D', 'ANN'], example: 'PAYG'),
                    new OA\Property(property: 'vehicle_id', type: 'integer', example: 1),
                    new OA\Property(property: 'premium_amount', type: 'number', nullable: true, example: 1.20),
                ]
            )
        ),
        responses: [
            new OA\Response(
                response: 201,
                description: 'Policy created successfully',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: true),
                        new OA\Property(property: 'data', type: 'object'),
                        new OA\Property(property: 'message', type: 'string', example: 'Policy created successfully'),
                    ]
                )
            ),
            new OA\Response(
                response: 403,
                description: 'KYC verification required',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: false),
                        new OA\Property(property: 'message', type: 'string', example: 'KYC verification required before creating a policy'),
                    ]
                )
            ),
            new OA\Response(
                response: 422,
                description: 'Validation error',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: false),
                        new OA\Property(property: 'message', type: 'string', example: 'Validation failed'),
                        new OA\Property(property: 'errors', type: 'object'),
                    ]
                )
            ),
        ]
    )]
    public function store(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'product_type' => 'required|in:PAYG,30D,ANN',
            'vehicle_id' => 'required|exists:vehicles,id',
            'premium_amount' => 'nullable|numeric|min:0',
        ]);

        if ($validator->fails()) {
            return $this->validationErrorResponse($validator->errors());
        }

        $user = $request->user();

        // Check KYC status
        if ($user->kyc_status !== 'verified') {
            return $this->errorResponse('KYC verification required before creating a policy', null, 403);
        }

        $policy = Policy::create([
            'user_id' => $user->id,
            'vehicle_id' => $request->vehicle_id,
            'product_type' => $request->product_type,
            'status' => 'draft',
            'premium_amount' => $request->premium_amount ?? 0,
            'policy_number' => 'POL-' . strtoupper(uniqid()),
        ]);

        return $this->successResponse($policy, 'Policy created successfully', 201);
    }

    /**
     * Display the specified policy
     */
    #[OA\Get(
        path: '/api/v1/policies/{id}',
        summary: 'Get policy details',
        description: 'Retrieve details of a specific policy',
        tags: ['Policies'],
        security: [['sanctum' => []]],
        parameters: [
            new OA\Parameter(name: 'id', in: 'path', required: true, schema: new OA\Schema(type: 'integer'), example: 1),
        ],
        responses: [
            new OA\Response(
                response: 200,
                description: 'Policy retrieved successfully',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: true),
                        new OA\Property(property: 'data', type: 'object'),
                        new OA\Property(property: 'message', type: 'string', example: 'Policy retrieved successfully'),
                    ]
                )
            ),
            new OA\Response(
                response: 404,
                description: 'Policy not found',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: false),
                        new OA\Property(property: 'message', type: 'string', example: 'Policy not found'),
                    ]
                )
            ),
        ]
    )]
    public function show(Request $request, string $id): JsonResponse
    {
        $policy = $request->user()->policies()->with(['vehicle'])->find($id);
        
        if (!$policy) {
            return $this->notFoundResponse('Policy not found');
        }

        return $this->successResponse($policy, 'Policy retrieved successfully');
    }

    /**
     * Update the specified policy
     */
    #[OA\Put(
        path: '/api/v1/policies/{id}',
        summary: 'Update policy',
        description: 'Update status of a specific policy',
        tags: ['Policies'],
        security: [['sanctum' => []]],
        parameters: [
            new OA\Parameter(name: 'id', in: 'path', required: true, schema: new OA\Schema(type: 'integer'), example: 1),
        ],
        requestBody: new OA\RequestBody(
            required: true,
            content: new OA\JsonContent(
                properties: [
                    new OA\Property(property: 'status', type: 'string', nullable: true, enum: ['draft', 'active', 'inactive', 'expired', 'cancelled']),
                ]
            )
        ),
        responses: [
            new OA\Response(
                response: 200,
                description: 'Policy updated successfully',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: true),
                        new OA\Property(property: 'data', type: 'object'),
                        new OA\Property(property: 'message', type: 'string', example: 'Policy updated successfully'),
                    ]
                )
            ),
            new OA\Response(
                response: 404,
                description: 'Policy not found',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: false),
                        new OA\Property(property: 'message', type: 'string', example: 'Policy not found'),
                    ]
                )
            ),
        ]
    )]
    public function update(Request $request, string $id): JsonResponse
    {
        $policy = $request->user()->policies()->find($id);
        
        if (!$policy) {
            return $this->notFoundResponse('Policy not found');
        }

        $validator = Validator::make($request->all(), [
            'status' => 'sometimes|in:draft,active,inactive,expired,cancelled',
        ]);

        if ($validator->fails()) {
            return $this->validationErrorResponse($validator->errors());
        }

        $policy->update($request->only(['status']));

        return $this->successResponse($policy, 'Policy updated successfully');
    }

    /**
     * Remove the specified policy
     */
    #[OA\Delete(
        path: '/api/v1/policies/{id}',
        summary: 'Delete policy',
        description: 'Delete a specific policy',
        tags: ['Policies'],
        security: [['sanctum' => []]],
        parameters: [
            new OA\Parameter(name: 'id', in: 'path', required: true, schema: new OA\Schema(type: 'integer'), example: 1),
        ],
        responses: [
            new OA\Response(
                response: 200,
                description: 'Policy deleted successfully',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: true),
                        new OA\Property(property: 'message', type: 'string', example: 'Policy deleted successfully'),
                    ]
                )
            ),
            new OA\Response(
                response: 404,
                description: 'Policy not found',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: false),
                        new OA\Property(property: 'message', type: 'string', example: 'Policy not found'),
                    ]
                )
            ),
        ]
    )]
    public function destroy(Request $request, string $id): JsonResponse
    {
        $policy = $request->user()->policies()->find($id);
        
        if (!$policy) {
            return $this->notFoundResponse('Policy not found');
        }

        $policy->delete();

        return $this->successResponse(null, 'Policy deleted successfully');
    }

    /**
     * Activate policy
     */
    #[OA\Post(
        path: '/api/v1/policies/{id}/activate',
        summary: 'Activate policy',
        description: 'Activate a draft or inactive policy',
        tags: ['Policies'],
        security: [['sanctum' => []]],
        parameters: [
            new OA\Parameter(name: 'id', in: 'path', required: true, schema: new OA\Schema(type: 'integer'), example: 1),
        ],
        responses: [
            new OA\Response(
                response: 200,
                description: 'Policy activated successfully',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: true),
                        new OA\Property(property: 'data', type: 'object'),
                        new OA\Property(property: 'message', type: 'string', example: 'Policy activated successfully'),
                    ]
                )
            ),
            new OA\Response(
                response: 400,
                description: 'Policy already active',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: false),
                        new OA\Property(property: 'message', type: 'string', example: 'Policy is already active'),
                    ]
                )
            ),
            new OA\Response(
                response: 404,
                description: 'Policy not found',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: false),
                        new OA\Property(property: 'message', type: 'string', example: 'Policy not found'),
                    ]
                )
            ),
        ]
    )]
    public function activate(Request $request, string $id): JsonResponse
    {
        $policy = $request->user()->policies()->find($id);
        
        if (!$policy) {
            return $this->notFoundResponse('Policy not found');
        }

        if ($policy->status === 'active') {
            return $this->errorResponse('Policy is already active');
        }

        $policy->update([
            'status' => 'active',
            'start_date' => now(),
        ]);

        return $this->successResponse($policy, 'Policy activated successfully');
    }

    /**
     * Deactivate policy
     */
    #[OA\Post(
        path: '/api/v1/policies/{id}/deactivate',
        summary: 'Deactivate policy',
        description: 'Deactivate an active policy',
        tags: ['Policies'],
        security: [['sanctum' => []]],
        parameters: [
            new OA\Parameter(name: 'id', in: 'path', required: true, schema: new OA\Schema(type: 'integer'), example: 1),
        ],
        responses: [
            new OA\Response(
                response: 200,
                description: 'Policy deactivated successfully',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: true),
                        new OA\Property(property: 'data', type: 'object'),
                        new OA\Property(property: 'message', type: 'string', example: 'Policy deactivated successfully'),
                    ]
                )
            ),
            new OA\Response(
                response: 404,
                description: 'Policy not found',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'boolean', example: false),
                        new OA\Property(property: 'message', type: 'string', example: 'Policy not found'),
                    ]
                )
            ),
        ]
    )]
    public function deactivate(Request $request, string $id): JsonResponse
    {
        $policy = $request->user()->policies()->find($id);
        
        if (!$policy) {
            return $this->notFoundResponse('Policy not found');
        }

        $policy->update([
            'status' => 'inactive',
        ]);

        return $this->successResponse($policy, 'Policy deactivated successfully');
    }
}
