package app

import (
	"fmt"
	"strings"

	"github.com/seaweedfs/seaweedfs/weed/admin/dash"
	"github.com/seaweedfs/seaweedfs/weed/s3api/s3tables"
)

templ S3TablesNamespaces(data dash.S3TablesNamespacesData) {
	<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
		<h1 class="h2">
			<i class="fas fa-layer-group me-2"></i>S3 Tables Namespaces
		</h1>
		<div class="btn-toolbar mb-2 mb-md-0">
			<div class="btn-group me-2">
				<button type="button" class="btn btn-sm btn-primary" data-bs-toggle="modal" data-bs-target="#createS3TablesNamespaceModal">
					<i class="fas fa-plus me-1"></i>Create Namespace
				</button>
			</div>
		</div>
	</div>
	<div class="mb-3">
		<a href={ dash.PUrl(ctx, "/object-store/s3tables/buckets") } class="btn btn-sm btn-outline-secondary">
			<i class="fas fa-arrow-left me-1"></i>Back to Buckets
		</a>
		<span class="text-muted ms-2">Bucket ARN: { data.BucketARN }</span>
		{{ bucketName, parseErr := s3tables.ParseBucketNameFromARN(data.BucketARN) }}
		if parseErr != nil {
			<span class="text-danger ms-2">Invalid bucket ARN</span>
		}
	</div>
	<div id="s3tables-namespaces-content" data-bucket-arn={ data.BucketARN }>
		<div class="row mb-4">
			<div class="col-xl-4 col-md-6 mb-4">
				<div class="card border-left-primary shadow h-100 py-2">
					<div class="card-body">
						<div class="row no-gutters align-items-center">
							<div class="col mr-2">
								<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
									Total Namespaces
								</div>
								<div class="h5 mb-0 font-weight-bold text-gray-800">
									{ fmt.Sprintf("%d", data.TotalNamespaces) }
								</div>
							</div>
							<div class="col-auto">
								<i class="fas fa-layer-group fa-2x text-gray-300"></i>
							</div>
						</div>
					</div>
				</div>
			</div>
			<div class="col-xl-4 col-md-6 mb-4">
				<div class="card border-left-info shadow h-100 py-2">
					<div class="card-body">
						<div class="row no-gutters align-items-center">
							<div class="col mr-2">
								<div class="text-xs font-weight-bold text-info text-uppercase mb-1">
									Last Updated
								</div>
								<div class="h6 mb-0 font-weight-bold text-gray-800">
									{ data.LastUpdated.Format("15:04") }
								</div>
							</div>
							<div class="col-auto">
								<i class="fas fa-clock fa-2x text-gray-300"></i>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
		<div class="row">
			<div class="col-12">
				<div class="card shadow mb-4">
					<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
						<h6 class="m-0 font-weight-bold text-primary">
							<i class="fas fa-layer-group me-2"></i>Namespaces
						</h6>
					</div>
					<div class="card-body">
						<div class="table-responsive">
							<table class="table table-hover" width="100%" cellspacing="0" id="s3tablesNamespacesTable">
								<thead>
									<tr>
										<th>Namespace</th>
										<th>Iceberg Endpoint</th>
										<th>Created</th>
										<th>Actions</th>
									</tr>
								</thead>
								<tbody>
									for _, namespace := range data.Namespaces {
										<tr>
											{{ namespaceName := strings.Join(namespace.Namespace, ".") }}
											<td>{ namespaceName }</td>
											<td>
												if parseErr == nil {
													<code class="small">/v1/{ bucketName }/namespaces/{ namespaceName }/tables</code>
												} else {
													<span class="text-muted">-</span>
												}
											</td>
											<td>{ namespace.CreatedAt.Format("2006-01-02 15:04") }</td>
											<td>
												<div class="btn-group btn-group-sm" role="group">
													if parseErr == nil {
														<a class="btn btn-outline-primary btn-sm" href={ dash.PUrl(ctx, fmt.Sprintf("/object-store/s3tables/buckets/%s/namespaces/%s/tables", bucketName, namespaceName)) }>
															<i class="fas fa-table"></i>
														</a>
													} else {
														<button type="button" class="btn btn-outline-primary btn-sm" disabled title="Invalid bucket ARN">
															<i class="fas fa-table"></i>
														</button>
													}
													<button type="button" class="btn btn-outline-danger btn-sm s3tables-delete-namespace-btn" data-namespace-name={ namespaceName } title="Delete">
														<i class="fas fa-trash"></i>
													</button>
												</div>
											</td>
										</tr>
									}
									if len(data.Namespaces) == 0 {
										<tr>
											<td colspan="4" class="text-center text-muted py-4">
												<i class="fas fa-layer-group fa-3x mb-3 text-muted"></i>
												<div>
													<h5>No namespaces found</h5>
													<p>Create your first namespace to organize tables.</p>
													<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#createS3TablesNamespaceModal">
														<i class="fas fa-plus me-1"></i>Create Namespace
													</button>
												</div>
											</td>
										</tr>
									}
								</tbody>
							</table>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
	<div class="modal fade" id="createS3TablesNamespaceModal" tabindex="-1" aria-labelledby="createS3TablesNamespaceModalLabel" aria-hidden="true">
		<div class="modal-dialog">
			<div class="modal-content">
				<div class="modal-header">
					<h5 class="modal-title" id="createS3TablesNamespaceModalLabel">
						<i class="fas fa-plus me-2"></i>Create Namespace
					</h5>
					<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
				</div>
				<form id="createS3TablesNamespaceForm">
						<div class="modal-body">
							<input type="hidden" name="bucket_arn" value={ data.BucketARN }/>
							<div class="mb-3">
								<label for="s3tablesNamespaceName" class="form-label">Namespace</label>
								<input type="text" class="form-control" id="s3tablesNamespaceName" name="name" placeholder="analytics" required/>
								<div class="form-text">Use lowercase letters, numbers, and underscores. Use dots for nested namespaces (for example, analytics.daily).</div>
							</div>
						</div>
					<div class="modal-footer">
						<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
						<button type="submit" class="btn btn-primary">
							<i class="fas fa-plus me-1"></i>Create
						</button>
					</div>
				</form>
			</div>
		</div>
	</div>
	<div class="modal fade" id="deleteS3TablesNamespaceModal" tabindex="-1" aria-labelledby="deleteS3TablesNamespaceModalLabel" aria-hidden="true">
		<div class="modal-dialog">
			<div class="modal-content">
				<div class="modal-header">
					<h5 class="modal-title" id="deleteS3TablesNamespaceModalLabel">
						<i class="fas fa-exclamation-triangle me-2 text-warning"></i>Delete Namespace
					</h5>
					<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
				</div>
				<div class="modal-body">
					<p>Are you sure you want to delete the namespace <strong id="deleteS3TablesNamespaceName"></strong>?</p>
				</div>
				<div class="modal-footer">
					<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
					<button type="button" class="btn btn-danger" onclick="deleteS3TablesNamespace()">
						<i class="fas fa-trash me-1"></i>Delete
					</button>
				</div>
			</div>
		</div>
	</div>
	<script>
		let s3tablesNamespaceDeleteModalInstance = null;
		const dataBucketArn = document.getElementById('s3tables-namespaces-content').dataset.bucketArn || '';
		const csrfTokenMeta = document.querySelector('meta[name="csrf-token"]');
		const csrfToken = csrfTokenMeta ? (csrfTokenMeta.getAttribute('content') || '') : '';

		function makeJSONHeaders() {
			const headers = { 'Content-Type': 'application/json' };
			if (csrfToken) {
				headers['X-CSRF-Token'] = csrfToken;
			}
			return headers;
		}

		async function readErrorMessage(response, fallbackMessage) {
			const responseBody = await response.text();
			if (!responseBody) {
				return fallbackMessage;
			}
			try {
				const payload = JSON.parse(responseBody);
				if (payload && typeof payload.error === 'string' && payload.error) {
					return payload.error;
				}
				if (payload && typeof payload.message === 'string' && payload.message) {
					return payload.message;
				}
			} catch (parseError) {
				// Fall through to the raw response body when parsing fails.
			}
			return responseBody;
		}

		function validateNamespaceInput(input, allowEmpty) {
			if (typeof window.applyS3TablesNamespaceNameValidity === 'function') {
				return window.applyS3TablesNamespaceNameValidity(input, allowEmpty);
			}
			const name = (input.value || '').trim();
			if (allowEmpty && name === '') {
				input.setCustomValidity('');
				return '';
			}
				let message = '';
				if (!name) {
					message = 'Namespace name is required';
				} else if (name.length < 1 || name.length > 255) {
					message = 'Namespace name must be between 1 and 255 characters';
				} else if (name === '.' || name === '..') {
					message = "namespace name cannot be '.' or '..'";
				} else if (name.includes('/')) {
					message = "namespace name cannot contain '/'";
				} else {
					for (const part of name.split('.')) {
						if (!part) {
							message = 'namespace levels cannot be empty';
							break;
						}
						const start = part[0];
						const end = part[part.length - 1];
						const isStartValid = (start >= 'a' && start <= 'z') || (start >= '0' && start <= '9');
						const isEndValid = (end >= 'a' && end <= 'z') || (end >= '0' && end <= '9');
						if (!isStartValid) {
							message = 'Namespace name must start with a letter or digit';
							break;
						}
						if (!isEndValid) {
							message = 'Namespace name must end with a letter or digit';
							break;
						}
						for (const ch of part) {
							const isLower = ch >= 'a' && ch <= 'z';
							const isDigit = ch >= '0' && ch <= '9';
							if (!(isLower || isDigit || ch === '_')) {
								message = "invalid namespace name: only 'a-z', '0-9', and '_' are allowed";
								break;
							}
						}
						if (message) {
							break;
						}
						if (part.startsWith('aws')) {
							message = "namespace name cannot start with reserved prefix 'aws'";
							break;
						}
					}
				}
				input.setCustomValidity(message);
				return message;
			}

		document.addEventListener('DOMContentLoaded', function() {
			s3tablesNamespaceDeleteModalInstance = new bootstrap.Modal(document.getElementById('deleteS3TablesNamespaceModal'));

			document.querySelectorAll('.s3tables-delete-namespace-btn').forEach(button => {
				button.addEventListener('click', function() {
					document.getElementById('deleteS3TablesNamespaceName').textContent = this.dataset.namespaceName || '';
					document.getElementById('deleteS3TablesNamespaceModal').dataset.namespaceName = this.dataset.namespaceName || '';
					s3tablesNamespaceDeleteModalInstance.show();
				});
			});

			const namespaceInput = document.getElementById('s3tablesNamespaceName');
			if (namespaceInput) {
				namespaceInput.addEventListener('input', function() {
					validateNamespaceInput(this, true);
				});
			}

			document.getElementById('createS3TablesNamespaceForm').addEventListener('submit', async function(e) {
				e.preventDefault();
				const namespaceInput = document.getElementById('s3tablesNamespaceName');
				const name = namespaceInput.value.trim();
				const nameError = validateNamespaceInput(namespaceInput, false);
				if (nameError) {
					namespaceInput.reportValidity();
					return;
				}
				try {
					const response = await fetch((window.__BASE_PATH__ || '') + '/api/s3tables/namespaces', {
						method: 'POST',
						headers: makeJSONHeaders(),
						body: JSON.stringify({ bucket_arn: dataBucketArn, name: name })
					});
					if (!response.ok) {
						const errorMessage = await readErrorMessage(response, 'Failed to create namespace');
						alert(errorMessage);
						return;
					}
					alert('Namespace created');
					location.reload();
				} catch (error) {
					alert('Failed to create namespace: ' + error.message);
				}
			});

		});

		async function deleteS3TablesNamespace() {
			const namespace = document.getElementById('deleteS3TablesNamespaceModal').dataset.namespaceName;
			if (!namespace) return;
			try {
				const requestOptions = { method: 'DELETE' };
				if (csrfToken) {
					requestOptions.headers = { 'X-CSRF-Token': csrfToken };
				}
				const response = await fetch((window.__BASE_PATH__ || '') + `/api/s3tables/namespaces?bucket=${encodeURIComponent(dataBucketArn)}&name=${encodeURIComponent(namespace)}`, requestOptions);
				if (!response.ok) {
					const errorMessage = await readErrorMessage(response, 'Failed to delete namespace');
					alert(errorMessage);
					return;
				}
				alert('Namespace deleted');
				location.reload();
			} catch (error) {
				alert('Failed to delete namespace: ' + error.message);
			}
		}

	</script>
}
