<?php
namespace api\Controllers;

use api\ApiRouter;
use Domain\Attribute\AttributeRepository;
use Domain\Producer\ProducerRepository;
use Domain\ShopStatus\ShopStatusRepository;
use Domain\Transport\TransportRepository;
use Domain\PaymentMethod\PaymentMethodRepository;

class DictionariesApiController
{
    private $statusRepo;
    private $transportRepo;
    private $paymentRepo;
    private $attrRepo;
    private $producerRepo;

    public function __construct(
        ShopStatusRepository $statusRepo,
        TransportRepository $transportRepo,
        PaymentMethodRepository $paymentRepo,
        AttributeRepository $attrRepo,
        ProducerRepository $producerRepo
    ) {
        $this->statusRepo = $statusRepo;
        $this->transportRepo = $transportRepo;
        $this->paymentRepo = $paymentRepo;
        $this->attrRepo = $attrRepo;
        $this->producerRepo = $producerRepo;
    }

    public function statuses(): void
    {
        if (!ApiRouter::requireMethod('GET')) {
            return;
        }

        $statuses = $this->statusRepo->allStatuses();

        $result = [];
        foreach ($statuses as $id => $name) {
            $result[] = [
                'id' => (int)$id,
                'name' => (string)$name,
            ];
        }

        ApiRouter::sendSuccess($result);
    }

    public function transports(): void
    {
        if (!ApiRouter::requireMethod('GET')) {
            return;
        }

        $transports = $this->transportRepo->allActive();

        $result = [];
        foreach ($transports as $transport) {
            $result[] = [
                'id' => (int)($transport['id'] ?? 0),
                'name' => (string)($transport['name_visible'] ?? $transport['name'] ?? ''),
                'cost' => (float)($transport['cost'] ?? 0),
            ];
        }

        ApiRouter::sendSuccess($result);
    }

    public function payment_methods(): void
    {
        if (!ApiRouter::requireMethod('GET')) {
            return;
        }

        $methods = $this->paymentRepo->allActive();

        $result = [];
        foreach ($methods as $method) {
            $result[] = [
                'id' => (int)($method['id'] ?? 0),
                'name' => (string)($method['name'] ?? ''),
            ];
        }

        ApiRouter::sendSuccess($result);
    }

    public function attributes(): void
    {
        if (!ApiRouter::requireMethod('GET')) {
            return;
        }

        $attributes = $this->attrRepo->listForApi();

        ApiRouter::sendSuccess($attributes);
    }

    public function ensure_attribute(): void
    {
        if (!ApiRouter::requireMethod('POST')) {
            return;
        }

        $body = ApiRouter::getJsonBody();
        if (!is_array($body)) {
            ApiRouter::sendError('BAD_REQUEST', 'Missing or invalid JSON body', 400);
            return;
        }

        $name = trim((string) ($body['name'] ?? ''));
        if ($name === '') {
            ApiRouter::sendError('BAD_REQUEST', 'Missing name', 400);
            return;
        }

        $type = (int) ($body['type'] ?? 0);
        $lang = trim((string) ($body['lang'] ?? 'pl'));
        if ($lang === '') {
            $lang = 'pl';
        }

        $result = $this->attrRepo->ensureAttributeForApi($name, $type, $lang);
        if (!is_array($result) || (int) ($result['id'] ?? 0) <= 0) {
            ApiRouter::sendError('INTERNAL_ERROR', 'Failed to ensure attribute', 500);
            return;
        }

        ApiRouter::sendSuccess([
            'id' => (int) ($result['id'] ?? 0),
            'created' => !empty($result['created']),
        ]);
    }

    public function ensure_attribute_value(): void
    {
        if (!ApiRouter::requireMethod('POST')) {
            return;
        }

        $body = ApiRouter::getJsonBody();
        if (!is_array($body)) {
            ApiRouter::sendError('BAD_REQUEST', 'Missing or invalid JSON body', 400);
            return;
        }

        $attributeId = (int) ($body['attribute_id'] ?? 0);
        if ($attributeId <= 0) {
            ApiRouter::sendError('BAD_REQUEST', 'Missing or invalid attribute_id', 400);
            return;
        }

        $name = trim((string) ($body['name'] ?? ''));
        if ($name === '') {
            ApiRouter::sendError('BAD_REQUEST', 'Missing name', 400);
            return;
        }

        $lang = trim((string) ($body['lang'] ?? 'pl'));
        if ($lang === '') {
            $lang = 'pl';
        }

        $result = $this->attrRepo->ensureAttributeValueForApi($attributeId, $name, $lang);
        if (!is_array($result) || (int) ($result['id'] ?? 0) <= 0) {
            ApiRouter::sendError('INTERNAL_ERROR', 'Failed to ensure attribute value', 500);
            return;
        }

        ApiRouter::sendSuccess([
            'id' => (int) ($result['id'] ?? 0),
            'created' => !empty($result['created']),
        ]);
    }

    public function ensure_producer(): void
    {
        if (!ApiRouter::requireMethod('POST')) {
            return;
        }

        $body = ApiRouter::getJsonBody();
        if (!is_array($body)) {
            ApiRouter::sendError('BAD_REQUEST', 'Missing or invalid JSON body', 400);
            return;
        }

        $name = trim((string) ($body['name'] ?? ''));
        if ($name === '') {
            ApiRouter::sendError('BAD_REQUEST', 'Missing name', 400);
            return;
        }

        $result = $this->producerRepo->ensureProducerForApi($name);
        if ((int) ($result['id'] ?? 0) <= 0) {
            ApiRouter::sendError('INTERNAL_ERROR', 'Failed to ensure producer', 500);
            return;
        }

        ApiRouter::sendSuccess([
            'id'      => (int) ($result['id'] ?? 0),
            'created' => !empty($result['created']),
        ]);
    }
}
