<?php
require_once __DIR__ . '/functions.php';

$tenant = enrep_tenant_segment($_POST['tenant'] ?? $_GET['tenant'] ?? null);
if ($tenant !== '' && !defined('CONFIG_LOADED')) {
    require_once '../../' . $tenant . '/config.php';
}

assetmanager_require_user();

$con = $GLOBALS['con'] ?? null;
if (!$con instanceof mysqli) {
    assetmanager_json_response(['success' => false, 'message' => 'Tenant database connection unavailable.']);
}
$con->set_charset('utf8mb4');

$clientnumber = enrep_request_int('clientnumber', 0);
if ($clientnumber <= 0) {
    assetmanager_json_response(['success' => false, 'message' => 'Client number is required.']);
}
assetmanager_json_require_client_access($con, $clientnumber);
assetmanager_json_require_module($con, $tenant, $clientnumber, 'hire', 'Hire');

if (!assetmanager_table_exists($con, 'assetmanager_hire_pricing')) {
    assetmanager_json_response(['success' => false, 'setup_required' => true, 'message' => 'Hire pricing table is not installed yet.']);
}

$groupName = enrep_request_string('group_name', '', 160);
$ruleId = enrep_request_int('rule_id', 0);
$source = enrep_request_enum('source', ['enrep_item', 'assetmanager_item'], '');
$sourceId = enrep_request_int('source_id', 0);
$assetTitle = enrep_request_string('asset_title', 'Asset', 255);
if ($groupName === '' && ($source === '' || $sourceId <= 0)) {
    assetmanager_json_response(['success' => false, 'message' => 'Enter a pricing group or choose a specific hire item.']);
}

$payload = assetmanager_request_json_array('pricing_payload_json');
$dailyRate = enrep_request_string('daily_rate', '', 40);
$weeklyRate = enrep_request_string('weekly_rate', '', 40);
$monthlyRate = enrep_request_string('monthly_rate', '', 40);
$vatMode = enrep_request_enum('vat_mode', ['vatable', 'no_vat'], 'vatable');
$vatRate = enrep_request_string('vat_rate', '20', 40);
$depositAmount = enrep_request_string('deposit_amount', '', 40);
$insuranceDailyRate = enrep_request_string('insurance_daily_rate', '', 40);
$dailyRate = $dailyRate === '' ? null : (float)$dailyRate;
$weeklyRate = $weeklyRate === '' ? null : (float)$weeklyRate;
$monthlyRate = $monthlyRate === '' ? null : (float)$monthlyRate;
$vatRate = $vatRate === '' ? null : (float)$vatRate;
$depositAmount = $depositAmount === '' ? null : (float)$depositAmount;
$insuranceDailyRate = $insuranceDailyRate === '' ? null : (float)$insuranceDailyRate;
$minDuration = isset($payload['min_duration']) && $payload['min_duration'] !== '' ? (float)$payload['min_duration'] : null;
$maxDuration = isset($payload['max_duration']) && $payload['max_duration'] !== '' ? (float)$payload['max_duration'] : null;
$durationUnit = in_array((string)($payload['duration_unit'] ?? 'days'), ['days', 'weeks', 'months'], true) ? (string)$payload['duration_unit'] : 'days';
$payloadJson = assetmanager_encode_json($payload);
$userId = assetmanager_actor_user_id();
$now = date('Y-m-d H:i:s');
$status = 'active';

$resolvePostedAsset = static function (array $asset) use ($con, $tenant, $clientnumber): ?array {
    $ref = (string)($asset['ref'] ?? '');
    $parts = explode('|', $ref);
    $source = $parts[0] ?? '';
    $sourceId = (int)($parts[1] ?? 0);
    if (!in_array($source, ['enrep_item', 'assetmanager_item'], true) || $sourceId <= 0) {
        return null;
    }
    assetmanager_json_require_asset_access($con, $tenant, $clientnumber, $source, $sourceId);
    $label = (string)($asset['label'] ?? ($parts[2] ?? 'Asset'));
    $assetId = assetmanager_resolve_asset_id($con, $tenant, $clientnumber, $source, $sourceId, $label, true);
    if ($assetId <= 0) {
        return null;
    }
    return [
        'asset_id' => $assetId,
        'source' => $source,
        'source_id' => $sourceId,
        'label' => $label,
    ];
};

$singleAsset = null;
if ($source !== '' && $sourceId > 0) {
    assetmanager_json_require_asset_access($con, $tenant, $clientnumber, $source, $sourceId);
    $assetId = assetmanager_resolve_asset_id($con, $tenant, $clientnumber, $source, $sourceId, $assetTitle, true);
    if ($assetId <= 0) {
        assetmanager_json_response(['success' => false, 'message' => 'The selected hire item could not be linked.']);
    }
    $singleAsset = [
        'asset_id' => $assetId,
        'source' => $source,
        'source_id' => $sourceId,
        'label' => $assetTitle,
    ];
}

$groupMemberAssets = [];
foreach (assetmanager_request_json_array('group_asset_refs_json') as $member) {
    if (!is_array($member)) {
        continue;
    }
    $resolved = $resolvePostedAsset($member);
    if ($resolved !== null) {
        $groupMemberAssets[$resolved['asset_id']] = $resolved;
    }
}

$assetIdsToCheck = [];
if ($singleAsset !== null && $groupName === '') {
    $assetIdsToCheck[] = (int)$singleAsset['asset_id'];
}
foreach ($groupMemberAssets as $memberAsset) {
    $assetIdsToCheck[] = (int)$memberAsset['asset_id'];
}
$assetIdsToCheck = array_values(array_unique(array_filter($assetIdsToCheck)));
foreach ($assetIdsToCheck as $checkAssetId) {
    $stmt = $con->prepare("
        SELECT id
        FROM assetmanager_hire_pricing
        WHERE tenant_key=? AND clientnumber=? AND asset_id=? AND status_key='active' AND id<>?
        LIMIT 1
    ");
    if ($stmt) {
        $stmt->bind_param('siii', $tenant, $clientnumber, $checkAssetId, $ruleId);
        $stmt->execute();
        $existing = $stmt->get_result()->fetch_assoc();
        $stmt->close();
        if ($existing) {
            assetmanager_json_response(['success' => false, 'message' => 'One or more selected items already has active hire pricing.']);
        }
    }
}

$insertPricing = static function (?int $id, string $recordType, string $groupKey, string $groupName, ?int $assetId, array $rowPayload) use ($con, $tenant, $clientnumber, $status, $dailyRate, $weeklyRate, $monthlyRate, $vatMode, $vatRate, $depositAmount, $insuranceDailyRate, $minDuration, $maxDuration, $durationUnit, $userId, $now): int {
    $rowPayloadJson = assetmanager_encode_json($rowPayload);
    if ($id !== null && $id > 0) {
        $stmt = $con->prepare("
            UPDATE assetmanager_hire_pricing
            SET record_type=?, group_key=?, group_name=?, asset_id=?, daily_rate=?, weekly_rate=?, monthly_rate=?, vat_mode=?, vat_rate=?, deposit_amount=?, insurance_daily_rate=?, min_duration=?, max_duration=?, duration_unit=?, payload_json=?, updated_at=?
            WHERE id=? AND tenant_key=? AND clientnumber=?
        ");
        if (!$stmt) {
            return 0;
        }
        $stmt->bind_param('sssidddsddddsssisi', $recordType, $groupKey, $groupName, $assetId, $dailyRate, $weeklyRate, $monthlyRate, $vatMode, $vatRate, $depositAmount, $insuranceDailyRate, $minDuration, $maxDuration, $durationUnit, $rowPayloadJson, $now, $id, $tenant, $clientnumber);
        $ok = $stmt->execute();
        $stmt->close();
        return $ok ? $id : 0;
    }

    $stmt = $con->prepare("
        INSERT INTO assetmanager_hire_pricing
            (tenant_key, clientnumber, record_type, group_key, group_name, asset_id, status_key, daily_rate, weekly_rate, monthly_rate, vat_mode, vat_rate, deposit_amount, insurance_daily_rate, min_duration, max_duration, duration_unit, payload_json, created_by, created_at, updated_at)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    ");
    if (!$stmt) {
        return 0;
    }
    $stmt->bind_param('sisssisdddsdddddssiss', $tenant, $clientnumber, $recordType, $groupKey, $groupName, $assetId, $status, $dailyRate, $weeklyRate, $monthlyRate, $vatMode, $vatRate, $depositAmount, $insuranceDailyRate, $minDuration, $maxDuration, $durationUnit, $rowPayloadJson, $userId, $now, $now);
    $ok = $stmt->execute();
    $newId = $ok ? (int)$stmt->insert_id : 0;
    $stmt->close();
    return $newId;
};

if ($groupName !== '') {
    if (empty($groupMemberAssets)) {
        assetmanager_json_response(['success' => false, 'message' => 'Add at least one item to the pricing group.']);
    }

    $groupId = $ruleId > 0 ? $ruleId : null;
    $groupKey = $groupId !== null ? (string)$groupId : '';
    $groupPayload = $payload;
    $groupPayload['members'] = array_values($groupMemberAssets);
    $savedGroupId = $insertPricing($groupId, 'group', $groupKey, $groupName, null, $groupPayload);
    if ($savedGroupId <= 0) {
        assetmanager_json_response(['success' => false, 'message' => 'Hire pricing group could not be saved.']);
    }
    if ($groupKey === '') {
        $groupKey = (string)$savedGroupId;
        $stmt = $con->prepare("UPDATE assetmanager_hire_pricing SET group_key=? WHERE id=? AND tenant_key=? AND clientnumber=?");
        if ($stmt) {
            $stmt->bind_param('sisi', $groupKey, $savedGroupId, $tenant, $clientnumber);
            $stmt->execute();
            $stmt->close();
        }
    }

    $stmt = $con->prepare("UPDATE assetmanager_hire_pricing SET status_key='replaced', updated_at=? WHERE tenant_key=? AND clientnumber=? AND record_type='item' AND group_key=? AND status_key='active'");
    if ($stmt) {
        $stmt->bind_param('ssis', $now, $tenant, $clientnumber, $groupKey);
        $stmt->execute();
        $stmt->close();
    }

    $ok = true;
    foreach ($groupMemberAssets as $memberAsset) {
        $memberPayload = $payload;
        $memberPayload['asset_label'] = $memberAsset['label'];
        $memberPayload['group_member'] = 1;
        $memberPayload['source'] = $memberAsset['source'];
        $memberPayload['source_id'] = $memberAsset['source_id'];
        $memberId = $insertPricing(null, 'item', $groupKey, $groupName, (int)$memberAsset['asset_id'], $memberPayload);
        $ok = $memberId > 0 && $ok;
    }

    if ($ok) {
        assetmanager_audit($con, $tenant, $clientnumber, $userId, 'hire_pricing', $savedGroupId, 'group_save', [], [
            'group_name' => $groupName,
            'member_count' => count($groupMemberAssets),
        ]);
    }
    assetmanager_json_response([
        'success' => $ok,
        'rule_id' => $savedGroupId,
        'message' => $ok ? 'Hire pricing group saved.' : 'Hire pricing group could not be saved.',
    ]);
}

$assetId = $singleAsset !== null ? (int)$singleAsset['asset_id'] : null;
$savedRuleId = $insertPricing($ruleId > 0 ? $ruleId : null, 'item', '', '', $assetId, $payload);
$ok = $savedRuleId > 0;
if ($ok) {
    assetmanager_audit($con, $tenant, $clientnumber, $userId, 'hire_pricing', $savedRuleId, $ruleId > 0 ? 'update' : 'create', [], [
        'asset_id' => $assetId,
        'daily_rate' => $dailyRate,
        'weekly_rate' => $weeklyRate,
        'monthly_rate' => $monthlyRate,
    ]);
}

assetmanager_json_response([
    'success' => $ok,
    'rule_id' => $savedRuleId,
    'message' => $ok ? 'Hire pricing saved.' : 'Hire pricing could not be saved.',
]);
