<?php
require_once __DIR__ . '/../../includes/bootstrap.php';
require_login();

$pageTitle = 'Goods Returned to Supplier';

if (!function_exists('h')) {
    function h($value): string { return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); }
}
if (!function_exists('money_fmt')) {
    function money_fmt($amount): string { return number_format((float)$amount, 2); }
}
if (!function_exists('grtn_flash')) {
    function grtn_flash(string $type, string $message): void {
        $_SESSION['grtn_flash'][] = ['type'=>$type, 'message'=>$message];
    }
}
if (!function_exists('grtn_get_flash')) {
    function grtn_get_flash(): array {
        $rows = $_SESSION['grtn_flash'] ?? [];
        unset($_SESSION['grtn_flash']);
        return $rows;
    }
}
if (!function_exists('grtn_column_exists')) {
    function grtn_column_exists(PDO $pdo, string $table, string $column): bool {
        $stmt = $pdo->prepare("
            SELECT COUNT(*) FROM information_schema.columns
            WHERE table_schema = DATABASE()
              AND table_name = :table_name
              AND column_name = :column_name
        ");
        $stmt->execute([':table_name'=>$table, ':column_name'=>$column]);
        return (int)$stmt->fetchColumn() > 0;
    }
}
if (!function_exists('grtn_user_id')) {
    function grtn_user_id(): ?int {
        foreach (['user_id','ss_user_id','id','uid','UserID','userid'] as $key) {
            if (isset($_SESSION[$key]) && (int)$_SESSION[$key] > 0) return (int)$_SESSION[$key];
        }
        if (isset($_SESSION['user']) && is_array($_SESSION['user'])) {
            foreach (['id','user_id','UserID'] as $key) {
                if (isset($_SESSION['user'][$key]) && (int)$_SESSION['user'][$key] > 0) {
                    return (int)$_SESSION['user'][$key];
                }
            }
        }
        return null;
    }
}
if (!function_exists('grtn_no')) {
    function grtn_no(PDO $pdo): string {
        $prefix = 'GRTN-' . date('ymd') . '-';
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM inventory_supplier_returns WHERE return_no LIKE :p");
        $stmt->execute([':p'=>$prefix . '%']);
        return $prefix . str_pad((string)((int)$stmt->fetchColumn() + 1), 4, '0', STR_PAD_LEFT);
    }
}
if (!function_exists('grtn_calc_line')) {
    function grtn_calc_line(float $qty, float $unitPriceInput, string $taxType, float $taxRate, string $priceTaxMode, ?float $grossOverride = null): array {
        $qty = max(0, $qty);
        $unitPriceInput = max(0, $unitPriceInput);
        $gross = $grossOverride !== null ? round(max(0, $grossOverride), 2) : round($qty * $unitPriceInput, 2);
        $taxType = $taxType === 'Fixed' ? 'Fixed' : 'Percentage';
        $priceTaxMode = $priceTaxMode === 'inclusive' ? 'inclusive' : 'exclusive';

        if ($taxRate <= 0) {
            return [
                'net'=>$gross,
                'tax'=>0.0,
                'total'=>$gross,
                'unit_cost'=>$qty > 0 ? round($gross / $qty, 4) : 0.0,
            ];
        }

        if ($priceTaxMode === 'inclusive') {
            if ($taxType === 'Fixed') {
                $tax = round($taxRate * $qty, 2);
                $net = max(0, round($gross - $tax, 2));
            } else {
                $tax = round($gross * ($taxRate / (100 + $taxRate)), 2);
                $net = round($gross - $tax, 2);
            }
            $total = $gross;
        } else {
            $net = $gross;
            $tax = $taxType === 'Fixed'
                ? round($taxRate * $qty, 2)
                : round($net * ($taxRate / 100), 2);
            $total = round($net + $tax, 2);
        }

        return [
            'net'=>$net,
            'tax'=>$tax,
            'total'=>$total,
            'unit_cost'=>$qty > 0 ? round($net / $qty, 4) : 0.0,
        ];
    }
}
if (!function_exists('grtn_available_qty')) {
    function grtn_available_qty(PDO $pdo, int $itemId, int $storeId): float {
        $stmt = $pdo->prepare("
            SELECT COALESCE(SUM(qty_in - qty_out),0)
            FROM stock_movements
            WHERE item_id = :item_id
              AND store_id = :store_id
        ");
        $stmt->execute([':item_id'=>$itemId, ':store_id'=>$storeId]);
        return (float)$stmt->fetchColumn();
    }
}
if (!function_exists('grtn_ensure_movement_enum')) {
    function grtn_ensure_movement_enum(PDO $pdo): void {
        $stmt = $pdo->query("SHOW COLUMNS FROM stock_movements LIKE 'movement_type'");
        $row = $stmt ? $stmt->fetch(PDO::FETCH_ASSOC) : false;
        if (!$row || empty($row['Type'])) return;

        $type = (string)$row['Type'];
        if (stripos($type, "'RETURN_SUPPLIER'") !== false) return;
        if (!preg_match('/^enum\((.*)\)$/i', $type, $m)) return;

        $values = str_getcsv($m[1], ',', "'");
        $values = array_values(array_filter(array_map('trim', $values), fn($v) => $v !== ''));
        if (!in_array('RETURN_SUPPLIER', $values, true)) $values[] = 'RETURN_SUPPLIER';

        $quoted = array_map(function($v) use ($pdo) { return $pdo->quote($v); }, $values);
        $pdo->exec("
            ALTER TABLE stock_movements
            MODIFY COLUMN movement_type ENUM(" . implode(',', $quoted) . ") NOT NULL
        ");
    }
}

$errors = [];

try {
    $pdo->exec("CREATE TABLE IF NOT EXISTS inventory_supplier_returns (
        id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        return_no VARCHAR(60) NOT NULL,
        supplier_id INT UNSIGNED NOT NULL,
        supplier_name VARCHAR(180) NULL,
        store_id INT UNSIGNED NOT NULL,
        grn_id BIGINT UNSIGNED NULL,
        original_grn_no VARCHAR(60) NULL,
        supplier_credit_note_no VARCHAR(100) NULL,
        return_date DATE NOT NULL,
        reason VARCHAR(255) NULL,
        subtotal DECIMAL(14,2) NOT NULL DEFAULT 0.00,
        tax_amount DECIMAL(14,2) NOT NULL DEFAULT 0.00,
        total_amount DECIMAL(14,2) NOT NULL DEFAULT 0.00,
        status ENUM('posted','void') NOT NULL DEFAULT 'posted',
        notes TEXT NULL,
        created_by INT UNSIGNED NULL,
        void_reason TEXT NULL,
        voided_at DATETIME NULL,
        created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        UNIQUE KEY uq_inventory_supplier_return_no (return_no),
        INDEX idx_supplier_return_supplier (supplier_id),
        INDEX idx_supplier_return_store (store_id),
        INDEX idx_supplier_return_grn (grn_id),
        INDEX idx_supplier_return_date (return_date)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    $pdo->exec("CREATE TABLE IF NOT EXISTS inventory_supplier_return_lines (
        id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        return_id BIGINT UNSIGNED NOT NULL,
        grn_line_id BIGINT UNSIGNED NULL,
        item_id INT UNSIGNED NOT NULL,
        qty DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        unit_price_entered DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        unit_cost DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        tax_id INT UNSIGNED NULL,
        tax_name VARCHAR(255) NULL,
        tax_type VARCHAR(30) NULL,
        price_tax_mode ENUM('exclusive','inclusive') NOT NULL DEFAULT 'exclusive',
        tax_rate DECIMAL(7,4) NOT NULL DEFAULT 0.0000,
        line_tax DECIMAL(14,2) NOT NULL DEFAULT 0.00,
        line_total DECIMAL(14,2) NOT NULL DEFAULT 0.00,
        reason VARCHAR(255) NULL,
        created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        INDEX idx_supplier_return_line_return (return_id),
        INDEX idx_supplier_return_line_item (item_id),
        INDEX idx_supplier_return_line_grn_line (grn_line_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    grtn_ensure_movement_enum($pdo);
} catch (Throwable $e) {
    $errors[] = 'Could not prepare supplier return tables: ' . $e->getMessage();
}

/* AJAX: load an existing GRN into the return form. */
if (isset($_GET['ajax']) && $_GET['ajax'] === 'load_grn') {
    header('Content-Type: application/json; charset=utf-8');
    try {
        $grnId = (int)($_GET['grn_id'] ?? 0);
        if ($grnId <= 0) throw new RuntimeException('Invalid GRN.');

        $stmt = $pdo->prepare("
            SELECT g.*, sl.location_name
            FROM inventory_grns g
            LEFT JOIN store_locations sl ON sl.id = g.store_id
            WHERE g.id = :id
              AND g.status = 'posted'
            LIMIT 1
        ");
        $stmt->execute([':id'=>$grnId]);
        $grn = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$grn) throw new RuntimeException('Posted GRN not found.');

        $stmt = $pdo->prepare("
            SELECT
                gl.id AS grn_line_id,
                gl.item_id,
                ii.item_code,
                ii.item_name,
                gl.qty AS received_qty,
                gl.unit_price_entered,
                gl.unit_cost,
                gl.tax_id,
                gl.tax_name,
                gl.tax_type,
                gl.price_tax_mode,
                gl.tax_rate,
                COALESCE((
                    SELECT SUM(srl.qty)
                    FROM inventory_supplier_return_lines srl
                    INNER JOIN inventory_supplier_returns sr ON sr.id = srl.return_id
                    WHERE srl.grn_line_id = gl.id
                      AND sr.status = 'posted'
                ),0) AS already_returned
            FROM inventory_grn_lines gl
            INNER JOIN inventory_items ii ON ii.id = gl.item_id
            WHERE gl.grn_id = :grn_id
            ORDER BY gl.id
        ");
        $stmt->execute([':grn_id'=>$grnId]);
        $lines = $stmt->fetchAll(PDO::FETCH_ASSOC);

        foreach ($lines as &$line) {
            $line['remaining_from_grn'] = max(0, (float)$line['received_qty'] - (float)$line['already_returned']);
            $line['available_qty'] = grtn_available_qty($pdo, (int)$line['item_id'], (int)$grn['store_id']);
        }

        echo json_encode(['ok'=>true, 'grn'=>$grn, 'lines'=>$lines]);
    } catch (Throwable $e) {
        http_response_code(422);
        echo json_encode(['ok'=>false, 'error'=>$e->getMessage()]);
    }
    exit;
}

if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
    try {
        if (function_exists('verify_csrf')) verify_csrf();
        $action = (string)($_POST['action'] ?? '');

        if ($action === 'post_return') {
            $supplierId = (int)($_POST['supplier_id'] ?? 0);
            $storeId = (int)($_POST['store_id'] ?? 0);
            $grnId = (int)($_POST['grn_id'] ?? 0);
            $creditNoteNo = trim((string)($_POST['supplier_credit_note_no'] ?? ''));
            $returnDate = trim((string)($_POST['return_date'] ?? date('Y-m-d')));
            $headerReason = trim((string)($_POST['reason'] ?? ''));
            $notes = trim((string)($_POST['notes'] ?? ''));

            if ($supplierId <= 0) throw new RuntimeException('Please select supplier.');
            if ($storeId <= 0) throw new RuntimeException('Please select store.');
            if (strtotime($returnDate) === false) $returnDate = date('Y-m-d');

            $stmt = $pdo->prepare("SELECT supplier_name FROM inventory_suppliers WHERE id=:id LIMIT 1");
            $stmt->execute([':id'=>$supplierId]);
            $supplierName = (string)($stmt->fetchColumn() ?: '');
            if ($supplierName === '') throw new RuntimeException('Supplier not found.');

            $originalGrnNo = null;
            if ($grnId > 0) {
                $stmt = $pdo->prepare("
                    SELECT grn_no, supplier_id, store_id
                    FROM inventory_grns
                    WHERE id=:id AND status='posted'
                    LIMIT 1
                ");
                $stmt->execute([':id'=>$grnId]);
                $grn = $stmt->fetch(PDO::FETCH_ASSOC);
                if (!$grn) throw new RuntimeException('Original GRN was not found.');
                if ((int)$grn['supplier_id'] !== $supplierId) {
                    throw new RuntimeException('Selected supplier does not match the original GRN.');
                }
                if ((int)$grn['store_id'] !== $storeId) {
                    throw new RuntimeException('Selected store does not match the original GRN.');
                }
                $originalGrnNo = (string)$grn['grn_no'];
            }

            $itemIds = $_POST['item_id'] ?? [];
            $grnLineIds = $_POST['grn_line_id'] ?? [];
            $qtys = $_POST['qty'] ?? [];
            $unitPrices = $_POST['unit_price'] ?? [];
            $lineAmounts = $_POST['line_amount'] ?? [];
            $taxIds = $_POST['tax_id'] ?? [];
            $taxModes = $_POST['price_tax_mode'] ?? [];
            $lineReasons = $_POST['line_reason'] ?? [];

            $taxMap = [];
            foreach ($pdo->query("SELECT id,name,code,type,rate FROM taxes ORDER BY name")->fetchAll(PDO::FETCH_ASSOC) as $taxRow) {
                $taxMap[(int)$taxRow['id']] = $taxRow;
            }

            $lines = [];
            $subtotal = 0.0;
            $taxAmount = 0.0;

            foreach ($itemIds as $idx => $itemRaw) {
                $itemId = (int)$itemRaw;
                $qty = (float)str_replace(',', '', (string)($qtys[$idx] ?? 0));
                $unitPrice = (float)str_replace(',', '', (string)($unitPrices[$idx] ?? 0));
                $lineAmountRaw = trim(str_replace(',', '', (string)($lineAmounts[$idx] ?? '')));
                $lineAmount = ($lineAmountRaw !== '' && is_numeric($lineAmountRaw)) ? (float)$lineAmountRaw : null;
                $grnLineId = (int)($grnLineIds[$idx] ?? 0);
                $taxId = (int)($taxIds[$idx] ?? 0);
                $taxMode = strtolower((string)($taxModes[$idx] ?? 'exclusive')) === 'inclusive' ? 'inclusive' : 'exclusive';
                $lineReason = trim((string)($lineReasons[$idx] ?? ''));

                if ($itemId <= 0 && $qty <= 0) continue;
                if ($itemId <= 0) throw new RuntimeException('One return line is missing an item.');
                if ($qty <= 0) throw new RuntimeException('Return quantity must be greater than zero.');
                if ($unitPrice < 0 || ($lineAmount !== null && $lineAmount < 0)) {
                    throw new RuntimeException('Return prices and amounts cannot be negative.');
                }

                $stmt = $pdo->prepare("SELECT item_name,is_stock_item FROM inventory_items WHERE id=:id LIMIT 1");
                $stmt->execute([':id'=>$itemId]);
                $item = $stmt->fetch(PDO::FETCH_ASSOC);
                if (!$item) throw new RuntimeException('Selected inventory item was not found.');
                if ((int)$item['is_stock_item'] !== 1) throw new RuntimeException($item['item_name'] . ' is not a stock item.');

                $available = grtn_available_qty($pdo, $itemId, $storeId);
                if ($qty > $available + 0.00001) {
                    throw new RuntimeException(
                        $item['item_name'] . ': return quantity ' . number_format($qty,4) .
                        ' exceeds available stock ' . number_format($available,4) . '.'
                    );
                }

                if ($grnLineId > 0) {
                    $stmt = $pdo->prepare("
                        SELECT gl.qty, gl.item_id,
                               COALESCE((
                                 SELECT SUM(srl.qty)
                                 FROM inventory_supplier_return_lines srl
                                 INNER JOIN inventory_supplier_returns sr ON sr.id=srl.return_id
                                 WHERE srl.grn_line_id=gl.id AND sr.status='posted'
                               ),0) already_returned
                        FROM inventory_grn_lines gl
                        WHERE gl.id=:id AND gl.grn_id=:grn_id
                        LIMIT 1
                    ");
                    $stmt->execute([':id'=>$grnLineId, ':grn_id'=>$grnId]);
                    $source = $stmt->fetch(PDO::FETCH_ASSOC);
                    if (!$source || (int)$source['item_id'] !== $itemId) {
                        throw new RuntimeException('A return line does not match the selected original GRN.');
                    }
                    $remaining = max(0, (float)$source['qty'] - (float)$source['already_returned']);
                    if ($qty > $remaining + 0.00001) {
                        throw new RuntimeException(
                            $item['item_name'] . ': return quantity exceeds the remaining quantity from the original GRN.'
                        );
                    }
                }

                $taxName = null;
                $taxType = 'Percentage';
                $taxRate = 0.0;
                if ($taxId > 0) {
                    if (!isset($taxMap[$taxId])) throw new RuntimeException('Invalid tax selected.');
                    $taxName = (string)$taxMap[$taxId]['name'];
                    $taxType = (string)$taxMap[$taxId]['type'] === 'Fixed' ? 'Fixed' : 'Percentage';
                    $taxRate = (float)$taxMap[$taxId]['rate'];
                }

                $amounts = grtn_calc_line($qty, $unitPrice, $taxType, $taxRate, $taxMode, $lineAmount);
                $subtotal += (float)$amounts['net'];
                $taxAmount += (float)$amounts['tax'];

                $storedUnitPrice = $unitPrice;
                if ($lineAmount !== null && $qty > 0 && $storedUnitPrice <= 0) {
                    $storedUnitPrice = round($lineAmount / $qty, 4);
                }

                $lines[] = [
                    'grn_line_id'=>$grnLineId > 0 ? $grnLineId : null,
                    'item_id'=>$itemId,
                    'item_name'=>(string)$item['item_name'],
                    'qty'=>$qty,
                    'unit_price'=>$storedUnitPrice,
                    'unit_cost'=>(float)$amounts['unit_cost'],
                    'tax_id'=>$taxId > 0 ? $taxId : null,
                    'tax_name'=>$taxName,
                    'tax_type'=>$taxType,
                    'tax_mode'=>$taxMode,
                    'tax_rate'=>$taxRate,
                    'line_tax'=>(float)$amounts['tax'],
                    'line_total'=>(float)$amounts['total'],
                    'reason'=>$lineReason !== '' ? $lineReason : $headerReason,
                ];
            }

            if (!$lines) throw new RuntimeException('Please add at least one goods return line.');

            $subtotal = round($subtotal,2);
            $taxAmount = round($taxAmount,2);
            $totalAmount = round($subtotal + $taxAmount,2);

            $pdo->beginTransaction();

            $returnNo = grtn_no($pdo);
            $stmt = $pdo->prepare("
                INSERT INTO inventory_supplier_returns
                (return_no,supplier_id,supplier_name,store_id,grn_id,original_grn_no,
                 supplier_credit_note_no,return_date,reason,subtotal,tax_amount,total_amount,
                 status,notes,created_by)
                VALUES
                (:return_no,:supplier_id,:supplier_name,:store_id,:grn_id,:original_grn_no,
                 :supplier_credit_note_no,:return_date,:reason,:subtotal,:tax_amount,:total_amount,
                 'posted',:notes,:created_by)
            ");
            $stmt->execute([
                ':return_no'=>$returnNo,
                ':supplier_id'=>$supplierId,
                ':supplier_name'=>$supplierName,
                ':store_id'=>$storeId,
                ':grn_id'=>$grnId > 0 ? $grnId : null,
                ':original_grn_no'=>$originalGrnNo,
                ':supplier_credit_note_no'=>$creditNoteNo !== '' ? $creditNoteNo : null,
                ':return_date'=>date('Y-m-d',strtotime($returnDate)),
                ':reason'=>$headerReason !== '' ? $headerReason : null,
                ':subtotal'=>$subtotal,
                ':tax_amount'=>$taxAmount,
                ':total_amount'=>$totalAmount,
                ':notes'=>$notes !== '' ? $notes : null,
                ':created_by'=>grtn_user_id(),
            ]);
            $returnId = (int)$pdo->lastInsertId();

            $lineStmt = $pdo->prepare("
                INSERT INTO inventory_supplier_return_lines
                (return_id,grn_line_id,item_id,qty,unit_price_entered,unit_cost,tax_id,tax_name,
                 tax_type,price_tax_mode,tax_rate,line_tax,line_total,reason)
                VALUES
                (:return_id,:grn_line_id,:item_id,:qty,:unit_price_entered,:unit_cost,:tax_id,:tax_name,
                 :tax_type,:price_tax_mode,:tax_rate,:line_tax,:line_total,:reason)
            ");
            $moveStmt = $pdo->prepare("
                INSERT INTO stock_movements
                (item_id,store_id,movement_type,qty_in,qty_out,unit_cost,total_cost,
                 reference_type,reference_id,notes,movement_date)
                VALUES
                (:item_id,:store_id,'RETURN_SUPPLIER',0,:qty_out,:unit_cost,:total_cost,
                 'SUPPLIER_RETURN',:reference_id,:notes,:movement_date)
            ");

            foreach ($lines as $line) {
                $lineStmt->execute([
                    ':return_id'=>$returnId,
                    ':grn_line_id'=>$line['grn_line_id'],
                    ':item_id'=>$line['item_id'],
                    ':qty'=>$line['qty'],
                    ':unit_price_entered'=>$line['unit_price'],
                    ':unit_cost'=>$line['unit_cost'],
                    ':tax_id'=>$line['tax_id'],
                    ':tax_name'=>$line['tax_name'],
                    ':tax_type'=>$line['tax_type'],
                    ':price_tax_mode'=>$line['tax_mode'],
                    ':tax_rate'=>$line['tax_rate'],
                    ':line_tax'=>$line['line_tax'],
                    ':line_total'=>$line['line_total'],
                    ':reason'=>$line['reason'] ?: null,
                ]);

                $moveStmt->execute([
                    ':item_id'=>$line['item_id'],
                    ':store_id'=>$storeId,
                    ':qty_out'=>$line['qty'],
                    ':unit_cost'=>$line['unit_cost'],
                    ':total_cost'=>round($line['qty'] * $line['unit_cost'],4),
                    ':reference_id'=>$returnId,
                    ':notes'=>'Supplier return ' . $returnNo . ($creditNoteNo !== '' ? ' / Credit Note ' . $creditNoteNo : ''),
                    ':movement_date'=>date('Y-m-d H:i:s', strtotime($returnDate . ' ' . date('H:i:s'))),
                ]);
            }

            $pdo->commit();

            grtn_flash('success', 'Goods Returned Note posted successfully: ' . $returnNo);
            header('Location: goods_return_note.php?view_id=' . $returnId);
            exit;
        }

        if ($action === 'void_return') {
            $returnId = (int)($_POST['return_id'] ?? 0);
            $reason = trim((string)($_POST['void_reason'] ?? ''));
            if ($returnId <= 0) throw new RuntimeException('Invalid return selected.');
            if ($reason === '') throw new RuntimeException('Void reason is required.');

            $stmt = $pdo->prepare("SELECT * FROM inventory_supplier_returns WHERE id=:id LIMIT 1");
            $stmt->execute([':id'=>$returnId]);
            $return = $stmt->fetch(PDO::FETCH_ASSOC);
            if (!$return) throw new RuntimeException('Goods Returned Note not found.');
            if ($return['status'] === 'void') throw new RuntimeException('This return is already void.');

            $stmt = $pdo->prepare("
                SELECT srl.*, ii.item_name
                FROM inventory_supplier_return_lines srl
                INNER JOIN inventory_items ii ON ii.id=srl.item_id
                WHERE srl.return_id=:return_id
            ");
            $stmt->execute([':return_id'=>$returnId]);
            $lines = $stmt->fetchAll(PDO::FETCH_ASSOC);

            $pdo->beginTransaction();

            $reverseStmt = $pdo->prepare("
                INSERT INTO stock_movements
                (item_id,store_id,movement_type,qty_in,qty_out,unit_cost,total_cost,
                 reference_type,reference_id,notes,movement_date)
                VALUES
                (:item_id,:store_id,'RETURN',:qty_in,0,:unit_cost,:total_cost,
                 'SUPPLIER_RETURN_VOID',:reference_id,:notes,NOW())
            ");

            foreach ($lines as $line) {
                $reverseStmt->execute([
                    ':item_id'=>(int)$line['item_id'],
                    ':store_id'=>(int)$return['store_id'],
                    ':qty_in'=>(float)$line['qty'],
                    ':unit_cost'=>(float)$line['unit_cost'],
                    ':total_cost'=>round((float)$line['qty'] * (float)$line['unit_cost'],4),
                    ':reference_id'=>$returnId,
                    ':notes'=>'Void supplier return ' . $return['return_no'] . ': ' . $reason,
                ]);
            }

            $stmt = $pdo->prepare("
                UPDATE inventory_supplier_returns
                SET status='void', void_reason=:reason, voided_at=NOW()
                WHERE id=:id
            ");
            $stmt->execute([':reason'=>$reason, ':id'=>$returnId]);

            $pdo->commit();

            grtn_flash('success', 'Goods Returned Note voided and stock restored.');
            header('Location: goods_return_note.php?view_id=' . $returnId);
            exit;
        }

    } catch (Throwable $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        $errors[] = $e->getMessage();
    }
}

$suppliers = [];
$stores = [];
$items = [];
$taxes = [];
$grns = [];
$returns = [];
$viewReturn = null;
$viewLines = [];

try {
    $suppliers = $pdo->query("
        SELECT id,supplier_name
        FROM inventory_suppliers
        WHERE is_active=1
        ORDER BY supplier_name
    ")->fetchAll(PDO::FETCH_ASSOC);

    $stores = $pdo->query("
        SELECT id,location_name
        FROM store_locations
        WHERE is_active=1
        ORDER BY location_name
    ")->fetchAll(PDO::FETCH_ASSOC);

    $items = $pdo->query("
        SELECT ii.id,ii.item_code,ii.item_name,ii.cost_price,ii.avg_cost,
               COALESCE(iu.unit_code,'') unit_code
        FROM inventory_items ii
        LEFT JOIN inventory_units iu ON iu.id=ii.unit_id
        WHERE ii.is_active=1 AND ii.is_stock_item=1
        ORDER BY ii.item_name
    ")->fetchAll(PDO::FETCH_ASSOC);

    $taxes = $pdo->query("
        SELECT id,name,code,type,rate
        FROM taxes
        ORDER BY name,code
    ")->fetchAll(PDO::FETCH_ASSOC);

    $grns = $pdo->query("
        SELECT g.id,g.grn_no,g.supplier_id,g.supplier_name,g.store_id,g.invoice_no,g.grn_date,g.total_amount
        FROM inventory_grns g
        WHERE g.status='posted'
        ORDER BY g.id DESC
        LIMIT 500
    ")->fetchAll(PDO::FETCH_ASSOC);

    $returns = $pdo->query("
        SELECT sr.*, sl.location_name
        FROM inventory_supplier_returns sr
        LEFT JOIN store_locations sl ON sl.id=sr.store_id
        ORDER BY sr.id DESC
        LIMIT 500
    ")->fetchAll(PDO::FETCH_ASSOC);

    $viewId = (int)($_GET['view_id'] ?? 0);
    if ($viewId > 0) {
        $stmt = $pdo->prepare("
            SELECT sr.*, sl.location_name
            FROM inventory_supplier_returns sr
            LEFT JOIN store_locations sl ON sl.id=sr.store_id
            WHERE sr.id=:id LIMIT 1
        ");
        $stmt->execute([':id'=>$viewId]);
        $viewReturn = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;

        if ($viewReturn) {
            $stmt = $pdo->prepare("
                SELECT srl.*,ii.item_code,ii.item_name,iu.unit_code
                FROM inventory_supplier_return_lines srl
                INNER JOIN inventory_items ii ON ii.id=srl.item_id
                LEFT JOIN inventory_units iu ON iu.id=ii.unit_id
                WHERE srl.return_id=:return_id
                ORDER BY srl.id
            ");
            $stmt->execute([':return_id'=>$viewId]);
            $viewLines = $stmt->fetchAll(PDO::FETCH_ASSOC);
        }
    }
} catch (Throwable $e) {
    $errors[] = 'Could not load supplier return data: ' . $e->getMessage();
}

$flash = grtn_get_flash();

require_once __DIR__ . '/../../includes/header.php';
?>

<style>
:root{
    --grtn-bg:#f5f7fb;
    --grtn-card:#fff;
    --grtn-border:#e3e8ef;
    --grtn-text:#152033;
    --grtn-muted:#667085;
    --grtn-primary:#0d6efd;
    --grtn-danger:#dc3545;
    --grtn-success:#159455;
}
body{background:var(--grtn-bg)}
.grtn-page{width:100%;max-width:none;padding:18px 22px 30px}
.grtn-toolbar{display:flex;align-items:center;justify-content:space-between;gap:15px;margin-bottom:16px}
.grtn-toolbar h4{margin:0;font-weight:760;color:var(--grtn-text)}
.grtn-toolbar .sub{font-size:13px;color:var(--grtn-muted);margin-top:3px}
.grtn-card{background:#fff;border:1px solid var(--grtn-border);border-radius:15px;box-shadow:0 2px 5px rgba(16,24,40,.035)}
.grtn-history-card{overflow:hidden}
.grtn-history-head{display:flex;align-items:center;justify-content:space-between;padding:16px 18px;border-bottom:1px solid var(--grtn-border)}
.grtn-history-head h5{font-size:16px;font-weight:750;margin:0}
.grtn-history-scroll{max-height:calc(100vh - 270px);overflow:auto}
.grtn-table{margin:0;min-width:1050px}
.grtn-table th{position:sticky;top:0;z-index:3;background:#f8fafc!important;color:#475467;font-size:11px;text-transform:uppercase;letter-spacing:.04em;border-bottom:1px solid var(--grtn-border)!important;padding:12px 14px}
.grtn-table td{font-size:13px;color:#25324a;padding:12px 14px;vertical-align:middle;border-color:#edf0f4}
.grtn-table tr:hover td{background:#fbfdff}
.status-pill{display:inline-flex;align-items:center;padding:4px 9px;border-radius:999px;font-size:11px;font-weight:750;text-transform:uppercase}
.status-posted{background:#eaf8f0;color:#147a45}.status-void{background:#fdecec;color:#b42318}
.grtn-modal{--bs-modal-width:none}
.grtn-dialog{width:calc(100vw - 34px);max-width:none;height:calc(100vh - 34px);margin:17px auto}
.grtn-shell{height:100%;border:0;border-radius:18px;overflow:hidden;background:#f7f9fc;box-shadow:0 30px 90px rgba(2,12,27,.35)}
.grtn-modal-head{height:88px;padding:18px 24px;display:flex;align-items:center;justify-content:space-between;background:#fff;border-bottom:1px solid var(--grtn-border)}
.grtn-title{display:flex;align-items:center;gap:14px}.grtn-title-icon{width:44px;height:44px;border:1px solid #cfe0ff;border-radius:12px;display:grid;place-items:center;color:var(--grtn-primary);background:#f4f8ff;font-size:20px}.grtn-title h4{font-weight:760;margin:0;color:var(--grtn-text)}.grtn-title .small{color:var(--grtn-muted);margin-top:3px}
.grtn-close{width:40px;height:40px;border:0;background:transparent;border-radius:10px}.grtn-close:hover{background:#f2f4f7}
.grtn-modal-body{padding:16px 20px;overflow:hidden;flex:1}
#returnForm{height:100%;display:grid;grid-template-columns:minmax(0,1fr) 275px;grid-template-rows:auto minmax(0,1fr) auto;gap:14px}
.grtn-details{grid-column:1/-1;padding:18px}.grtn-details-grid{display:grid;grid-template-columns:1.2fr 1.2fr 1fr .9fr 1fr;gap:14px}.grtn-field label,.grtn-lines label{font-size:12px;font-weight:700;color:#344054;margin-bottom:6px}.grtn-field .form-control,.grtn-field .form-select{height:44px;border-radius:9px;border-color:#d8dee8;font-size:13px}
.grtn-notes-grid{display:grid;grid-template-columns:1fr 1.5fr;gap:14px;margin-top:14px}.grtn-notes-grid textarea{min-height:52px;resize:none;border-radius:9px}
.grtn-lines{grid-column:1;min-height:0;padding:16px;display:flex;flex-direction:column}.grtn-lines-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}.grtn-lines-head h5{font-size:16px;font-weight:750;margin:0}.grtn-lines-scroll{min-height:0;overflow:auto;border:1px solid var(--grtn-border);border-radius:10px;background:#fff}
.grtn-line{min-width:1260px;display:grid;grid-template-columns:minmax(300px,2fr) 100px 110px 120px 125px 150px minmax(165px,1fr) 42px;gap:10px;padding:10px;border-bottom:1px solid #edf0f4;align-items:end}.grtn-line:last-child{border-bottom:0}.grtn-line .form-control,.grtn-line .form-select{height:40px;min-height:40px;border-radius:8px;font-size:12px;border-color:#d8dee8}.line-meta{font-size:10px;color:var(--grtn-muted);margin-top:4px}.remove-line{height:38px;width:38px;border-radius:8px}
.grtn-summary{grid-column:2;grid-row:2;align-self:start;overflow:hidden}.grtn-summary h5{font-size:16px;font-weight:750;padding:16px;margin:0}.grtn-summary-row{display:flex;justify-content:space-between;padding:9px 16px;font-size:13px}.grtn-summary-total{margin-top:8px;padding:16px;border-top:1px solid var(--grtn-border);background:#fff5f5;color:#c92a2a;font-size:17px;font-weight:760}
.grtn-footer{grid-column:1/-1;height:72px;padding:13px 16px;display:flex;align-items:center;justify-content:space-between}.grtn-footer .btn{height:44px;border-radius:9px;padding:0 18px;font-size:13px;font-weight:700;display:flex;align-items:center;gap:8px}.post-return-btn{min-width:210px;justify-content:center;background:var(--grtn-danger);border-color:var(--grtn-danger);color:#fff}
.item-search-wrap{position:relative}.native-item-select{display:none!important}.item-search-menu.portal-menu{position:fixed!important;display:none;z-index:250000!important;min-width:460px;max-width:min(760px,calc(100vw - 24px));max-height:420px;overflow:auto;padding:7px;background:#fff;border:1px solid #cfd7e3;border-radius:11px;box-shadow:0 22px 55px rgba(15,23,42,.25)}.item-search-menu.portal-menu.open{display:block!important}.item-option{padding:10px 12px;border-radius:8px;cursor:pointer;font-size:13px}.item-option:hover,.item-option.active{background:#edf4ff;color:#123a70}.item-option small{display:block;color:#667085;margin-top:2px}
.detail-modal .modal-content{border:0;border-radius:16px}.detail-lines{max-height:390px;overflow:auto}
@media(max-width:1200px){.grtn-details-grid{grid-template-columns:1fr 1fr 1fr}.grtn-notes-grid{grid-template-columns:1fr}.grtn-dialog{width:100vw;height:100vh;margin:0}.grtn-shell{border-radius:0}#returnForm{grid-template-columns:1fr}.grtn-details,.grtn-lines,.grtn-summary,.grtn-footer{grid-column:1}.grtn-summary{grid-row:auto}}
@media(max-width:700px){.grtn-page{padding:12px}.grtn-toolbar{align-items:flex-start;flex-direction:column}.grtn-details-grid{grid-template-columns:1fr}.grtn-modal-head{padding:14px}.grtn-title .small{display:none}.grtn-modal-body{padding:10px;overflow:auto}.grtn-footer{height:auto;flex-direction:column;gap:10px}.grtn-footer .btn{width:100%;justify-content:center}}
</style>

<div class="grtn-page">
    <?php foreach ($flash as $f): ?>
        <div class="alert alert-<?= h($f['type']) ?> alert-dismissible fade show">
            <?= h($f['message']) ?>
            <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
        </div>
    <?php endforeach; ?>
    <?php foreach ($errors as $error): ?>
        <div class="alert alert-danger"><?= h($error) ?></div>
    <?php endforeach; ?>

    <div class="grtn-toolbar">
        <div>
            <h4>Goods Returned to Supplier</h4>
            <div class="sub">Create Goods Returned Notes and record supplier credit notes while reducing store stock.</div>
        </div>
        <button type="button" class="btn btn-danger" id="newReturnBtn">
            <i class="bi bi-arrow-return-left me-2"></i>New Goods Return
        </button>
    </div>

    <?php if ($viewReturn): ?>
        <div class="alert alert-light border d-flex justify-content-between align-items-center flex-wrap gap-2">
            <div>
                <strong><?= h($viewReturn['return_no']) ?></strong>
                — <?= h($viewReturn['supplier_name']) ?>
                — <?= h($viewReturn['return_date']) ?>
                — Total <?= money_fmt($viewReturn['total_amount']) ?>
            </div>
            <div class="d-flex gap-2">
                <a class="btn btn-sm btn-outline-primary" target="_blank" href="supplier_credit_note_print.php?id=<?= (int)$viewReturn['id'] ?>">
                    <i class="bi bi-printer me-1"></i>Print
                </a>
                <?php if ($viewReturn['status'] === 'posted'): ?>
                    <button class="btn btn-sm btn-outline-danger" data-bs-toggle="modal" data-bs-target="#voidModal">Void</button>
                <?php endif; ?>
            </div>
        </div>
    <?php endif; ?>

    <div class="grtn-card grtn-history-card">
        <div class="grtn-history-head">
            <h5>Supplier Return History</h5>
            <span class="small text-muted"><?= count($returns) ?> records</span>
        </div>
        <div class="grtn-history-scroll">
            <table class="table grtn-table">
                <thead>
                <tr>
                    <th>Return No</th>
                    <th>Date</th>
                    <th>Supplier</th>
                    <th>Store</th>
                    <th>Original GRN</th>
                    <th>Credit Note</th>
                    <th>Reason</th>
                    <th class="text-end">Total</th>
                    <th>Status</th>
                    <th></th>
                </tr>
                </thead>
                <tbody>
                <?php if (!$returns): ?>
                    <tr><td colspan="10" class="text-center py-5 text-muted">No supplier returns have been posted yet.</td></tr>
                <?php endif; ?>
                <?php foreach ($returns as $row): ?>
                    <tr>
                        <td><strong><?= h($row['return_no']) ?></strong></td>
                        <td><?= h($row['return_date']) ?></td>
                        <td><?= h($row['supplier_name']) ?></td>
                        <td><?= h($row['location_name']) ?></td>
                        <td><?= h($row['original_grn_no'] ?: '—') ?></td>
                        <td><?= h($row['supplier_credit_note_no'] ?: '—') ?></td>
                        <td><?= h($row['reason'] ?: '—') ?></td>
                        <td class="text-end"><strong><?= money_fmt($row['total_amount']) ?></strong></td>
                        <td><span class="status-pill status-<?= h($row['status']) ?>"><?= h($row['status']) ?></span></td>
                        <td class="text-end">
                            <a href="goods_return_note.php?view_id=<?= (int)$row['id'] ?>" class="btn btn-sm btn-outline-secondary">View</a>
                            <a href="supplier_credit_note_print.php?id=<?= (int)$row['id'] ?>" target="_blank" class="btn btn-sm btn-outline-primary">Print</a>
                        </td>
                    </tr>
                <?php endforeach; ?>
                </tbody>
            </table>
        </div>
    </div>
</div>

<div class="modal fade grtn-modal" id="returnModal" tabindex="-1" aria-hidden="true" data-bs-backdrop="static">
    <div class="modal-dialog modal-dialog-centered grtn-dialog">
        <div class="modal-content grtn-shell">
            <div class="grtn-modal-head">
                <div class="grtn-title">
                    <div class="grtn-title-icon"><i class="bi bi-arrow-return-left"></i></div>
                    <div>
                        <h4>Create Goods Returned Note</h4>
                        <div class="small">Return stock to a supplier and record the expected or received supplier credit note.</div>
                    </div>
                </div>
                <button type="button" class="grtn-close" data-bs-dismiss="modal"><i class="bi bi-x-lg"></i></button>
            </div>

            <div class="grtn-modal-body">
                <form method="post" id="returnForm">
                    <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
                    <input type="hidden" name="action" value="post_return">

                    <section class="grtn-card grtn-details">
                        <div class="grtn-details-grid">
                            <div class="grtn-field">
                                <label>Original GRN (optional)</label>
                                <select class="form-select" id="sourceGrn">
                                    <option value="">Manual return / no GRN selected</option>
                                    <?php foreach ($grns as $g): ?>
                                        <option value="<?= (int)$g['id'] ?>"
                                                data-supplier="<?= (int)$g['supplier_id'] ?>"
                                                data-store="<?= (int)$g['store_id'] ?>">
                                            <?= h($g['grn_no'] . ' — ' . ($g['supplier_name'] ?: '') . ' — Invoice ' . ($g['invoice_no'] ?: 'N/A') . ' — ' . $g['grn_date']) ?>
                                        </option>
                                    <?php endforeach; ?>
                                </select>
                                <input type="hidden" name="grn_id" id="grnId" value="">
                            </div>
                            <div class="grtn-field">
                                <label>Supplier</label>
                                <select class="form-select" name="supplier_id" id="supplierId" required>
                                    <option value="">Select supplier</option>
                                    <?php foreach ($suppliers as $s): ?>
                                        <option value="<?= (int)$s['id'] ?>"><?= h($s['supplier_name']) ?></option>
                                    <?php endforeach; ?>
                                </select>
                            </div>
                            <div class="grtn-field">
                                <label>Store</label>
                                <select class="form-select" name="store_id" id="storeId" required>
                                    <option value="">Select store</option>
                                    <?php foreach ($stores as $s): ?>
                                        <option value="<?= (int)$s['id'] ?>"><?= h($s['location_name']) ?></option>
                                    <?php endforeach; ?>
                                </select>
                            </div>
                            <div class="grtn-field">
                                <label>Return Date</label>
                                <input type="date" class="form-control" name="return_date" value="<?= h(date('Y-m-d')) ?>" required>
                            </div>
                            <div class="grtn-field">
                                <label>Supplier Credit Note No.</label>
                                <input type="text" class="form-control" name="supplier_credit_note_no" placeholder="Optional">
                            </div>
                        </div>

                        <div class="grtn-notes-grid">
                            <div class="grtn-field">
                                <label>Return Reason</label>
                                <input type="text" class="form-control" name="reason" placeholder="Damaged, rejected, over-supplied, expired...">
                            </div>
                            <div class="grtn-field">
                                <label>Notes</label>
                                <textarea class="form-control" name="notes" placeholder="Supporting details, supplier contact, transport arrangements..."></textarea>
                            </div>
                        </div>
                    </section>

                    <section class="grtn-card grtn-lines">
                        <div class="grtn-lines-head">
                            <div>
                                <h5>Goods Return Lines</h5>
                                <div class="small text-muted">The system prevents returning more than the store has in stock.</div>
                            </div>
                            <button type="button" class="btn btn-sm btn-outline-primary" id="addLineBtn">
                                <i class="bi bi-plus-lg me-1"></i>Add Line
                            </button>
                        </div>
                        <div class="grtn-lines-scroll" id="lineBox"></div>
                    </section>

                    <aside class="grtn-card grtn-summary">
                        <h5>Supplier Credit Summary</h5>
                        <div class="grtn-summary-row"><span>Subtotal</span><strong id="subtotalText">0.00</strong></div>
                        <div class="grtn-summary-row"><span>Tax</span><strong id="taxText">0.00</strong></div>
                        <div class="grtn-summary-row grtn-summary-total"><span>Credit Total</span><span id="totalText">0.00</span></div>
                    </aside>

                    <footer class="grtn-card grtn-footer">
                        <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">
                            <i class="bi bi-x-lg"></i>Cancel
                        </button>
                        <button type="submit" class="btn post-return-btn">
                            <i class="bi bi-check-circle"></i>Post Goods Return
                        </button>
                    </footer>
                </form>
            </div>
        </div>
    </div>
</div>

<?php if ($viewReturn && $viewReturn['status'] === 'posted'): ?>
<div class="modal fade" id="voidModal" tabindex="-1">
    <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content">
            <form method="post">
                <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
                <input type="hidden" name="action" value="void_return">
                <input type="hidden" name="return_id" value="<?= (int)$viewReturn['id'] ?>">
                <div class="modal-header">
                    <h5 class="modal-title">Void <?= h($viewReturn['return_no']) ?></h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body">
                    <div class="alert alert-warning">Voiding restores the returned quantities to the original store.</div>
                    <label class="form-label">Void reason</label>
                    <textarea class="form-control" name="void_reason" required></textarea>
                </div>
                <div class="modal-footer">
                    <button class="btn btn-light" type="button" data-bs-dismiss="modal">Cancel</button>
                    <button class="btn btn-danger" type="submit">Void and Restore Stock</button>
                </div>
            </form>
        </div>
    </div>
</div>
<?php endif; ?>

<template id="lineTemplate">
    <div class="grtn-line">
        <div>
            <label>Item</label>
            <select class="native-item-select item-select" name="item_id[]" required>
                <option value="">Select item</option>
                <?php foreach ($items as $item): ?>
                    <option value="<?= (int)$item['id'] ?>"
                            data-cost="<?= h((string)(($item['avg_cost'] > 0) ? $item['avg_cost'] : $item['cost_price'])) ?>">
                        <?= h(($item['item_code'] ? $item['item_code'] . ' — ' : '') . $item['item_name'] . ($item['unit_code'] ? ' (' . $item['unit_code'] . ')' : '')) ?>
                    </option>
                <?php endforeach; ?>
            </select>
            <input type="hidden" name="grn_line_id[]" class="grn-line-id" value="">
            <div class="line-meta stock-meta">Select a store and item to check available stock.</div>
        </div>
        <div>
            <label>Return Qty</label>
            <input type="number" step="0.0001" min="0" class="form-control qty-input" name="qty[]" value="1">
        </div>
        <div>
            <label>Unit Price</label>
            <input type="number" step="0.0001" min="0" class="form-control unit-price-input" name="unit_price[]" value="0">
        </div>
        <div>
            <label>Line Amount</label>
            <input type="number" step="0.01" min="0" class="form-control line-amount-input" name="line_amount[]" placeholder="Optional">
        </div>
        <div>
            <label>Tax</label>
            <select class="form-select tax-input" name="tax_id[]">
                <option value="0" data-rate="0" data-type="Percentage">No Tax</option>
                <?php foreach ($taxes as $tax): ?>
                    <option value="<?= (int)$tax['id'] ?>"
                            data-rate="<?= h($tax['rate']) ?>"
                            data-type="<?= h($tax['type']) ?>">
                        <?= h($tax['name'] . ' (' . $tax['rate'] . ($tax['type'] === 'Fixed' ? '' : '%') . ')') ?>
                    </option>
                <?php endforeach; ?>
            </select>
        </div>
        <div>
            <label>Tax Mode</label>
            <select class="form-select tax-mode-input" name="price_tax_mode[]">
                <option value="exclusive">Exclusive</option>
                <option value="inclusive">Inclusive</option>
            </select>
        </div>
        <div>
            <label>Line Reason</label>
            <input type="text" class="form-control" name="line_reason[]" placeholder="Optional">
            <div class="line-meta line-total-meta">Line total: 0.00</div>
        </div>
        <div>
            <button type="button" class="btn btn-outline-danger remove-line" title="Remove line"><i class="bi bi-trash"></i></button>
        </div>
    </div>
</template>

<script>
document.addEventListener('DOMContentLoaded', function(){
    const modalEl = document.getElementById('returnModal');
    const modal = bootstrap.Modal.getOrCreateInstance(modalEl);
    const lineBox = document.getElementById('lineBox');
    const template = document.getElementById('lineTemplate');
    const storeSelect = document.getElementById('storeId');
    const supplierSelect = document.getElementById('supplierId');
    const sourceGrn = document.getElementById('sourceGrn');
    const grnId = document.getElementById('grnId');

    function money(n){ return (Number(n)||0).toFixed(2); }

    function calcLine(row){
        const qty = Number(row.querySelector('.qty-input').value || 0);
        const unit = Number(row.querySelector('.unit-price-input').value || 0);
        const amountRaw = row.querySelector('.line-amount-input').value.trim();
        const gross = amountRaw !== '' ? Number(amountRaw || 0) : qty * unit;
        const taxSelect = row.querySelector('.tax-input');
        const taxOpt = taxSelect.options[taxSelect.selectedIndex];
        const rate = Number(taxOpt.dataset.rate || 0);
        const type = taxOpt.dataset.type === 'Fixed' ? 'Fixed' : 'Percentage';
        const mode = row.querySelector('.tax-mode-input').value;
        let net = gross, tax = 0, total = gross;

        if (rate > 0) {
            if (mode === 'inclusive') {
                tax = type === 'Fixed' ? rate * qty : gross * (rate / (100 + rate));
                net = Math.max(0, gross - tax);
                total = gross;
            } else {
                tax = type === 'Fixed' ? rate * qty : gross * (rate / 100);
                total = gross + tax;
            }
        }
        row.dataset.net = net.toFixed(2);
        row.dataset.tax = tax.toFixed(2);
        row.dataset.total = total.toFixed(2);
        row.querySelector('.line-total-meta').textContent = 'Line total: ' + money(total);
    }

    function recalc(){
        let subtotal=0,tax=0,total=0;
        lineBox.querySelectorAll('.grtn-line').forEach(row=>{
            calcLine(row);
            subtotal += Number(row.dataset.net || 0);
            tax += Number(row.dataset.tax || 0);
            total += Number(row.dataset.total || 0);
        });
        document.getElementById('subtotalText').textContent = money(subtotal);
        document.getElementById('taxText').textContent = money(tax);
        document.getElementById('totalText').textContent = money(total);
    }

    async function updateStockMeta(row){
        const itemId = Number(row.querySelector('.item-select').value || 0);
        const storeId = Number(storeSelect.value || 0);
        const meta = row.querySelector('.stock-meta');
        if (!itemId || !storeId) {
            meta.textContent = 'Select a store and item to check available stock.';
            return;
        }
        meta.textContent = 'Available stock will be validated when posting.';
    }

    function positionMenu(input, menu){
        const rect = input.getBoundingClientRect();
        const gap = 10;
        const width = Math.min(Math.max(rect.width, 520), window.innerWidth - gap*2);
        let left = Math.max(gap, rect.left);
        if (left + width > window.innerWidth - gap) left = window.innerWidth - gap - width;
        const below = window.innerHeight - rect.bottom - gap;
        const above = rect.top - gap;
        const openAbove = below < 220 && above > below;
        menu.style.width = width + 'px';
        menu.style.left = left + 'px';
        menu.style.maxHeight = Math.max(160, Math.min(420, openAbove ? above-6 : below-6)) + 'px';
        if (openAbove) {
            menu.style.top = 'auto';
            menu.style.bottom = (window.innerHeight - rect.top + 5) + 'px';
        } else {
            menu.style.bottom = 'auto';
            menu.style.top = (rect.bottom + 5) + 'px';
        }
    }

    function initItemSearch(row){
        const select = row.querySelector('.item-select');
        if (!select || select.dataset.ready === '1') return;
        select.dataset.ready = '1';

        const wrap = document.createElement('div');
        wrap.className = 'item-search-wrap';
        const input = document.createElement('input');
        input.type = 'text';
        input.className = 'form-control item-search-input';
        input.placeholder = 'Type item name or code...';
        input.autocomplete = 'off';
        const menu = document.createElement('div');
        menu.className = 'item-search-menu portal-menu';
        document.body.appendChild(menu);

        select.parentNode.insertBefore(wrap, select);
        wrap.appendChild(input);
        wrap.appendChild(select);

        function close(){ menu.classList.remove('open'); }
        function render(term){
            const q = String(term||'').trim().toLowerCase();
            const matches = Array.from(select.options)
                .filter(o=>o.value && o.textContent.toLowerCase().includes(q))
                .slice(0,100);
            menu.innerHTML = '';
            if (!matches.length) {
                menu.innerHTML = '<div class="p-3 text-muted">No matching items found</div>';
                return;
            }
            matches.forEach((opt,idx)=>{
                const div = document.createElement('div');
                div.className = 'item-option' + (idx===0?' active':'');
                div.innerHTML = '<div>'+opt.textContent.trim()+'</div><small>Current cost: '+Number(opt.dataset.cost||0).toFixed(4)+'</small>';
                div.addEventListener('mousedown',function(e){
                    e.preventDefault();
                    select.value = opt.value;
                    input.value = opt.textContent.trim();
                    row.querySelector('.unit-price-input').value = Number(opt.dataset.cost||0).toFixed(4);
                    close();
                    updateStockMeta(row);
                    recalc();
                });
                menu.appendChild(div);
            });
        }
        function open(){
            render(input.value);
            positionMenu(input,menu);
            menu.classList.add('open');
        }
        input.addEventListener('focus',open);
        input.addEventListener('click',open);
        input.addEventListener('input',function(){
            select.value='';
            render(input.value);
            positionMenu(input,menu);
            menu.classList.add('open');
            recalc();
        });
        input.addEventListener('keydown',function(e){
            const opts=Array.from(menu.querySelectorAll('.item-option'));
            let ix=opts.findIndex(o=>o.classList.contains('active'));
            if(e.key==='Escape'){close();return;}
            if(!opts.length)return;
            if(e.key==='ArrowDown'||e.key==='ArrowUp'){
                e.preventDefault();
                opts[ix]?.classList.remove('active');
                ix=e.key==='ArrowDown'?(ix>=opts.length-1?0:ix+1):(ix<=0?opts.length-1:ix-1);
                opts[ix].classList.add('active'); opts[ix].scrollIntoView({block:'nearest'});
            } else if(e.key==='Enter'){
                e.preventDefault();
                (opts[ix>=0?ix:0]).dispatchEvent(new MouseEvent('mousedown',{bubbles:true}));
            }
        });
        document.addEventListener('mousedown',e=>{ if(!wrap.contains(e.target)&&!menu.contains(e.target)) close(); });
        document.addEventListener('scroll',()=>{ if(menu.classList.contains('open')) positionMenu(input,menu); },true);
        window.addEventListener('resize',()=>{ if(menu.classList.contains('open')) positionMenu(input,menu); });
        modalEl.addEventListener('hidden.bs.modal',close);
    }

    function addLine(data){
        const node = template.content.cloneNode(true);
        const row = node.querySelector('.grtn-line');
        lineBox.appendChild(node);
        const actual = lineBox.lastElementChild;
        initItemSearch(actual);

        actual.querySelectorAll('input,select').forEach(el=>{
            el.addEventListener('input',recalc);
            el.addEventListener('change',function(){ recalc(); updateStockMeta(actual); });
        });
        actual.querySelector('.remove-line').addEventListener('click',function(){
            actual.remove();
            if (!lineBox.querySelector('.grtn-line')) addLine();
            recalc();
        });

        if (data) {
            const select = actual.querySelector('.item-select');
            select.value = String(data.item_id || '');
            const opt = select.options[select.selectedIndex];
            const input = actual.querySelector('.item-search-input');
            input.value = opt ? opt.textContent.trim() : '';
            actual.querySelector('.grn-line-id').value = data.grn_line_id || '';
            actual.querySelector('.qty-input').value = data.remaining_from_grn > 0 ? data.remaining_from_grn : 0;
            actual.querySelector('.unit-price-input').value = Number(data.unit_price_entered || data.unit_cost || 0).toFixed(4);
            actual.querySelector('.tax-input').value = String(data.tax_id || 0);
            actual.querySelector('.tax-mode-input').value = data.price_tax_mode || 'exclusive';
            actual.querySelector('.stock-meta').textContent =
                'Available in store: ' + Number(data.available_qty||0).toFixed(4) +
                ' · Remaining from GRN: ' + Number(data.remaining_from_grn||0).toFixed(4);
        }
        recalc();
    }

    document.getElementById('addLineBtn').addEventListener('click',()=>addLine());
    document.getElementById('newReturnBtn').addEventListener('click',function(){
        modal.show();
        if (!lineBox.querySelector('.grtn-line')) addLine();
    });

    sourceGrn.addEventListener('change',async function(){
        const id = Number(this.value || 0);
        grnId.value = id ? String(id) : '';
        if (!id) return;

        const res = await fetch('goods_return_note.php?ajax=load_grn&grn_id=' + encodeURIComponent(id));
        const data = await res.json();
        if (!data.ok) {
            alert(data.error || 'Could not load GRN.');
            return;
        }

        supplierSelect.value = String(data.grn.supplier_id || '');
        storeSelect.value = String(data.grn.store_id || '');
        supplierSelect.disabled = true;
        storeSelect.disabled = true;

        /* disabled fields are not submitted; mirror them with hidden fields */
        document.querySelectorAll('.locked-field-mirror').forEach(el=>el.remove());
        [supplierSelect,storeSelect].forEach(el=>{
            const hidden=document.createElement('input');
            hidden.type='hidden'; hidden.name=el.name; hidden.value=el.value; hidden.className='locked-field-mirror';
            el.parentNode.appendChild(hidden);
        });

        lineBox.innerHTML = '';
        data.lines.filter(l=>Number(l.remaining_from_grn)>0).forEach(addLine);
        if (!lineBox.querySelector('.grtn-line')) {
            addLine();
            alert('All quantities from this GRN have already been returned.');
        }
        recalc();
    });

    sourceGrn.addEventListener('change',function(){
        if (!this.value) {
            supplierSelect.disabled=false;
            storeSelect.disabled=false;
            document.querySelectorAll('.locked-field-mirror').forEach(el=>el.remove());
        }
    });

    storeSelect.addEventListener('change',function(){
        lineBox.querySelectorAll('.grtn-line').forEach(updateStockMeta);
    });

    document.getElementById('returnForm').addEventListener('submit',function(e){
        if (!lineBox.querySelector('.grtn-line')) {
            e.preventDefault();
            alert('Please add at least one goods return line.');
        }
    });

    addLine();

    <?php if (isset($_GET['grn_id']) && (int)$_GET['grn_id'] > 0): ?>
    sourceGrn.value = <?= json_encode((string)(int)$_GET['grn_id']) ?>;
    modal.show();
    sourceGrn.dispatchEvent(new Event('change'));
    <?php endif; ?>
});
</script>

<?php require_once __DIR__ . '/../../includes/footer.php'; ?>
