<?php

namespace Modules\LotesSeries\Controllers;

use Gestoreasy\Core\Http\Request;
use Gestoreasy\Core\Http\Response;
use Gestoreasy\Core\Tenant\ConnectionManager;
use Modules\LotesSeries\Services\SerieService;
use PDO;

class SeriesController {
    public function list(Request $req): Response {
        try {
            $tenantId = \Gestoreasy\Core\Tenant\TenantContext::getTenantId();
            $pdo = ConnectionManager::forTenant();
            
            $page = max(1, (int)($req->query['page'] ?? 1));
            $per = min(100, max(1, (int)($req->query['per_page'] ?? 20)));
            $offset = ($page - 1) * $per;

            $where = ['tenant_id = ?'];
            $params = [$tenantId];

            if (!empty($req->query['product_id'])) {
                $where[] = 'product_id = ?';
                $params[] = $req->query['product_id'];
            }

            if (!empty($req->query['status'])) {
                $where[] = 'status = ?';
                $params[] = $req->query['status'];
            }

            if (!empty($req->query['numero_serie'])) {
                $where[] = 'numero_serie LIKE ?';
                $params[] = '%' . $req->query['numero_serie'] . '%';
            }

            $whereSql = implode(' AND ', $where);

            $sql = "SELECT s.*, p.codigo as produto_codigo, p.nome as produto_nome
                    FROM product_serial_numbers s
                    INNER JOIN products p ON s.product_id = p.id
                    WHERE {$whereSql}
                    ORDER BY s.created_at DESC
                    LIMIT ? OFFSET ?";
            $stmt = $pdo->prepare($sql);
            $stmt->execute(array_merge($params, [$per, $offset]));
            $series = $stmt->fetchAll(PDO::FETCH_ASSOC);

            // Total
            $countSql = "SELECT COUNT(*) FROM product_serial_numbers WHERE {$whereSql}";
            $countStmt = $pdo->prepare($countSql);
            $countStmt->execute($params);
            $total = (int)$countStmt->fetchColumn();

            return Response::json([
                'data' => $series,
                'pagination' => [
                    'page' => $page,
                    'per_page' => $per,
                    'total' => $total,
                    'total_pages' => (int)ceil($total / $per)
                ]
            ]);
        } catch (\Exception $e) {
            return new Response(500, ['error' => ['code' => 'error', 'message' => $e->getMessage()]]);
        }
    }

    public function get(Request $req): Response {
        try {
            $tenantId = \Gestoreasy\Core\Tenant\TenantContext::getTenantId();
            $pdo = ConnectionManager::forTenant();
            $id = (int)($req->get('params')[0] ?? 0);

            $stmt = $pdo->prepare('
                SELECT s.*, p.codigo as produto_codigo, p.nome as produto_nome
                FROM product_serial_numbers s
                INNER JOIN products p ON s.product_id = p.id
                WHERE s.id = ? AND s.tenant_id = ?
            ');
            $stmt->execute([$id, $tenantId]);
            $serie = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$serie) {
                return new Response(404, ['error' => ['code' => 'not_found', 'message' => 'Série não encontrada']]);
            }

            return Response::json(['data' => $serie]);
        } catch (\Exception $e) {
            return new Response(500, ['error' => ['code' => 'error', 'message' => $e->getMessage()]]);
        }
    }

    public function create(Request $req): Response {
        try {
            $tenantId = \Gestoreasy\Core\Tenant\TenantContext::getTenantId();
            $body = is_array($req->body) ? $req->body : [];

            $service = new SerieService($tenantId);
            $serieId = $service->criarSerie($body);

            return Response::json(['data' => ['id' => $serieId]], 201);
        } catch (\Exception $e) {
            return new Response(500, ['error' => ['code' => 'error', 'message' => $e->getMessage()]]);
        }
    }

    public function update(Request $req): Response {
        try {
            $tenantId = \Gestoreasy\Core\Tenant\TenantContext::getTenantId();
            $pdo = ConnectionManager::forTenant();
            $id = (int)($req->get('params')[0] ?? 0);
            $body = is_array($req->body) ? $req->body : [];

            $allowedFields = ['observacoes', 'warehouse_id', 'bin_id', 'status'];
            $updates = [];
            $params = [];

            foreach ($allowedFields as $field) {
                if (isset($body[$field])) {
                    $updates[] = "{$field} = ?";
                    $params[] = $body[$field];
                }
            }

            if (empty($updates)) {
                return new Response(422, ['error' => ['code' => 'validation_error', 'message' => 'Nenhum campo para atualizar']]);
            }

            $params[] = $id;
            $params[] = $tenantId;

            $sql = 'UPDATE product_serial_numbers SET ' . implode(', ', $updates) . ' WHERE id = ? AND tenant_id = ?';
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);

            return Response::json(['data' => ['success' => true]]);
        } catch (\Exception $e) {
            return new Response(500, ['error' => ['code' => 'error', 'message' => $e->getMessage()]]);
        }
    }

    public function delete(Request $req): Response {
        try {
            $tenantId = \Gestoreasy\Core\Tenant\TenantContext::getTenantId();
            $pdo = ConnectionManager::forTenant();
            $id = (int)($req->get('params')[0] ?? 0);

            $stmt = $pdo->prepare('DELETE FROM product_serial_numbers WHERE id = ? AND tenant_id = ?');
            $stmt->execute([$id, $tenantId]);

            if ($stmt->rowCount() === 0) {
                return new Response(404, ['error' => ['code' => 'not_found', 'message' => 'Série não encontrada']]);
            }

            return Response::json(['data' => ['success' => true]]);
        } catch (\Exception $e) {
            return new Response(500, ['error' => ['code' => 'error', 'message' => $e->getMessage()]]);
        }
    }

    public function validarSerie(Request $req): Response {
        try {
            $tenantId = \Gestoreasy\Core\Tenant\TenantContext::getTenantId();
            $body = is_array($req->body) ? $req->body : [];

            $productId = (int)($body['product_id'] ?? 0);
            $numeroSerie = $body['numero_serie'] ?? '';

            if (!$productId || !$numeroSerie) {
                return new Response(422, ['error' => ['code' => 'validation_error', 'message' => 'product_id e numero_serie são obrigatórios']]);
            }

            $service = new SerieService($tenantId);
            $validacao = $service->validarSerie($productId, $numeroSerie);

            return Response::json(['data' => $validacao]);
        } catch (\Exception $e) {
            return new Response(500, ['error' => ['code' => 'error', 'message' => $e->getMessage()]]);
        }
    }
}

