<?php
session_start();

require(realpath(__DIR__ . '/../../../services/Model.php'));
$obj = new Model();
$db = $obj->getConnection();

$userid = isset($_SESSION['userid']) ? $_SESSION['userid'] : null;

function customerReturnResponse($success, $status, $extra = [])
{
    echo json_encode(array_merge(['success' => $success, 'status' => $status], $extra));
    exit;
}

function normalizeCustomerReturnModels($modelIds)
{
    if (!is_array($modelIds)) {
        return [];
    }

    $normalized = [];
    foreach ($modelIds as $modelId) {
        $modelId = (int)$modelId;
        if ($modelId > 0) {
            $normalized[$modelId] = $modelId;
        }
    }

    return array_values($normalized);
}

$wherecond = '1=1';

if (isset($_GET['customer']) && $_GET['customer'] !== '') {
    $customer = (int)$_GET['customer'];
    $wherecond .= " AND customer_return.customer_id = $customer";
}

if (isset($_GET['product']) && $_GET['product'] !== '') {
    $product = (int)$_GET['product'];
    $wherecond .= " AND customer_return.product_id = $product";
}

if (isset($_GET['batch']) && $_GET['batch'] !== '') {
    $batch = trim($_GET['batch']);
    $wherecond .= " AND customer_return.batch_id = '$batch'";
}

if (isset($_GET['datefrom']) && $_GET['datefrom'] !== '') {
    $dateFrom = date('Y-m-d', strtotime($_GET['datefrom']));
    $wherecond .= " AND DATE(customer_return.return_date) >= '$dateFrom'";
}

if (isset($_GET['dateto']) && $_GET['dateto'] !== '') {
    $dateTo = date('Y-m-d', strtotime($_GET['dateto']));
    $wherecond .= " AND DATE(customer_return.return_date) <= '$dateTo'";
}

$order_column = $_GET['order'][0]['column'] ?? '';
$order_dir = $_GET['order'][0]['dir'] ?? '';
$columns = [
    'return_id',
    'ag_name',
    'product_name',
    'batch_id',
    'qty_return',
    'model_id',
    'return_date',
    'return_reason',
    'FullName',
];

if (isset($order_column) && isset($columns[$order_column])) {
    if ($order_column == '1' || $order_column == '5') {
        $order_by = 'customer_return.customer_id ' . $order_dir;
    } elseif ($order_column == '2') {
        $order_by = 'customer_return.product_id ' . $order_dir;
    } elseif ($order_column == '8') {
        $order_by = 'customer_return.created_by ' . $order_dir;
    } else {
        $order_by = 'customer_return.' . $columns[$order_column] . ' ' . $order_dir;
    }
} else {
    $order_by = 'customer_return.return_id DESC';
}

$start = isset($_GET['start']) ? (int)$_GET['start'] : 0;
$length = isset($_GET['length']) ? (int)$_GET['length'] : 10;
$search = $_GET['search']['value'] ?? '';

if ($search !== '') {
    $wherecond .= " AND (
        vw_agent.ag_name LIKE '%$search%' OR
        products.product_name LIKE '%$search%' OR
        customer_return.batch_id LIKE '%$search%' OR
        customer_return.qty_return LIKE '%$search%' OR
        customer_return.return_date LIKE '%$search%' OR
        customer_return.return_reason LIKE '%$search%' OR
        _createuser.FullName LIKE '%$search%'
    )";
}

if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    $returnData = $obj->rawSql("
        SELECT
            customer_return.*,
            products.product_name,
            vw_agent.ag_name,
            _createuser.FullName
        FROM customer_return
        LEFT JOIN products ON customer_return.product_id = products.product_id
        LEFT JOIN vw_agent ON customer_return.customer_id = vw_agent.ag_id
        LEFT JOIN _createuser ON customer_return.created_by = _createuser.UserId
        WHERE customer_return.deleted_at IS NULL AND $wherecond
        ORDER BY $order_by
        LIMIT $length OFFSET $start
    ");

    $i = $start + 1;
    foreach ($returnData as &$row) {
        $row['sl'] = $i++;
        $model_ids = json_decode($row['model_id'], true);
        if (!is_array($model_ids)) {
            $model_ids = [];
        }

        $model_numbers = [];
        foreach ($model_ids as $key => $model_id) {
            $model = $obj->rawSqlSingle("SELECT * FROM product_model WHERE id = '$model_id' AND deleted_at IS NULL");
            if ($model) {
                $model_numbers[$key] = [
                    'model_no' => $model['model_no'],
                    'serial_no' => $model['serial_no'],
                    'expire_date' => $model['expire_date'],
                ];
            }
        }

        $row['model_id'] = $model_numbers;
    }

    $totalData = $obj->rawSql("
        SELECT COUNT(*) AS total
        FROM customer_return
        WHERE deleted_at IS NULL
    ")[0]['total'] ?? 0;

    $totalFiltered = $obj->rawSql("
        SELECT COUNT(*) AS total
        FROM customer_return
        LEFT JOIN products ON customer_return.product_id = products.product_id
        LEFT JOIN vw_agent ON customer_return.customer_id = vw_agent.ag_id
        LEFT JOIN _createuser ON customer_return.created_by = _createuser.UserId
        WHERE customer_return.deleted_at IS NULL AND $wherecond
    ")[0]['total'] ?? 0;

    echo json_encode([
        'draw' => isset($_GET['draw']) ? (int)$_GET['draw'] : 1,
        'recordsTotal' => (int)$totalData,
        'recordsFiltered' => (int)$totalFiltered,
        'data' => $returnData,
    ]);
    exit;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['id'])) {
    $id = (int)($_POST['id'] ?? 0);
    $product = (int)($_POST['product'] ?? 0);
    $quantity = (int)($_POST['quantity'] ?? 0);
    $customer = (int)($_POST['customer'] ?? 0);
    $saleDate = trim($_POST['sale_date'] ?? '');
    $batchId = trim($_POST['batch_id'] ?? '');
    $stockId = (int)($_POST['stock_id'] ?? 0);
    $reason = trim($_POST['reason'] ?? '');
    $models = normalizeCustomerReturnModels($_POST['models'] ?? []);

    if ($id <= 0 || $product <= 0 || $customer <= 0 || $quantity <= 0 || $saleDate === '' || $batchId === '' || $stockId <= 0) {
        customerReturnResponse(false, 'Please fill all required return fields');
    }

    if (count($models) !== $quantity) {
        customerReturnResponse(false, 'Selected model count must match return quantity');
    }

    $sale = $obj->rawSqlSingle("SELECT * FROM sales WHERE sale_id = '$id' AND deleted_at IS NULL");
    if (!$sale) {
        customerReturnResponse(false, 'Sale not found');
    }

    if ((int)$sale['product_id'] !== $product || (int)$sale['customer_id'] !== $customer || (int)$sale['stock_id'] !== $stockId || (string)$sale['batch_id'] !== $batchId) {
        customerReturnResponse(false, 'Return request does not match the original sale');
    }

    $remainingQty = (int)$sale['quantity'] - (int)$sale['return_qty'];
    if ($quantity > $remainingQty) {
        customerReturnResponse(false, 'Return quantity exceeds the remaining sold quantity');
    }

    $saleModelIds = normalizeCustomerReturnModels(json_decode($sale['model_id'], true));
    if (array_diff($models, $saleModelIds)) {
        customerReturnResponse(false, 'One or more selected models do not belong to this sale');
    }

    $modelIdList = implode(',', $models);
    $validModels = $obj->rawSql("
        SELECT id
        FROM product_model
        WHERE id IN ($modelIdList)
          AND sold = 1
          AND deleted_at IS NULL
    ");

    if (count($validModels) !== count($models)) {
        customerReturnResponse(false, 'One or more selected models are unavailable for return');
    }

    $stock = $obj->rawSqlSingle("
        SELECT *
        FROM stock
        WHERE stock_id = '$stockId'
          AND product_id = '$product'
          AND batch_id = '$batchId'
          AND deleted_at IS NULL
    ");

    if (!$stock) {
        customerReturnResponse(false, 'Stock not found for this return');
    }

    try {
        $db->beginTransaction();
        $now = date('Y-m-d H:i:s');

        $insertStmt = $db->prepare("
            INSERT INTO customer_return (product_id, customer_id, batch_id, model_id, stock_id, qty_return, return_reason, return_date, created_at, created_by, deleted_at)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ");
        $insertStmt->execute([
            $product,
            $customer,
            $batchId,
            json_encode($models),
            $stockId,
            $quantity,
            $reason,
            $saleDate,
            $now,
            $userid,
            null,
        ]);

        $modelStmt = $db->prepare("
            UPDATE product_model
            SET sold = 0, updated_by = ?, updated_at = ?
            WHERE id = ?
        ");
        foreach ($models as $modelId) {
            $modelStmt->execute([$userid, $now, $modelId]);
        }

        $saleStmt = $db->prepare("
            UPDATE sales
            SET return_qty = ?, updated_at = ?, updated_by = ?
            WHERE sale_id = ?
        ");
        $saleStmt->execute([
            ((int)$sale['return_qty']) + $quantity,
            $now,
            $userid,
            $id,
        ]);

        $stockStmt = $db->prepare("
            UPDATE stock
            SET current_stock = ?, updated_at = ?, updated_by = ?
            WHERE stock_id = ?
        ");
        $stockStmt->execute([
            ((int)$stock['current_stock']) + $quantity,
            $now,
            $userid,
            $stockId,
        ]);

        $db->commit();
        customerReturnResponse(true, 'Added successfully');
    } catch (Throwable $e) {
        if ($db->inTransaction()) {
            $db->rollBack();
        }
        customerReturnResponse(false, 'Failed to add customer return');
    }
}
