package components

import (
	"fmt"
	"github.com/starfleetcptn/gomft/internal/db"
	"context"
	"github.com/starfleetcptn/gomft/components/providers/source"
	"github.com/starfleetcptn/gomft/components/providers/destination"
	"github.com/starfleetcptn/gomft/components/providers/common"
)

type ConfigFormData struct {
	Config *db.TransferConfig
	IsNew  bool
}

func getConfigFormTitle(isNew bool) string {
	if isNew {
		return "New Configuration"
	}
	return "Edit Configuration"
}

func getInitialData(config *db.TransferConfig) string {
	// Default values for a new configuration
	name := ""
	sourceType := "local"
	sourcePath := ""
	sourceHost := ""
	sourcePort := 22
	sourceUser := ""
	sourcePassword := ""
	sourceKeyFile := ""
	sourceAuthType := "password"
	sourceBucket := ""
	sourceRegion := ""
	sourceAccessKey := ""
	sourceSecretKey := ""
	sourceEndpoint := ""
	sourceShare := ""
	sourceDomain := ""
	sourcePassiveMode := false
	sourceClientId := ""
	sourceClientSecret := ""
	sourceDriveId := ""
	sourceTeamDrive := ""
	// Google Photos source fields
	sourceReadOnly := false
	sourceStartYear := 2025
	sourceIncludeArchived := false
	
	filePattern := ""
	outputPattern := "${filename}"
	
	destinationType := "local"
	destinationPath := ""
	destHost := ""
	destPort := 22
	destUser := ""
	destPassword := ""
	destKeyFile := ""
	destAuthType := "password"
	destBucket := ""
	destRegion := ""
	destAccessKey := ""
	destSecretKey := ""
	destEndpoint := ""
	destShare := ""
	destDomain := ""
	destPassiveMode := false
	destClientId := ""
	destClientSecret := ""
	destDriveId := ""
	destTeamDrive := ""
	// Google Photos destination fields
	destReadOnly := false
	destStartYear := 2025
	destIncludeArchived := false
	
	archivePath := ""
	archiveEnabled := false
	deleteAfterTransfer := false
	skipProcessedFiles := true
	maxConcurrentTransfers := 4
	rcloneFlags := ""
	commandId := uint(1) // Default to 'copy' command
	commandFlags := ""
	useBuiltinAuthSource := true
	useBuiltinAuthDest := true

	// If editing an existing config, populate with those values
	if config != nil {
		name = config.Name
		sourceType = config.SourceType
		sourcePath = config.SourcePath
		sourceHost = config.SourceHost
		sourcePort = config.SourcePort
		sourceUser = config.SourceUser
		sourcePassword = config.SourcePassword
		sourceKeyFile = config.SourceKeyFile
		if sourceKeyFile != "" && sourcePassword == "" {
			sourceAuthType = "key"
		}
		sourceBucket = config.SourceBucket
		sourceRegion = config.SourceRegion
		sourceAccessKey = config.SourceAccessKey
		sourceSecretKey = config.SourceSecretKey
		sourceEndpoint = config.SourceEndpoint
		sourceShare = config.SourceShare
		sourceDomain = config.SourceDomain
		sourcePassiveMode = config.GetSourcePassiveMode()
		sourceClientId = config.SourceClientID
		sourceClientSecret = config.SourceClientSecret
		sourceDriveId = config.SourceDriveID
		sourceTeamDrive = config.SourceTeamDrive
		
		// Google Photos source fields
		if config.SourceReadOnly != nil {
			sourceReadOnly = *config.SourceReadOnly
		}
		// sourceStartYear = config.SourceStartYear
		if config.SourceIncludeArchived != nil {
			sourceIncludeArchived = *config.SourceIncludeArchived
		}
		
		filePattern = config.FilePattern
		outputPattern = config.OutputPattern
		
		destinationType = config.DestinationType
		destinationPath = config.DestinationPath
		destHost = config.DestHost
		destPort = config.DestPort
		destUser = config.DestUser
		destPassword = config.DestPassword
		destKeyFile = config.DestKeyFile
		if destKeyFile != "" && destPassword == "" {
			destAuthType = "key"
		}
		destBucket = config.DestBucket
		destRegion = config.DestRegion
		destAccessKey = config.DestAccessKey
		destSecretKey = config.DestSecretKey
		destEndpoint = config.DestEndpoint
		destShare = config.DestShare
		destDomain = config.DestDomain
		destPassiveMode = config.GetDestPassiveMode()
		destClientId = config.DestClientID
		destClientSecret = config.DestClientSecret
		destDriveId = config.DestDriveID
		destTeamDrive = config.DestTeamDrive
		
		// Google Photos destination fields
		if config.DestReadOnly != nil {
			destReadOnly = *config.DestReadOnly
		}
		// destStartYear = config.DestStartYear
		if config.DestIncludeArchived != nil {
			destIncludeArchived = *config.DestIncludeArchived
		}
		
		archivePath = config.ArchivePath
		archiveEnabled = config.GetArchiveEnabled()
		deleteAfterTransfer = config.GetDeleteAfterTransfer()
		skipProcessedFiles = config.GetSkipProcessedFiles()
		maxConcurrentTransfers = config.MaxConcurrentTransfers
		rcloneFlags = config.RcloneFlags
		commandId = config.CommandID
		commandFlags = config.CommandFlags
		if config.UseBuiltinAuthSource != nil {
			useBuiltinAuthSource = *config.UseBuiltinAuthSource
		} else if sourceClientId != "" || sourceClientSecret != "" {
			useBuiltinAuthSource = false
		}
		if config.UseBuiltinAuthDest != nil {
			useBuiltinAuthDest = *config.UseBuiltinAuthDest
		} else if destClientId != "" || destClientSecret != "" {
			useBuiltinAuthDest = false
		}
	}

	// Return the JSON-formatted string with all the data, add new path validation states
	return fmt.Sprintf(`{
		name: '%s',
		sourceType: '%s',
		sourcePath: '%s',
		sourceHost: '%s',
		sourcePort: %d,
		sourceUser: '%s',
		sourcePassword: '%s',
		sourceKeyFile: '%s',
		sourceAuthType: '%s',
		sourceBucket: '%s',
		sourceRegion: '%s',
		sourceAccessKey: '%s',
		sourceSecretKey: '%s',
		sourceEndpoint: '%s',
		sourceShare: '%s',
		sourceDomain: '%s',
		sourcePassiveMode: %v,
		sourceClientId: '%s',
		sourceClientSecret: '%s',
		sourceDriveId: '%s',
		sourceTeamDrive: '%s',
		sourceReadOnly: %v,
		sourceStartYear: %d,
		sourceIncludeArchived: %v,
		
		filePattern: '%s',
		outputPattern: '%s',
		
		destinationType: '%s',
		destinationPath: '%s',
		destHost: '%s',
		destPort: %d,
		destUser: '%s',
		destPassword: '%s',
		destKeyFile: '%s',
		destAuthType: '%s',
		destBucket: '%s',
		destRegion: '%s',
		destAccessKey: '%s',
		destSecretKey: '%s',
		destEndpoint: '%s',
		destShare: '%s',
		destDomain: '%s',
		destPassiveMode: %v,
		destClientId: '%s',
		destClientSecret: '%s',
		destDriveId: '%s',
		destTeamDrive: '%s',
		destReadOnly: %v,
		destStartYear: %d,
		destIncludeArchived: %v,
		
		useBuiltinAuthSource: %v,
		useBuiltinAuthDest: %v,
		
		archivePath: '%s',
		archiveEnabled: %v,
		deleteAfterTransfer: %v,
		skipProcessedFiles: %v,
		maxConcurrentTransfers: %d,
		rcloneFlags: '%s',
		commandId: %d,
		commandFlags: '%s',

		// Path validation states
		sourcePathValid: null,
		sourcePathError: '',
		destPathValid: null,
		destPathError: '',
		
		// Command configuration
		requiresDestination: true,

		// Methods for path validation
		checkPath(path, type) {
			if (!path) {
				this[type + 'PathValid'] = false;
				this[type + 'PathError'] = 'Path cannot be empty';
				return;
			}

			fetch('/check-path?path=' + encodeURIComponent(path))
				.then(response => response.json())
				.then(data => {
					this[type + 'PathValid'] = data.valid;
					this[type + 'PathError'] = data.error || '';
				})
				.catch(error => {
					this[type + 'PathValid'] = false;
					this[type + 'PathError'] = 'Error checking path: ' + error.message;
				});
		},
		
		// Method to check if destination is required based on command type
		updateCommandRequirements() {
			// List of commands that don't require destination
			const listingCommands = ['ls', 'lsd', 'lsl', 'lsf', 'lsjson', 'listremotes'];
			const infoCommands = ['md5sum', 'sha1sum', 'size', 'version'];
			const dirCommands = ['mkdir', 'rmdir', 'rmdirs'];
			const destructiveCommands = ['delete', 'purge'];
			const specialSinglePathCommands = ['obscure'];
			
			// Get the command name from the command ID
			// This will need coordination with your backend to ensure the IDs match the commands
			let commandName = '';
			switch(parseInt(this.commandId)) {
				// Map command IDs to command names - adjust these based on your actual command IDs
				case 1: commandName = 'copy'; break;
				case 2: commandName = 'move'; break;
				case 3: commandName = 'sync'; break;
				case 4: commandName = 'ls'; break;
				case 5: commandName = 'lsd'; break;
				case 6: commandName = 'lsl'; break;
				case 7: commandName = 'lsf'; break;
				case 8: commandName = 'lsjson'; break;
				case 9: commandName = 'md5sum'; break;
				case 10: commandName = 'sha1sum'; break;
				case 11: commandName = 'size'; break;
				case 12: commandName = 'delete'; break;
				case 13: commandName = 'purge'; break;
				case 14: commandName = 'mkdir'; break;
				case 15: commandName = 'rmdir'; break;
				case 16: commandName = 'rmdirs'; break;
				case 17: commandName = 'check'; break;
				case 18: commandName = 'cleanup'; break;
				case 19: commandName = 'dedupe'; break;
				case 20: commandName = 'version'; break;
				case 21: commandName = 'listremotes'; break;
				case 22: commandName = 'cryptcheck'; break;
				case 23: commandName = 'bisync'; break;
				case 24: commandName = 'copyto'; break;
				case 25: commandName = 'moveto'; break;
				default: commandName = 'copy'; // Default to copy
			}
			
			console.log('Command ID:', this.commandId, 'Command Name:', commandName);
			
			// Check if the command requires a destination
			if (
				listingCommands.includes(commandName) ||
				infoCommands.includes(commandName) ||
				(dirCommands.includes(commandName) && !this.rcloneFlags.includes('--dst')) ||
				destructiveCommands.includes(commandName) ||
				specialSinglePathCommands.includes(commandName) ||
				commandName === 'version' ||
				commandName === 'listremotes'
			) {
				this.requiresDestination = false;
				console.log('Destination not required for command:', commandName);
			} else {
				this.requiresDestination = true;
				console.log('Destination required for command:', commandName);
			}
		}
	}`, 
	name, sourceType, sourcePath, sourceHost, sourcePort, sourceUser, sourcePassword, sourceKeyFile, sourceAuthType,
	sourceBucket, sourceRegion, sourceAccessKey, sourceSecretKey, sourceEndpoint, sourceShare, sourceDomain, sourcePassiveMode,
	sourceClientId, sourceClientSecret, sourceDriveId, sourceTeamDrive,
	sourceReadOnly, sourceStartYear, sourceIncludeArchived,
	filePattern, outputPattern,
	destinationType, destinationPath, destHost, destPort, destUser, destPassword, destKeyFile, destAuthType,
	destBucket, destRegion, destAccessKey, destSecretKey, destEndpoint, destShare, destDomain, destPassiveMode,
	destClientId, destClientSecret, destDriveId, destTeamDrive,
	destReadOnly, destStartYear, destIncludeArchived,
	useBuiltinAuthSource, useBuiltinAuthDest,
	archivePath, archiveEnabled, deleteAfterTransfer, skipProcessedFiles, maxConcurrentTransfers, rcloneFlags, 
	commandId, commandFlags)
}

templ ConfigForm(ctx context.Context, data ConfigFormData) {
	@LayoutWithContext(getConfigFormTitle(data.IsNew), ctx) {
		<!-- Main Content -->
		<section class="py-8 px-4">
			<div class="mx-auto max-w-3xl">
				<div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-sm p-6 md:p-8">
					<!-- Form Header -->
					<div class="mb-8 text-center">
						<div class="flex justify-center mb-4">
							<span class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-blue-50 dark:bg-blue-900">
								<i class="fas fa-cog text-blue-600 dark:text-blue-300 text-2xl"></i>
							</span>
						</div>
						<h1 class="text-2xl font-bold text-gray-900 dark:text-white">
							{ getConfigFormTitle(data.IsNew) }
						</h1>
						<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
							Configure your file transfer settings using the form below
						</p>
					</div>

					<!-- Main Form -->
					<form 
						class="space-y-6" 
						if data.IsNew {
							hx-post="/configs"
						} else {
							hx-post={ fmt.Sprintf("/configs/%d", data.Config.ID) }
						}
						hx-target="body"
						hx-redirect="/configs"
						hx-boost="true"
						x-data={ getInitialData(data.Config) }
						x-init="$nextTick(() => { 
							// Ensure initial form state displays correctly on load
							sourceType = sourceType || 'local';
							destinationType = destinationType || 'local';
							sourcePort = sourcePort || 22;
							destPort = destPort || 22;
							// Initialize command requirements
							updateCommandRequirements();
						})"
						>
						
						<!-- Configuration Details Section -->
						<div class="p-4 mb-4 bg-blue-50 border border-blue-100 rounded-lg dark:bg-blue-900/20 dark:border-blue-900">
							<div class="flex items-center mb-2">
								<i class="fas fa-info-circle text-blue-600 dark:text-blue-400 mr-2"></i>
								<h3 class="text-lg font-medium text-blue-600 dark:text-blue-400">Configuration Details</h3>
							</div>
							<p class="text-sm text-blue-700 dark:text-blue-300">
								Give your configuration a descriptive name and set up the source and destination locations.
							</p>
						</div>
							
						<!-- Name field -->
						<div class="mb-2">
							<label for="name" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Configuration Name</label>
							<input 
								type="text" 
								id="name" 
								name="name" 
								x-model="name" 
								required 
								class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" 
								placeholder="My Transfer Configuration"
							/>
							<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">Choose a descriptive name to identify this configuration.</p>
						</div>
						
						<!-- Rclone Command Configuration Section -->
						<div class="p-5 bg-white border border-gray-200 rounded-lg shadow-sm dark:bg-gray-800 dark:border-gray-700">
							<h3 class="mb-4 text-xl font-bold text-gray-900 dark:text-white flex items-center">
								<i class="fas fa-terminal mr-2 text-blue-500 dark:text-blue-400"></i>Command Configuration
							</h3>
							
							<!-- Use the RcloneFlags component from common package -->
							@common.RcloneFlags()
						</div>
						
						<!-- Source Configuration Section -->
						<div class="p-5 bg-white border border-gray-200 rounded-lg shadow-sm dark:bg-gray-800 dark:border-gray-700">
							<h3 class="mb-4 text-xl font-bold text-gray-900 dark:text-white flex items-center">
								<i class="fas fa-upload mr-2 text-blue-500 dark:text-blue-400"></i>Source Configuration
							</h3>
							
							<!-- Source selection -->
							@common.SourceSelection()
							
							<!-- Source type specific forms -->
							<template x-if="sourceType === 'local'">
								@source.LocalSourceForm()
							</template>
							
							<template x-if="sourceType === 'sftp'">
								@source.SFTPSourceForm()
							</template>

							<template x-if="sourceType === 'ftp'">
								@source.FTPSourceForm()
							</template>
							
							<template x-if="sourceType === 's3'">
								@source.S3SourceForm()
							</template>
							
							<template x-if="sourceType === 'minio'">
								@source.MinIOSourceForm()
							</template>

							<template x-if="sourceType === 'smb'">
								@source.SMBSourceForm()
							</template>
							
							<template x-if="sourceType === 'webdav'">
								@source.WebDAVSourceForm()
							</template>
							
							<template x-if="sourceType === 'nextcloud'">
								@source.NextCloudSourceForm()
							</template>

							<template x-if="sourceType === 'gdrive'">
								@source.GoogleDriveSourceForm()
							</template>
							
							<template x-if="sourceType === 'gphotos'">
								@source.GooglePhotosSourceForm()
							</template>
						</div>
						
						<!-- File Pattern Section -->
						<div class="p-5 bg-white border border-gray-200 rounded-lg shadow-sm dark:bg-gray-800 dark:border-gray-700">
							<h3 class="mb-4 text-xl font-bold text-gray-900 dark:text-white flex items-center">
								<i class="fas fa-filter mr-2 text-blue-500 dark:text-blue-400"></i>File Patterns
							</h3>
							
							<!-- File pattern fields -->
							@common.FilePatternFields()
						</div>
						
						<!-- Destination Configuration Section (only shown if required) -->
						<div x-show="requiresDestination" x-transition class="p-5 bg-white border border-gray-200 rounded-lg shadow-sm dark:bg-gray-800 dark:border-gray-700">
							<h3 class="mb-4 text-xl font-bold text-gray-900 dark:text-white flex items-center">
								<i class="fas fa-download mr-2 text-blue-500 dark:text-blue-400"></i>Destination Configuration
							</h3>
							
							<!-- Destination selection -->
							@common.DestinationSelection()
							
							<!-- Destination type specific forms -->
							<template x-if="destinationType === 'local'">
								@destination.LocalDestinationForm()
							</template>
							
							<template x-if="destinationType === 'sftp'">
								@destination.SFTPDestinationForm()
							</template>

							<template x-if="destinationType === 'ftp'">
								@destination.FTPDestinationForm()
							</template>
							
							<template x-if="destinationType === 's3'">
								@destination.S3DestinationForm()
							</template>
							
							<template x-if="destinationType === 'minio'">
								@destination.MinIODestinationForm()
							</template>
							
							<template x-if="destinationType === 'smb'">
								@destination.SMBDestinationForm()
							</template>	

							<template x-if="destinationType === 'nextcloud'">
								@destination.NextCloudDestinationForm()
							</template>

							<template x-if="destinationType === 'webdav'">
								@destination.WebDAVDestinationForm()
							</template>

							<template x-if="destinationType === 'gdrive'">
								@destination.GoogleDriveDestinationForm()
							</template>
							
							<template x-if="destinationType === 'gphotos'">
								@destination.GooglePhotosDestinationForm()
							</template>
						</div>
						
						<!-- Advanced Options Section -->
						<div class="p-5 bg-white border border-gray-200 rounded-lg shadow-sm dark:bg-gray-800 dark:border-gray-700">
							<h3 class="mb-4 text-xl font-bold text-gray-900 dark:text-white flex items-center">
								<i class="fas fa-cogs mr-2 text-blue-500 dark:text-blue-400"></i>Advanced Options
							</h3>
							
							<!-- Archive options -->
							<div class="mb-6">
								<h4 class="text-lg font-medium text-gray-900 dark:text-white mb-4">Archive Settings</h4>
								@common.ArchiveOptions()
							</div>
							

						</div>
						
						<!-- Form Actions -->
						<div class="flex items-center justify-between pt-6 border-t border-gray-200 dark:border-gray-700">
							<a href="/configs" 
								class="text-white bg-gray-500 hover:bg-gray-600 focus:ring-4 focus:ring-gray-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-gray-600 dark:hover:bg-gray-700 dark:focus:ring-gray-800">
								<i class="fas fa-arrow-left mr-2"></i>Cancel
							</a>
							<button 
								type="submit" 
								class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
								<span class="flex items-center">
									<i class="fas fa-save mr-2"></i>
									if data.IsNew {
										Create Configuration
									} else {
										Save Changes
									}
								</span>
							</button>
						</div>
					</form>
				</div>
				
				<!-- Help Card -->
				<div class="mt-4 p-4 bg-gray-50 border border-gray-200 rounded-lg shadow-sm dark:bg-gray-800 dark:border-gray-700">
					<div class="flex">
						<div class="flex-shrink-0">
							<i class="fas fa-lightbulb text-yellow-400 text-xl"></i>
						</div>
						<div class="ml-4">
							<h5 class="text-sm font-medium text-gray-900 dark:text-white">Configuration Tips</h5>
							<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
								Configure your file transfer settings carefully for optimal performance. Use file patterns to filter which files are transferred, and consider using archive options to keep track of processed files.
							</p>
						</div>
					</div>
				</div>
			</div>
		</section>
	}
} 