<?php

namespace App\Services\Facturapi;

use App\Helpers\Environment\FacturapiHelper;
use App\Models\Environment\Business;
use Facturapi\Exceptions\Facturapi_Exception;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Log;

class FacturapiOrganizationService extends FacturapiResourceService
{
  //* Constructor
    public function __construct() {
        $this->client = new FacturapiWrapper(FacturapiHelper::getUserKey());
    }

  //* CRUD Functions
    /**
     * Crear Organización
     */
    public function create(array $data): array
    {
        try {
            $payload = $this->parsePayload($data);

            $result = $this->client->Organizations->create($payload);
            return $this->toArray($result);
        } catch (Facturapi_Exception $e) {
            $this->handleFacturapiException($e);
        }
    }

    /**
     * Obtener Organización por ID de Facturapi
     */
    public function retrieve(string $facturapiId): array
    {
        $result = $this->client->Organizations->retrieve($facturapiId);
        return $this->toArray($result);
    }

    /**
     * Actualizar los datos legales de una Organización por ID de Facturapi
     */
    public function updateLegal(string $facturapiId, array $data): array
    {
        try {
            $payload = $this->parsePayload($data);

            $result = $this->client->Organizations->updateLegal($facturapiId, $payload);
            return $this->toArray($result);
        } catch (Facturapi_Exception $e) {
            $this->handleFacturapiException($e);
        }
    }

    /**
     * Actualizar los certificados fiscales de una Organización por ID de Facturapi
     */
    public function uploadCertificate(string $facturapiId, array $payload): array
    {
        $default_error_msg = "No fue posible actualizar los certificados de la organización. Notifica este error.";

        try {
            $response = $this->client->Organizations->uploadCertificate($facturapiId, $payload);
            $result = $this->toArray($response);

            if (isset($result['ok']) && $result['ok'] === false) {
                $message = $result['message'] ?? $default_error_msg;

                Log::warning('Facturapi rechazó el certificado', ['facturapiId' => $facturapiId, 'payload' => array_keys($payload), 'result' => $result]);
                throw ValidationException::withMessages(['facturapi' => [$message]]);
            }

            return $result;
        } catch (Facturapi_Exception $e) {
            $this->handleFacturapiException($e);
        }
    }

    /**
     * Eliminar Organización por ID de Facturapi
     */
    public function delete(string $facturapiId): array
    {

        $result = $this->client->Organizations->delete($facturapiId);
        return $this->toArray($result);
    }


  //* Inherited Functions
    protected function parsePayload(array $form_data): array {
        $tax_address = $form_data['tax_address'];
        $default_name = data_get($form_data, 'legal_name', Business::first()->legal_name);

        return [
            'name' => $default_name,
            'legal_name' => $default_name,
            'tax_system' => $form_data['tax_system'],
            'support_email' => $form_data['email'],

            'address' => array_filter([
                'zip'          => $form_data['zip'],
                'street'       => $tax_address['street'],
                'exterior'     => $tax_address['exterior'],
                'interior'     => $tax_address['interior'],
                'neighborhood' => $tax_address['neighborhood'],
                'city'         => $tax_address['city'],
                'municipality' => $tax_address['municipality'],
                'state'        => $tax_address['state'],
            ], fn ($value) => $value !== null), // Retrieves only non-null fields
        ];

    }
}
