<?php

namespace Modules\LotesSeries\Controllers;

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

class LotesController {
    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_lote'])) {
                $where[] = 'numero_lote LIKE ?';
                $params[] = '%' . $req->query['numero_lote'] . '%';
            }

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

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

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

            return Response::json([
                'data' => $lotes,
                '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 l.*, p.codigo as produto_codigo, p.nome as produto_nome
                FROM product_lots l
                INNER JOIN products p ON l.product_id = p.id
                WHERE l.id = ? AND l.tenant_id = ?
            ');
            $stmt->execute([$id, $tenantId]);
            $lote = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$lote) {
                return new Response(404, ['error' => ['code' => 'not_found', 'message' => 'Lote não encontrado']]);
            }

            return Response::json(['data' => $lote]);
        } 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 LoteService($tenantId);
            $loteId = $service->criarLote($body);

            return Response::json(['data' => ['id' => $loteId]], 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_lots 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_lots WHERE id = ? AND tenant_id = ?');
            $stmt->execute([$id, $tenantId]);

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

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

    public function getProximosVencer(Request $req): Response {
        try {
            $tenantId = \Gestoreasy\Core\Tenant\TenantContext::getTenantId();
            $dias = (int)($req->query['dias'] ?? 30);

            $service = new LoteService($tenantId);
            $lotes = $service->getProximosVencer($dias);

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

    public function getVencidos(Request $req): Response {
        try {
            $tenantId = \Gestoreasy\Core\Tenant\TenantContext::getTenantId();

            $service = new LoteService($tenantId);
            $lotes = $service->getVencidos();

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

    public function sugerirLote(Request $req): Response {
        try {
            $tenantId = \Gestoreasy\Core\Tenant\TenantContext::getTenantId();
            $productId = (int)($req->get('params')[0] ?? 0);
            $quantidade = (float)($req->query['quantidade'] ?? 1);
            $politica = $req->query['politica'] ?? 'fifo';

            $service = new LoteService($tenantId);
            $lote = $service->sugerirLote($productId, $quantidade, $politica);

            if (!$lote) {
                return new Response(404, ['error' => ['code' => 'not_found', 'message' => 'Nenhum lote disponível']]);
            }

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

