<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Cache;
use App\Models\OdooLog;
use App\Models\OdooError;
use Exception;

class OdooServices
{
    protected string $baseUrl;
    protected string $db;
    protected string $login;
    protected string $password;

    public function __construct()
    {
        $this->baseUrl  = config('services.odoo.host');
        $this->db       = config('services.odoo.database');
        $this->login    = config('services.odoo.username');
        $this->password = config('services.odoo.password');
    }

    /**
     * 🔐 Login
     */
    public function login(): array
    {
        try {

            $response = Http::post($this->baseUrl . '/web/session/authenticate', [
                'jsonrpc' => '2.0',
                'params'  => [
                    'db'       => $this->db,
                    'login'    => $this->login,
                    'password' => $this->password,
                ],
            ]);

            if (!$response->ok()) {
                throw new Exception('Error HTTP login Odoo');
            }
            
            $json = $response->json();
            
            // 🔥 ESTE ES EL FIX IMPORTANTE
            if (!isset($json['result']['uid'])) {
                throw new Exception('Credenciales inválidas');
            }
            $cookies = $response->cookies();

            if (!$cookies || empty($cookies->toArray())) {
                throw new Exception('Sin cookies de sesión');
            }

            // 🔥 serializamos (importante)
            Cache::put('odoo_cookies', serialize($cookies), now()->addHours(23));

            return [
                'success' => true
            ];

        } catch (\Throwable $e) {

            OdooError::create([
                'endpoint' => '/web/session/authenticate',
                'mensaje'  => $e->getMessage(),
            ]);

            return [
                'success' => false,
                'error'   => $e->getMessage(),
            ];
        }
    }

    /**
     * 🧠 Obtener cookies
     */
    private function getCookies()
    {
        $cookies = Cache::get('odoo_cookies');
        return $cookies ? unserialize($cookies) : null;
    }

    /**
     * 📡 Request genérico a Odoo
     */
    private function request(string $endpoint, array $payload, bool $retry = true)
    {
        $start = microtime(true);

        try {

            $cookies = $this->getCookies();

            if (!$cookies) {

                $login = $this->login($ODOO_DATABASE, $ODOO_HOST, $ODOO_USERNAME, $ODOO_PASSWORD);

                if (!$login['success']) {
                    return [
                        'error' => true,
                        'message' => $login['error'] ?? 'Error login Odoo'
                    ];
                }

                // 🔥 AHORA SÍ, vuelve a obtener cookies
                $cookies = $this->getCookies();

                if (!$cookies) {
                    throw new Exception('Login OK pero sin cookies');
                }
            }

            $response = Http::withOptions([
                'cookies' => $cookies,
            ])->post($this->baseUrl . $endpoint, $payload);

            $json = $response->json();

            // 🔥 sesión expirada
            if (isset($json['error']['code']) && $json['error']['code'] === 100) {

                Cache::forget('odoo_cookies');

                if ($retry) {
                    $this->login();
                    return $this->request($endpoint, $payload, false);
                }

                throw new Exception('Sesión expirada');
            }

            // 📊 log
            OdooLog::create([
                'endpoint'   => $endpoint,
                'modelo'     => $payload['params']['model'] ?? null,
                'metodo'     => $payload['params']['method'] ?? null,
                'request'    => $payload,
                'response'   => $json,
                'http_code'  => $response->status(),
                'duracion_ms'=> (microtime(true) - $start) * 1000,
                'exito'      => 1
            ]);

            return $json;

        } catch (\Throwable $e) {

            OdooError::create([
                'endpoint' => $endpoint,
                'mensaje'  => $e->getMessage(),
                'request'  => $payload
            ]);

            return [
                'error' => true,
                'message' => $e->getMessage()
            ];
        }
    }

    /**
     * 👥 Obtener contactos
     */
    public function listClientes(int $limit = 80, int $offset = 0, string $tipo = 'persona'): array
    {
        $domain = [];

        if ($tipo === 'persona') {
            $domain[] = ["is_company", "=", false];
        }

        if ($tipo === 'empresa') {
            $domain[] = ["is_company", "=", true];
        }

        if ($tipo === 'empleado') {
            $domain[] = ["employee", "=", true];
        }
        $payload = [
            "jsonrpc"=> "2.0",
            "method"=> "call",
            "params"=> [
                "model"=> "res.partner",
                "method"=> "web_search_read",
                "args"=> [],
                "kwargs"=> [
                    "specification"=> [
                        "id"=> [],
                        "write_date"=> [],
                        "complete_name"=> [],
                        "email"=> [],
                        "phone"=> [],
                        "vat"=> [],
                        "street"=> [],
                        "city"=> [],
                        "country_id"=> [
                            "fields"=> ["display_name"=>[]]
                        ]
                    ],
                    "offset"=> $offset,
                    "limit"=> $limit,
                    "domain"=> $domain
                ]
            ]
        ];

        $json = $this->request('/web/dataset/call_kw/res.partner/web_search_read', $payload);

        if (isset($json['error'])) {
            return [
                'success' => false,
                'error'   => $json['message']
            ];
        }

        return [
            'success'   => true,
            'contactos' => $json['result']['records'] ?? [],
            'total'     => $json['result']['length'] ?? 0
        ];
    }
}