<?php

declare(strict_types=1);

namespace App\Services;

use App\Models\Product;
use App\Models\LeadProduct;

class ProductService
{
    private Product $productModel;
    private LeadProduct $leadProductModel;

    public function __construct()
    {
        $this->productModel = new Product();
        $this->leadProductModel = new LeadProduct();
    }

    public function getProducts(array $filters = [], int $page = 1, int $perPage = 50): array
    {
        return $this->productModel->findWithPagination($page, $perPage, $filters);
    }

    public function getProduct(int $id): array
    {
        $product = $this->productModel->findById($id);
        if (!$product) {
            throw new \RuntimeException('Producto no encontrado', 404);
        }
        return $product;
    }

    public function createProduct(array $data): array
    {
        $category = null;
        if (!empty($data['category'])) {
            $category = is_array($data['category']) ? json_encode($data['category'], JSON_UNESCAPED_UNICODE) : $data['category'];
        }
        $species = null;
        if (!empty($data['species'])) {
            $species = is_array($data['species']) ? json_encode($data['species'], JSON_UNESCAPED_UNICODE) : $data['species'];
        }

        $id = $this->productModel->create([
            'name' => $data['name'],
            'description' => $data['description'] ?? null,
            'category' => $category,
            'species' => $species,
        ]);

        return $this->getProduct($id);
    }

    public function updateProduct(int $id, array $data): array
    {
        $product = $this->productModel->findById($id);
        if (!$product) {
            throw new \RuntimeException('Producto no encontrado', 404);
        }

        $updateData = [];
        foreach (['name', 'description'] as $field) {
            if (array_key_exists($field, $data)) {
                $updateData[$field] = $data[$field];
            }
        }

        if (array_key_exists('category', $data)) {
            $updateData['category'] = is_array($data['category']) ? json_encode($data['category'], JSON_UNESCAPED_UNICODE) : $data['category'];
        }

        if (array_key_exists('species', $data)) {
            $updateData['species'] = is_array($data['species']) ? json_encode($data['species'], JSON_UNESCAPED_UNICODE) : $data['species'];
        }

        if (!empty($updateData)) {
            $this->productModel->update($id, $updateData);
        }

        return $this->getProduct($id);
    }

    public function deleteProduct(int $id): void
    {
        $product = $this->productModel->findById($id);
        if (!$product) {
            throw new \RuntimeException('Producto no encontrado', 404);
        }

        $this->productModel->delete($id);
    }

    public function toggleStatus(int $id): array
    {
        $product = $this->productModel->findById($id);
        if (!$product) {
            throw new \RuntimeException('Producto no encontrado', 404);
        }

        $newStatus = $product['status'] === 'active' ? 'inactive' : 'active';
        $this->productModel->update($id, ['status' => $newStatus]);

        return $this->getProduct($id);
    }

    public function attachToLead(int $leadId, int $productId): array
    {
        $this->leadProductModel->attach($leadId, $productId);
        return $this->leadProductModel->getByLeadId($leadId);
    }

    public function detachFromLead(int $leadId, int $productId): array
    {
        $this->leadProductModel->detach($leadId, $productId);
        return $this->leadProductModel->getByLeadId($leadId);
    }

    public function getLeadProducts(int $leadId): array
    {
        return $this->leadProductModel->getByLeadId($leadId);
    }
}
