<?php

declare(strict_types=1);

namespace App\Repositories;

use PDO;

final class StockVoucherRepository
{
    public function __construct(private PDO $pdo) {}

    public function warehouses(): array { return get_warehouses($this->pdo); }
    public function items(): array { return $this->pdo->query("SELECT id, name, barcode, cost, price FROM items WHERE is_active=1 ORDER BY name LIMIT 2000")->fetchAll(); }
    public function units(): array { return get_units($this->pdo); }
    public function itemCost(int $itemId): float { $st=$this->pdo->prepare("SELECT cost FROM items WHERE id=?"); $st->execute([$itemId]); return (float)($st->fetchColumn() ?? 0); }
    public function nextDocNo(string $prefix): string
    {
        $y = date('Y');
        $like = $prefix . '-' . $y . '-%';
        $st = $this->pdo->prepare("SELECT doc_no FROM wh_docs WHERE doc_no LIKE ? ORDER BY id DESC LIMIT 1");
        $st->execute([$like]);
        $last = (string)($st->fetchColumn() ?: '');
        $seq = 1;
        if ($last) { $parts = explode('-', $last); $seq = (int)end($parts) + 1; }
        return sprintf('%s-%s-%05d', $prefix, $y, $seq);
    }
    public function balancesForItems(int $warehouseId, array $ids): array
    {
        if (!$ids) return [];
        $in = implode(',', array_fill(0,count($ids),'?'));
        $st = $this->pdo->prepare("SELECT item_id, COALESCE(qty,0) qty FROM stock_balances WHERE warehouse_id=? AND item_id IN ($in)");
        $st->execute(array_merge([$warehouseId], $ids));
        $have = [];
        foreach ($st->fetchAll() as $r) $have[(int)$r['item_id']] = (float)$r['qty'];
        return $have;
    }
    public function itemName(int $itemId): string
    {
        $st = $this->pdo->prepare("SELECT name FROM items WHERE id=?"); $st->execute([$itemId]);
        return (string)($st->fetchColumn() ?: ('#'.$itemId));
    }
    public function createDoc(array $data): int
    {
        $this->pdo->prepare("INSERT INTO wh_docs (doc_no, doc_date, doc_type, status, warehouse_id, to_warehouse_id, notes, created_by)
                       VALUES (?,?,?,?,?,?,?,?)")
            ->execute([$data['doc_no'], $data['doc_date'], $data['doc_type'], 'POSTED', $data['warehouse_id'], $data['to_warehouse_id'], $data['notes'], $data['created_by']]);
        return (int)$this->pdo->lastInsertId();
    }
    public function createLine(int $docId, int $lineNo, int $itemId, ?int $unitId, float $qty, float $cost): void
    {
        $this->pdo->prepare("INSERT INTO wh_doc_lines (doc_id, line_no, item_id, unit_id, qty, unit_cost)
                           VALUES (?,?,?,?,?,?)")
            ->execute([$docId, $lineNo, $itemId, $unitId, $qty, $cost]);
    }
    public function insertMove(string $refType, int $docId, int $warehouseId, int $itemId, float $qtyIn, float $qtyOut, float $cost, int $userId): void
    {
        $this->pdo->prepare("INSERT INTO stock_moves (ref_type, ref_id, warehouse_id, item_id, qty_in, qty_out, cost, user_id)
                               VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
            ->execute([$refType, $docId, $warehouseId, $itemId, $qtyIn, $qtyOut, $cost, $userId]);
    }
}
