<?php
/**
 * api/pawn/pledge_locker_move.php
 *
 * Purpose:
 *   SHOWROOM pledge কে LOCKER-এ পাঠানো।
 *
 * Polish:
 *   User-facing note/audit language বাংলায় সুন্দর করা হয়েছে।
 *
 * Main Actions:
 *   1) pawn_pledges UPDATE → holding_status = LOCKER
 *   2) cash_transactions INSERT → লকার থেকে টাকা IN
 *   3) locker_pledge_moves INSERT → locker move history
 *   4) audit_log INSERT
 */

ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
error_reporting(E_ALL);

header('Content-Type: application/json; charset=utf-8');

require_once __DIR__ . '/../../config/db.php';
require_once __DIR__ . '/../../config/session.php';

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

function lm_send($status, $success, $message, $data = null)
{
    http_response_code((int)$status);
    echo json_encode([
        'status'  => (int)$status,
        'success' => (bool)$success,
        'message' => $message,
        'data'    => $data
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

function lm_table_exists(PDO $pdo, string $table): bool
{
    try {
        $stmt = $pdo->prepare("
            SELECT COUNT(*)
            FROM information_schema.tables
            WHERE table_schema = DATABASE()
              AND table_name = ?
        ");
        $stmt->execute([$table]);
        return (int)$stmt->fetchColumn() > 0;
    } catch (Throwable $e) {
        return false;
    }
}

function lm_column_exists(PDO $pdo, string $table, string $column): bool
{
    try {
        $stmt = $pdo->prepare("
            SELECT COUNT(*)
            FROM information_schema.columns
            WHERE table_schema = DATABASE()
              AND table_name = ?
              AND column_name = ?
        ");
        $stmt->execute([$table, $column]);
        return (int)$stmt->fetchColumn() > 0;
    } catch (Throwable $e) {
        return false;
    }
}

function lm_safe_audit_log(PDO $pdo, string $tableName, int $recordId, string $action, int $changedBy, string $note = ''): void
{
    try {
        $stmt = $pdo->prepare("
            INSERT INTO audit_log
                (table_name, record_id, action, changed_by, changed_at, ip_address, note)
            VALUES
                (:table_name, :record_id, :action, :changed_by, NOW(), :ip_address, :note)
        ");

        $stmt->execute([
            ':table_name' => $tableName,
            ':record_id'  => $recordId,
            ':action'     => $action,
            ':changed_by' => $changedBy,
            ':ip_address' => $_SERVER['REMOTE_ADDR'] ?? '',
            ':note'       => $note
        ]);
    } catch (Throwable $e) {
        return;
    }
}

function lm_make_voucher(PDO $pdo): string
{
    $prefix = 'CV-' . date('Ym') . '-';

    $stmt = $pdo->prepare("
        SELECT COUNT(*)
        FROM cash_transactions
        WHERE voucher_no LIKE ?
    ");
    $stmt->execute([$prefix . '%']);

    $count = (int)$stmt->fetchColumn();

    return $prefix . str_pad($count + 1, 4, '0', STR_PAD_LEFT);
}

function lm_get_cash_category_id(PDO $pdo): int
{
    $codes = [
        'LOCKER_INVESTMENT_RECEIVE',
        'LOCKER_RECEIVE',
        'LOCKER_CASH_RECEIVE',
        'PLEDGE_INTEREST'
    ];

    foreach ($codes as $code) {
        try {
            $stmt = $pdo->prepare("
                SELECT id
                FROM cash_categories
                WHERE category_code = ?
                  AND direction = 'IN'
                  AND is_active = 1
                LIMIT 1
            ");
            $stmt->execute([$code]);

            $id = (int)($stmt->fetchColumn() ?: 0);

            if ($id > 0) {
                return $id;
            }
        } catch (Throwable $e) {
            continue;
        }
    }

    return 4;
}

if (empty($_SESSION['user_id'])) {
    lm_send(401, false, 'লগইন প্রয়োজন');
}

$userId = (int)($_SESSION['user_id'] ?? 1);

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    lm_send(405, false, 'শুধু POST অনুরোধ গ্রহণযোগ্য');
}

$raw  = file_get_contents('php://input');
$data = json_decode($raw, true);

if (!is_array($data)) {
    $data = $_POST;
}

if (!is_array($data)) {
    lm_send(400, false, 'Invalid request data');
}

$pledge_id       = (int)($data['pledge_id'] ?? 0);
$locker_id       = (int)($data['locker_id'] ?? 0);
$move_date       = trim((string)($data['move_date'] ?? date('Y-m-d')));
$cash_account_id = (int)($data['cash_account_id'] ?? 0);

$locker_amount = 0;
if (isset($data['locker_amount'])) {
    $locker_amount = round((float)$data['locker_amount'], 2);
} elseif (isset($data['locker_value'])) {
    $locker_amount = round((float)$data['locker_value'], 2);
}

$customer_rate = round((float)($data['customer_rate'] ?? 0), 2);
$locker_rate   = round((float)($data['locker_rate'] ?? 0), 2);
$note          = trim((string)($data['note'] ?? ''));

if ($pledge_id <= 0) {
    lm_send(400, false, 'Pledge ID দিন');
}

if ($locker_id <= 0) {
    lm_send(400, false, 'লকার select করুন');
}

if ($move_date === '') {
    lm_send(400, false, 'মুভ তারিখ দিন');
}

if ($cash_account_id <= 0) {
    lm_send(400, false, 'Cash account select করুন');
}

if ($locker_amount <= 0) {
    lm_send(400, false, 'লকার থেকে আসা টাকা দিন');
}

try {
    if (!lm_table_exists($pdo, 'pawn_pledges')) {
        lm_send(500, false, 'pawn_pledges table পাওয়া যায়নি');
    }

    if (!lm_table_exists($pdo, 'cash_transactions')) {
        lm_send(500, false, 'cash_transactions table পাওয়া যায়নি');
    }

    if (!lm_table_exists($pdo, 'cash_accounts')) {
        lm_send(500, false, 'cash_accounts table পাওয়া যায়নি');
    }

    $pdo->beginTransaction();

    $stmt = $pdo->prepare("
        SELECT 
            p.*,
            COALESCE(pa.name, '') AS party_name,
            COALESCE(pa.phone, '') AS party_phone
        FROM pawn_pledges p
        LEFT JOIN parties pa ON pa.id = p.party_id
        WHERE p.id = ?
        LIMIT 1
        FOR UPDATE
    ");
    $stmt->execute([$pledge_id]);
    $pledge = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$pledge) {
        throw new Exception('Pledge পাওয়া যায়নি');
    }

    $pledgeCode = (string)($pledge['pledge_code'] ?? '');
    $partyName  = (string)($pledge['party_name'] ?? '');
    $partyId    = (int)($pledge['party_id'] ?? 0);
    $loanAmount = round((float)($pledge['loan_amount'] ?? 0), 2);
    $oldHolding = strtoupper((string)($pledge['holding_status'] ?? 'SHOWROOM'));
    $oldStatus  = strtoupper((string)($pledge['status'] ?? 'OPEN'));

    if ($oldStatus === 'CLOSED') {
        throw new Exception('Closed pledge লকারে পাঠানো যাবে না');
    }

    if ($oldHolding === 'LOCKER') {
        throw new Exception('এই pledge আগেই LOCKER-এ আছে');
    }

    if (!lm_table_exists($pdo, 'lockers')) {
        throw new Exception('lockers table পাওয়া যায়নি');
    }

    $lockerStmt = $pdo->prepare("
        SELECT *
        FROM lockers
        WHERE id = ?
        LIMIT 1
    ");
    $lockerStmt->execute([$locker_id]);
    $locker = $lockerStmt->fetch(PDO::FETCH_ASSOC);

    if (!$locker) {
        throw new Exception('লকার পাওয়া যায়নি');
    }

    if (isset($locker['is_active']) && (int)$locker['is_active'] !== 1) {
        throw new Exception('এই লকার active নয়');
    }

    $lockerName = (string)(
        $locker['name']
        ?? $locker['locker_name']
        ?? $locker['party_name']
        ?? ('Locker #' . $locker_id)
    );

    $lockerPartyId = 0;
    if (isset($locker['party_id'])) {
        $lockerPartyId = (int)$locker['party_id'];
    }

    $caStmt = $pdo->prepare("
        SELECT id, account_name, current_balance
        FROM cash_accounts
        WHERE id = ?
          AND is_active = 1
        LIMIT 1
    ");
    $caStmt->execute([$cash_account_id]);
    $cashAccount = $caStmt->fetch(PDO::FETCH_ASSOC);

    if (!$cashAccount) {
        throw new Exception('Cash account পাওয়া যায়নি বা inactive');
    }

    $rentDiffRate = round(max(0, $customer_rate - $locker_rate), 2);
    $monthlyDiff  = round($loanAmount * ($rentDiffRate / 100), 2);

    /**
     * সুন্দর Bangla note
     */
    $moveNote = 'লকারে পাঠানো হয়েছে'
        . ' | তারিখ: ' . $move_date
        . ' | লকার: ' . $lockerName . ' (#' . $locker_id . ')'
        . ' | লকার থেকে আসা টাকা: ৳' . number_format($locker_amount, 2)
        . ' | গ্রাহকের ভাড়ার হার: ' . number_format($customer_rate, 2) . '%'
        . ' | লকার ভাড়ার হার: ' . number_format($locker_rate, 2) . '%'
        . ' | ভাড়ার পার্থক্য হার: ' . number_format($rentDiffRate, 2) . '%'
        . ' | প্রতি মাসে ভাড়ার পার্থক্য: ৳' . number_format($monthlyDiff, 2);

    if ($note !== '') {
        $moveNote .= ' | নোট: ' . $note;
    }

    $updateParts = [];
    $params = [];

    $updateParts[] = "holding_status = 'LOCKER'";
    $updateParts[] = "locker_id = ?";
    $params[] = $locker_id;

    if (lm_column_exists($pdo, 'pawn_pledges', 'location_note')) {
        $updateParts[] = "location_note = ?";
        $params[] = $lockerName;
    }

    if (lm_column_exists($pdo, 'pawn_pledges', 'locker_value')) {
        $updateParts[] = "locker_value = ?";
        $params[] = $locker_amount;
    }

    if (lm_column_exists($pdo, 'pawn_pledges', 'locker_rate')) {
        $updateParts[] = "locker_rate = ?";
        $params[] = $locker_rate;
    }

    if (lm_column_exists($pdo, 'pawn_pledges', 'updated_at')) {
        $updateParts[] = "updated_at = NOW()";
    }

    if (lm_column_exists($pdo, 'pawn_pledges', 'note')) {
        $updateParts[] = "note = CONCAT(IFNULL(note, ''), ' | ', ?)";
        $params[] = $moveNote;
    }

    $params[] = $pledge_id;

    $upd = $pdo->prepare("
        UPDATE pawn_pledges
        SET " . implode(', ', $updateParts) . "
        WHERE id = ?
    ");
    $upd->execute($params);

    $categoryId = lm_get_cash_category_id($pdo);
    $voucherNo  = lm_make_voucher($pdo);

    $cashNote = 'লকার থেকে টাকা গ্রহণ'
        . ' | ' . $pledgeCode
        . ' | গ্রাহক: ' . $partyName
        . ' | লকার: ' . $lockerName;

    if ($note !== '') {
        $cashNote .= ' | ' . $note;
    }

    $cashStmt = $pdo->prepare("
        INSERT INTO cash_transactions
            (
                voucher_no,
                transaction_date,
                cash_account_id,
                category_id,
                direction,
                amount,
                note,
                reference_type,
                reference_id,
                party_id,
                pledge_id,
                created_by,
                created_ip,
                created_at
            )
        VALUES
            (?, ?, ?, ?, 'IN', ?, ?, 'LOCKER_MOVE', ?, ?, ?, ?, ?, NOW())
    ");

    $cashStmt->execute([
        $voucherNo,
        $move_date,
        $cash_account_id,
        $categoryId,
        $locker_amount,
        $cashNote,
        $pledge_id,
        $lockerPartyId > 0 ? $lockerPartyId : $partyId,
        $pledge_id,
        $userId,
        $_SERVER['REMOTE_ADDR'] ?? ''
    ]);

    $cashTxnId = (int)$pdo->lastInsertId();

    $balUpd = $pdo->prepare("
        UPDATE cash_accounts
        SET current_balance = current_balance + ?
        WHERE id = ?
    ");
    $balUpd->execute([
        $locker_amount,
        $cash_account_id
    ]);

    $lockerMoveId = 0;

    if (lm_table_exists($pdo, 'locker_pledge_moves')) {
        $cols = [];
        $ph   = [];
        $vals = [];

        $addCol = function($col, $val) use (&$cols, &$ph, &$vals, $pdo) {
            if (lm_column_exists($pdo, 'locker_pledge_moves', $col)) {
                $cols[] = $col;
                $ph[]   = '?';
                $vals[] = $val;
            }
        };

        $addCol('pledge_id', $pledge_id);
        $addCol('locker_id', $locker_id);
        $addCol('party_id', $partyId);
        $addCol('locker_party_id', $lockerPartyId);
        $addCol('move_date', $move_date);
        $addCol('locker_amount', $locker_amount);
        $addCol('loan_amount', $loanAmount);
        $addCol('customer_rate', $customer_rate);
        $addCol('locker_rate', $locker_rate);
        $addCol('profit_rate', $rentDiffRate);
        $addCol('monthly_profit', $monthlyDiff);
        $addCol('cash_account_id', $cash_account_id);
        $addCol('cash_transaction_id', $cashTxnId);
        $addCol('status', 'active');
        $addCol('note', $moveNote);
        $addCol('created_by', $userId);

        if (lm_column_exists($pdo, 'locker_pledge_moves', 'created_at')) {
            $cols[] = 'created_at';
            $ph[]   = 'NOW()';
        }

        if (!empty($cols)) {
            $sql = "
                INSERT INTO locker_pledge_moves
                    (" . implode(', ', $cols) . ")
                VALUES
                    (" . implode(', ', $ph) . ")
            ";

            $lmIns = $pdo->prepare($sql);
            $lmIns->execute($vals);
            $lockerMoveId = (int)$pdo->lastInsertId();
        }
    }

    lm_safe_audit_log(
        $pdo,
        'pawn_pledges',
        $pledge_id,
        'UPDATE',
        $userId,
        'বন্ধক লকারে পাঠানো হয়েছে'
        . ' | বন্ধক: ' . $pledgeCode
        . ' | আগের অবস্থা: ' . $oldHolding
        . ' | নতুন অবস্থা: LOCKER'
        . ' | লকার: ' . $lockerName . ' (#' . $locker_id . ')'
        . ' | লকার থেকে আসা টাকা: ৳' . number_format($locker_amount, 2)
    );

    lm_safe_audit_log(
        $pdo,
        'cash_transactions',
        $cashTxnId,
        'INSERT',
        $userId,
        'লকার থেকে cash গ্রহণ'
        . ' | বন্ধক: ' . $pledgeCode
        . ' | Voucher: ' . $voucherNo
        . ' | Amount: ৳' . number_format($locker_amount, 2)
        . ' | Cash Account: ' . ($cashAccount['account_name'] ?? '') . ' (#' . $cash_account_id . ')'
    );

    if ($lockerMoveId > 0) {
        lm_safe_audit_log(
            $pdo,
            'locker_pledge_moves',
            $lockerMoveId,
            'INSERT',
            $userId,
            'লকার move history তৈরি হয়েছে'
            . ' | বন্ধক: ' . $pledgeCode
            . ' | লকার: ' . $lockerName . ' (#' . $locker_id . ')'
            . ' | লকার থেকে আসা টাকা: ৳' . number_format($locker_amount, 2)
            . ' | ভাড়ার পার্থক্য হার: ' . number_format($rentDiffRate, 2) . '%'
            . ' | প্রতি মাসে পার্থক্য: ৳' . number_format($monthlyDiff, 2)
        );
    }

    $pdo->commit();

    echo json_encode([
        'status'  => 200,
        'success' => true,
        'message' => 'লকারে সফলভাবে পাঠানো হয়েছে',
        'data' => [
            'pledge_id'             => $pledge_id,
            'pledge_code'           => $pledgeCode,
            'holding_status'        => 'LOCKER',
            'locker_id'             => $locker_id,
            'locker_name'           => $lockerName,
            'locker_amount'         => $locker_amount,
            'cash_transaction_id'   => $cashTxnId,
            'locker_move_id'        => $lockerMoveId,
            'voucher_no'            => $voucherNo,
            'customer_rate'         => $customer_rate,
            'locker_rate'           => $locker_rate,
            'rent_difference_rate'  => $rentDiffRate,
            'monthly_difference'    => $monthlyDiff
        ]
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

} catch (Throwable $e) {
    if (isset($pdo) && $pdo instanceof PDO && $pdo->inTransaction()) {
        $pdo->rollBack();
    }

    echo json_encode([
        'status'  => 500,
        'success' => false,
        'message' => 'সার্ভার সমস্যা: ' . $e->getMessage()
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}