<?php

namespace App\Service\Vendor;

use App\Http\Resources\ServiceItemResource;
use App\Models\ServiceItem;
use App\Models\ServiceCategory;
use App\Models\VendorService;
use App\Models\FeatureType;
use App\Models\FeatureOption;
use App\Traits\JsonResponseTrait;
use App\Traits\PaginationResponseTrait;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Models\User;

class ServiceItemService
{
    use JsonResponseTrait, PaginationResponseTrait;

    /**
     * Get all service items available for vendor customization
     */
    public function getAvailableServiceItems(User $authUser, array $filters = [])
    {
        $query = ServiceItem::with([
            'serviceCategory',
            'serviceItemFeatures.featureType',
            'serviceItemFeatureOptions.featureOption'
        ])->where('status', true); // Only active service items

        // Search functionality
        if (!empty($filters['search'])) {
            $searchTerm = $filters['search'];
            $query->where(function ($q) use ($searchTerm) {
                $q->where('name', 'LIKE', "%{$searchTerm}%")
                    ->orWhere('description', 'LIKE', "%{$searchTerm}%")
                    ->orWhere('slug', 'LIKE', "%{$searchTerm}%")
                    ->orWhereHas('serviceCategory', function ($categoryQuery) use ($searchTerm) {
                        $categoryQuery->where('name', 'LIKE', "%{$searchTerm}%");
                    });
            });
        }

        // Filter by category
        if (!empty($filters['category_id'])) {
            $query->where('service_category_id', $filters['category_id']);
        }

        // Filter by vendor's existing services
        if (!empty($filters['vendor_services_only'])) {
            $vendorServiceIds = VendorService::where('vendor_id', $authUser->id)
                ->pluck('service_item_id')
                ->toArray();
            $query->whereIn('id', $vendorServiceIds);
        }

        // Sorting functionality
        $sortBy = $filters['sort_by'] ?? 'created_at';
        $sortOrder = $filters['sort_order'] ?? 'desc';

        // Validate sort column to prevent SQL injection
        $allowedSortColumns = ['name', 'status', 'created_at', 'updated_at'];
        if (!in_array($sortBy, $allowedSortColumns)) {
            $sortBy = 'created_at';
        }

        // Validate sort order
        $sortOrder = in_array(strtolower($sortOrder), ['asc', 'desc']) ? $sortOrder : 'desc';

        $query->orderBy($sortBy, $sortOrder);

        // Use the pagination trait for consistent response format
        return $this->paginatedResponse(
            ServiceItemResource::class,
            $query,
            [],
            'Service items retrieved successfully'
        );
    }

    /**
     * Get service item by ID (vendor can only view active items)
     */
    public function getServiceItemById(User $authUser, string $serviceItemId)
    {
        $serviceItem = ServiceItem::with([
            'serviceCategory',
            'serviceItemFeatures.featureType',
            'serviceItemFeatureOptions.featureOption'
        ])
            ->where('id', $serviceItemId)
            ->where('status', true) // Only active items
            ->first();

        if (!$serviceItem) {
            return $this->errorResponse(statusCode: 404, message: "Service item not found");
        }

        return $this->successDataResponse(
            data: $serviceItem,
            message: "Service item retrieved successfully"
        );
    }

    /**
     * Create vendor service based on service item
     */
    public function createVendorService(User $authUser, array $data)
    {
        DB::beginTransaction();

        try {
            // Validate service item exists and is active
            $serviceItem = ServiceItem::where('id', $data['service_item_id'])
                ->where('status', true)
                ->first();

            if (!$serviceItem) {
                return $this->errorResponse(statusCode: 404, message: "Service item not found or inactive");
            }

            // Check if vendor already has this service
            $existingService = VendorService::where('vendor_id', $authUser->id)
                ->where('service_item_id', $data['service_item_id'])
                ->first();

            if ($existingService) {
                return $this->errorResponse(statusCode: 400, message: "You already offer this service");
            }

            $vendorService = VendorService::create([
                'vendor_id' => $authUser->id,
                'service_item_id' => $data['service_item_id'],
                'price' => $data['price'],
                'description' => $data['description'] ?? $serviceItem->description,
                'status' => $data['status'] ?? true,
                'features' => $data['features'] ?? [],
            ]);

            DB::commit();

            return $this->successDataResponse(
                data: $vendorService->load(['serviceItem', 'vendor']),
                message: "Vendor service created successfully"
            );
        } catch (\Exception $e) {
            DB::rollBack();

            Log::error('Vendor service creation failed: ' . $e->getMessage(), [
                'vendor_id' => $authUser->id,
                'data' => $data,
                'exception' => $e,
            ]);

            return $this->errorResponse(statusCode: 500, message: "An error occurred during vendor service creation.");
        }
    }

    /**
     * Update vendor service
     */
    public function updateVendorService(User $authUser, string $vendorServiceId, array $data)
    {
        $vendorService = VendorService::where('id', $vendorServiceId)
            ->where('vendor_id', $authUser->id)
            ->first();

        if (!$vendorService) {
            return $this->errorResponse(statusCode: 404, message: "Vendor service not found");
        }

        DB::beginTransaction();

        try {
            $vendorService->update([
                'price' => $data['price'] ?? $vendorService->price,
                'description' => $data['description'] ?? $vendorService->description,
                'status' => $data['status'] ?? $vendorService->status,
                'features' => $data['features'] ?? $vendorService->features,
            ]);

            DB::commit();

            return $this->successDataResponse(
                data: $vendorService->fresh()->load(['serviceItem', 'vendor']),
                message: "Vendor service updated successfully"
            );
        } catch (\Exception $e) {
            DB::rollBack();

            Log::error('Vendor service update failed: ' . $e->getMessage(), [
                'vendor_service_id' => $vendorServiceId,
                'vendor_id' => $authUser->id,
                'data' => $data,
                'exception' => $e,
            ]);

            return $this->errorResponse(statusCode: 500, message: "An error occurred during vendor service update.");
        }
    }

    /**
     * Delete vendor service
     */
    public function deleteVendorService(User $authUser, string $vendorServiceId)
    {
        $vendorService = VendorService::where('id', $vendorServiceId)
            ->where('vendor_id', $authUser->id)
            ->first();

        if (!$vendorService) {
            return $this->errorResponse(statusCode: 404, message: "Vendor service not found");
        }

        DB::beginTransaction();

        try {
            $vendorService->delete();

            DB::commit();

            return $this->successResponse(message: "Vendor service deleted successfully");
        } catch (\Exception $e) {
            DB::rollBack();

            Log::error('Vendor service deletion failed: ' . $e->getMessage(), [
                'vendor_service_id' => $vendorServiceId,
                'vendor_id' => $authUser->id,
                'exception' => $e,
            ]);

            return $this->errorResponse(statusCode: 500, message: "An error occurred during vendor service deletion.");
        }
    }

    /**
     * Toggle vendor service status
     */
    public function toggleVendorServiceStatus(User $authUser, string $vendorServiceId)
    {
        $vendorService = VendorService::where('id', $vendorServiceId)
            ->where('vendor_id', $authUser->id)
            ->first();

        if (!$vendorService) {
            return $this->errorResponse(statusCode: 404, message: "Vendor service not found");
        }

        try {
            $vendorService->update([
                'status' => !$vendorService->status,
            ]);

            return $this->successDataResponse(
                data: $vendorService->fresh(),
                message: "Vendor service status updated successfully"
            );
        } catch (\Exception $e) {
            Log::error('Vendor service status toggle failed: ' . $e->getMessage(), [
                'vendor_service_id' => $vendorServiceId,
                'vendor_id' => $authUser->id,
                'exception' => $e,
            ]);

            return $this->errorResponse(statusCode: 500, message: "An error occurred during vendor service status update.");
        }
    }

    /**
     * Get vendor's services
     */
    public function getVendorServices(User $authUser, array $filters = [])
    {
        $query = VendorService::with(['serviceItem', 'vendor'])
            ->where('vendor_id', $authUser->id);

        // Search functionality
        if (!empty($filters['search'])) {
            $searchTerm = $filters['search'];
            $query->where(function ($q) use ($searchTerm) {
                $q->where('description', 'LIKE', "%{$searchTerm}%")
                    ->orWhereHas('serviceItem', function ($serviceQuery) use ($searchTerm) {
                        $serviceQuery->where('name', 'LIKE', "%{$searchTerm}%");
                    });
            });
        }

        // Filter by status
        if (isset($filters['status'])) {
            $query->where('status', (bool) $filters['status']);
        }

        // Filter by service item
        if (!empty($filters['service_item_id'])) {
            $query->where('service_item_id', $filters['service_item_id']);
        }

        // Sorting functionality
        $sortBy = $filters['sort_by'] ?? 'created_at';
        $sortOrder = $filters['sort_order'] ?? 'desc';

        // Validate sort column to prevent SQL injection
        $allowedSortColumns = ['price', 'status', 'created_at', 'updated_at'];
        if (!in_array($sortBy, $allowedSortColumns)) {
            $sortBy = 'created_at';
        }

        // Validate sort order
        $sortOrder = in_array(strtolower($sortOrder), ['asc', 'desc']) ? $sortOrder : 'desc';

        $query->orderBy($sortBy, $sortOrder);

        // Use the pagination trait for consistent response format
        return $this->paginatedResponse(
            ServiceItemResource::class,
            $query,
            [],
            'Vendor services retrieved successfully'
        );
    }
}
