<?php

declare(strict_types=1);

namespace App\Repositories;

use PDO;

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

    public function search(string $q, string $status, int $partyId): array
    {
        $sql = "SELECT q.*, p.name party_name, p.phone party_phone
                FROM quotations q
                JOIN parties p ON p.id=q.party_id
                WHERE 1=1";
        $params = [];
        if ($status !== '') {
            $sql .= ' AND q.status=?';
            $params[] = $status;
        }
        if ($partyId > 0) {
            $sql .= ' AND q.party_id=?';
            $params[] = $partyId;
        }
        if ($q !== '') {
            $sql .= ' AND (q.quotation_no LIKE ? OR p.name LIKE ? OR COALESCE(p.phone,\'\') LIKE ?)';
            $like = "%{$q}%";
            array_push($params, $like, $like, $like);
        }
        $sql .= ' ORDER BY q.id DESC LIMIT 300';
        $st = $this->pdo->prepare($sql);
        $st->execute($params);
        return $st->fetchAll() ?: [];
    }

    public function fetchCustomers(): array
    {
        return $this->pdo->query("SELECT id, name, phone, email FROM parties WHERE COALESCE(is_customer,0)=1 AND COALESCE(is_active,1)=1 ORDER BY name ASC LIMIT 1000")->fetchAll() ?: [];
    }

    public function fetchCustomersCompact(): array
    {
        return $this->pdo->query("SELECT id, name, phone FROM parties WHERE COALESCE(is_customer,0)=1 AND COALESCE(is_active,1)=1 ORDER BY name ASC LIMIT 500")->fetchAll() ?: [];
    }

    public function findById(int $id): array|false
    {
        $st = $this->pdo->prepare("SELECT * FROM quotations WHERE id=? LIMIT 1");
        $st->execute([$id]);
        return $st->fetch();
    }

    public function findWithParty(int $id): array|false
    {
        $st = $this->pdo->prepare("SELECT q.*, p.name party_name, p.phone party_phone, p.email party_email FROM quotations q JOIN parties p ON p.id=q.party_id WHERE q.id=? LIMIT 1");
        $st->execute([$id]);
        return $st->fetch();
    }

    public function fetchItems(int $quotationId): array
    {
        $st = $this->pdo->prepare("SELECT qi.*, i.name item_name, i.barcode FROM quotation_items qi LEFT JOIN items i ON i.id=qi.item_id WHERE qi.quotation_id=? ORDER BY qi.id ASC");
        $st->execute([$quotationId]);
        return $st->fetchAll() ?: [];
    }

    public function fetchFormItems(int $quotationId): array
    {
        $st = $this->pdo->prepare("SELECT qi.*, i.name item_name FROM quotation_items qi LEFT JOIN items i ON i.id=qi.item_id WHERE qi.quotation_id=? ORDER BY qi.id ASC");
        $st->execute([$quotationId]);
        return $st->fetchAll() ?: [];
    }

    public function fetchDispatchLogs(int $quotationId): array
    {
        $st = $this->pdo->prepare("SELECT * FROM quotation_dispatch_logs WHERE quotation_id=? ORDER BY id DESC");
        $st->execute([$quotationId]);
        return $st->fetchAll() ?: [];
    }

    public function create(array $data): int
    {
        $st = $this->pdo->prepare("INSERT INTO quotations (quotation_no, quotation_date, valid_until, party_id, status, subtotal, discount_amount, tax_amount, total_amount, notes, payment_terms, delivery_terms, terms_conditions, created_by) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
        $st->execute([
            $data['quotation_no'],
            $data['quotation_date'],
            $data['valid_until'],
            $data['party_id'],
            $data['status'],
            $data['subtotal'],
            0,
            0,
            $data['subtotal'],
            $data['notes'],
            $data['payment_terms'],
            $data['delivery_terms'],
            $data['terms_conditions'],
            $data['created_by'],
        ]);
        return (int) $this->pdo->lastInsertId();
    }

    public function update(int $id, array $data): void
    {
        $st = $this->pdo->prepare("UPDATE quotations SET quotation_no=?, quotation_date=?, valid_until=?, party_id=?, status=?, subtotal=?, discount_amount=0, tax_amount=0, total_amount=?, notes=?, payment_terms=?, delivery_terms=?, terms_conditions=? WHERE id=?");
        $st->execute([
            $data['quotation_no'],
            $data['quotation_date'],
            $data['valid_until'],
            $data['party_id'],
            $data['status'],
            $data['subtotal'],
            $data['subtotal'],
            $data['notes'],
            $data['payment_terms'],
            $data['delivery_terms'],
            $data['terms_conditions'],
            $id,
        ]);
    }

    public function replaceItems(int $quotationId, array $lines): void
    {
        $this->pdo->prepare("DELETE FROM quotation_items WHERE quotation_id=?")->execute([$quotationId]);
        $ins = $this->pdo->prepare("INSERT INTO quotation_items (quotation_id, item_id, qty, unit_price, line_total, notes) VALUES (?,?,?,?,?,?)");
        foreach ($lines as $ln) {
            $ins->execute([
                $quotationId,
                $ln['item_id'],
                $ln['qty'],
                $ln['price'],
                $ln['line_total'],
                $ln['notes'],
            ]);
        }
    }

    public function markConverted(int $quotationId, int $invoiceId): void
    {
        $this->pdo->prepare("UPDATE quotations SET status='converted', converted_at=NOW(), converted_invoice_id=? WHERE id=?")->execute([$invoiceId, $quotationId]);
    }
}
