<?php

declare(strict_types=1);

namespace ApiModel\Infrastructure\Persistence\Repositories;

use ApiModel\Domain\Repository\InventoryTransferRepositoryInterface;
use ApiModel\Infrastructure\Persistence\Database;
use PDO;

final class PdoInventoryTransferRepository implements InventoryTransferRepositoryInterface
{
    public function __construct(private readonly PDO $pdo) {}

    public function findById(string $id): ?array
    {
        $st = $this->pdo->prepare(
            'SELECT t.*, w1.name as from_warehouse_name, w2.name as to_warehouse_name
             FROM inventory_transfers t
             JOIN warehouses w1 ON t.from_warehouse_id = w1.id
             JOIN warehouses w2 ON t.to_warehouse_id = w2.id
             WHERE t.id = ? 
             LIMIT 1'
        );
        $st->execute([$id]);
        $row = $st->fetch(PDO::FETCH_ASSOC);
        return $row !== false ? $row : null;
    }

    public function listByCompany(string $companyId): array
    {
        $st = $this->pdo->prepare(
            'SELECT t.*, w1.name as from_warehouse_name, w2.name as to_warehouse_name
             FROM inventory_transfers t
             JOIN warehouses w1 ON t.from_warehouse_id = w1.id
             JOIN warehouses w2 ON t.to_warehouse_id = w2.id
             WHERE t.company_id = ? 
             ORDER BY t.transfer_date DESC, t.created_at DESC'
        );
        $st->execute([$companyId]);
        return $st->fetchAll(PDO::FETCH_ASSOC);
    }

    public function nextTransferNumber(string $companyId): string
    {
        $st = $this->pdo->prepare('SELECT COUNT(*) FROM inventory_transfers WHERE company_id = ?');
        $st->execute([$companyId]);
        $count = (int) $st->fetchColumn();
        return 'TR-' . str_pad((string) ($count + 1), 6, '0', STR_PAD_LEFT);
    }

    public function insert(array $data): void
    {
        $st = $this->pdo->prepare(
            'INSERT INTO inventory_transfers (
                id, company_id, branch_id, transfer_number, transfer_date, 
                from_warehouse_id, to_warehouse_id, notes, created_by, created_at, updated_at
             ) VALUES (
                :id, :company_id, :branch_id, :transfer_number, :transfer_date,
                :from_warehouse_id, :to_warehouse_id, :notes, :created_by, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
             )'
        );
        $st->execute([
            'id' => $data['id'],
            'company_id' => $data['company_id'],
            'branch_id' => $data['branch_id'] ?: null,
            'transfer_number' => $data['transfer_number'],
            'transfer_date' => $data['transfer_date'],
            'from_warehouse_id' => $data['from_warehouse_id'],
            'to_warehouse_id' => $data['to_warehouse_id'],
            'notes' => $data['notes'] ?: null,
            'created_by' => $data['created_by'] ?: null,
        ]);
    }

    public function delete(string $id): void
    {
        $st = $this->pdo->prepare('DELETE FROM inventory_transfers WHERE id = ?');
        $st->execute([$id]);
    }

    public function findLinesByTransferId(string $transferId): array
    {
        $st = $this->pdo->prepare(
            'SELECT l.*, i.sku as item_sku, i.name as item_name
             FROM inventory_transfer_lines l
             JOIN inventory_items i ON l.item_id = i.id
             WHERE l.transfer_id = ?'
        );
        $st->execute([$transferId]);
        return $st->fetchAll(PDO::FETCH_ASSOC);
    }

    public function insertLines(string $transferId, array $lines): void
    {
        $st = $this->pdo->prepare(
            'INSERT INTO inventory_transfer_lines (id, transfer_id, item_id, quantity) 
             VALUES (?, ?, ?, ?)'
        );

        foreach ($lines as $line) {
            $id = $line['id'] ?? Database::uuid();
            $st->execute([
                $id,
                $transferId,
                $line['item_id'],
                $line['quantity'],
            ]);
        }
    }

    public function deleteLines(string $transferId): void
    {
        $st = $this->pdo->prepare('DELETE FROM inventory_transfer_lines WHERE transfer_id = ?');
        $st->execute([$transferId]);
    }
}
