<template>
  <div
    v-if="visible"
    class="fixed inset-0 bg-overlay flex justify-center items-center z-50 p-4"
    @click.self="handleCancel"
  >
    <div class="bg-background text-foreground p-6 rounded-lg shadow-xl border border-border w-full max-w-2xl max-h-[90vh] flex flex-col">
      <!-- Header -->
      <div class="flex justify-between items-center pb-4 mb-4 border-b border-border flex-shrink-0">
        <h3 class="text-xl font-semibold">
          {{ t('sendFilesModal.title') }}
        </h3>
        <button
          @click="handleCancel"
          class="text-text-secondary hover:text-foreground transition-colors"
          aria-label="Close modal"
        >
          <i class="fas fa-times text-xl"></i>
        </button>
      </div>

      <!-- Body -->
      <div class="flex-grow overflow-y-auto pr-1 space-y-4">
        <!-- Top Section: Search, Target Path, Transfer Method -->
        <div class="space-y-4">
          <input
            type="text"
            :placeholder="t('sendFilesModal.searchConnectionsPlaceholder')"
            v-model="searchTerm"
            class="w-full px-3 py-2 border border-border rounded-md shadow-sm bg-input text-foreground focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary text-sm"
          />
          <div class="flex flex-col sm:flex-row gap-4">
            <div class="form-group flex-1">
              <label for="targetPath" class="block text-sm font-medium text-text-secondary mb-1">{{ t('sendFilesModal.targetPathLabel') }}</label>
              <input
                type="text"
                id="targetPath"
                v-model="targetPath"
                :placeholder="t('sendFilesModal.targetPathPlaceholder')"
                class="w-full px-3 py-2 border border-border rounded-md shadow-sm bg-input text-foreground focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary text-sm"
              />
            </div>
            <div class="form-group sm:w-48">
              <label for="transferMethod" class="block text-sm font-medium text-text-secondary mb-1">{{ t('sendFilesModal.transferMethodLabel') }}</label>
              <select
                id="transferMethod"
                v-model="transferMethod"
                class="form-select w-full px-3 py-2 border border-border rounded-md shadow-sm bg-input text-foreground focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary text-sm"
              >
                <option value="auto">{{ t('sendFilesModal.transferMethodAuto') }}</option>
                <option value="rsync">rsync</option>
                <option value="scp">scp</option>
              </select>
            </div>
          </div>
        </div>

        <!-- Connections Section -->
        <div class="border border-border rounded-md p-4 space-y-3 max-h-72 overflow-y-auto bg-muted/30">
          <div v-if="isLoadingConnections || isLoadingTags" class="flex items-center justify-center h-24 text-text-secondary">
            <i class="fas fa-spinner fa-spin mr-2"></i> {{ t('sendFilesModal.loadingConnections') }}
          </div>
          <div v-else-if="filteredGroupedConnections.length === 0 && !searchTerm" class="flex flex-col items-center justify-center h-24 text-text-secondary">
            <i class="fas fa-folder-open text-2xl mb-2"></i>
            <p>{{ t('sendFilesModal.noConnections') }}</p>
          </div>
          <div v-else-if="filteredGroupedConnections.length === 0 && searchTerm" class="flex flex-col items-center justify-center h-24 text-text-secondary">
            <i class="fas fa-search text-2xl mb-2"></i>
            <p>{{ t('sendFilesModal.noConnectionsFound') }}</p>
          </div>
          <div v-else class="space-y-3">
            <div v-for="group in filteredGroupedConnections" :key="group.tag ? group.tag.id : 'untagged'" class="tag-group">
              <div class="flex items-center py-1.5">
                <input
                  type="checkbox"
                  :id="'tag-' + (group.tag ? group.tag.id : 'untagged')"
                  :checked="isTagGroupSelected(group)"
                  :indeterminate="isTagGroupIndeterminate(group)"
                  @change="toggleTagGroupSelection(group)"
                  class="mr-2 h-4 w-4 rounded border-border text-primary focus:ring-primary focus:ring-offset-0 cursor-pointer"
                />
                <label :for="'tag-' + (group.tag ? group.tag.id : 'untagged')" class="font-semibold text-foreground select-none cursor-pointer text-sm">
                  {{ group.tag ? group.tag.name : t('sendFilesModal.untaggedConnections') }} ({{ group.connections.length }})
                </label>
              </div>
              <ul class="pl-7 space-y-0.5">
                <li v-for="connection in group.connections" :key="connection.id" class="flex items-center py-0.5">
                  <input
                    type="checkbox"
                    :id="'conn-' + connection.id"
                    :value="connection.id"
                    v-model="selectedConnectionIds"
                    class="mr-2 h-4 w-4 rounded border-border text-primary focus:ring-primary focus:ring-offset-0 cursor-pointer"
                  />
                  <label :for="'conn-' + connection.id" class="text-sm text-foreground select-none cursor-pointer truncate" :title="connection.name">{{ connection.name }}</label>
                </li>
              </ul>
            </div>
          </div>
        </div>

        <!-- Items to Send Summary -->
        <div class="p-3 border border-border rounded-md bg-muted/30 space-y-1">
          <h3 class="text-sm font-semibold text-foreground">{{ t('sendFilesModal.itemsToSendTitle') }}</h3>
          <ul v-if="itemsToSend && itemsToSend.length > 0" class="max-h-24 overflow-y-auto space-y-0.5">
            <li v-for="item in itemsToSend" :key="item.path" class="text-xs text-text-secondary truncate" :title="item.path">
              {{ item.name }}
            </li>
          </ul>
           <p v-else class="text-xs text-text-secondary italic">{{ t('sendFilesModal.noItemsSelected') }}</p>
        </div>
      </div>

      <!-- Footer -->
      <div class="flex justify-end items-center pt-4 mt-auto border-t border-border flex-shrink-0 space-x-3">
        <button
          @click="handleCancel"
          class="px-4 py-2 bg-transparent text-text-secondary border border-border rounded-md shadow-sm hover:bg-border hover:text-foreground focus:outline-none focus:ring-2 focus:ring-offset-background focus:ring-primary disabled:opacity-50 transition-colors duration-150 ease-in-out"
        >
          {{ t('sendFilesModal.cancelButton') }}
        </button>
        <button
          @click="handleSend"
          class="px-4 py-2 bg-button text-button-text rounded-md shadow-sm hover:bg-button-hover focus:outline-none focus:ring-2 focus:ring-offset-background focus:ring-primary disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-150 ease-in-out"
          :disabled="selectedConnectionIds.length === 0 || !targetPath.trim()"
        >
          {{ t('sendFilesModal.sendButton') }}
        </button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { useConnectionsStore, type ConnectionInfo } from '../stores/connections.store';
import { useTagsStore, type TagInfo } from '../stores/tags.store';
import apiClient from '../utils/apiClient';
import { useUiNotificationsStore } from '../stores/uiNotifications.store';

interface ItemToSend {
  name: string;
  path: string;
  type: 'file' | 'directory'; // Type is now mandatory
}

interface SourceItem { // As per backend InitiateTransferPayload
  name: string;
  path: string;
  type: 'file' | 'directory';
}

interface GroupedConnection {
  tag: TagInfo | null;
  connections: ConnectionInfo[];
}

const props = defineProps<{
  visible: boolean;
  itemsToSend: ItemToSend[];
  sourceConnectionId: number | null; // +++ 新增 sourceConnectionId prop +++
}>();

const emit = defineEmits<{
  (e: 'update:visible', value: boolean): void;
  // 'send' emit might become obsolete or change if all logic moves to API call
}>();

const { t } = useI18n();
const connectionsStore = useConnectionsStore();
const tagsStore = useTagsStore();
const uiNotificationsStore = useUiNotificationsStore();

const searchTerm = ref('');
const targetPath = ref('');
const transferMethod = ref<'auto' | 'rsync' | 'scp'>('auto');
const selectedConnectionIds = ref<number[]>([]);

const isLoadingConnections = ref(false);
const isLoadingTags = ref(false);

// Simulate data for itemsToSend for development if not provided
const itemsToSendInternal = computed<ItemToSend[]>(() => {
  if (props.itemsToSend && props.itemsToSend.length > 0) {
    return props.itemsToSend;
  }
  return [
    { name: 'file1.txt', path: '/local/file1.txt', type: 'file' },
    { name: 'folderA', path: '/local/folderA', type: 'directory' },
    { name: 'another-item.zip', path: '/local/another-item.zip', type: 'file' }
  ];
});


onMounted(async () => {
  isLoadingConnections.value = true;
  isLoadingTags.value = true;
  try {
    if (connectionsStore.connections.length === 0) {
      await connectionsStore.fetchConnections();
    }
    if (tagsStore.tags.length === 0) {
      await tagsStore.fetchTags();
    }
  } catch (error) {
    console.error(t('sendFilesModal.errorFetchingData'), error);
    // Optionally, show a user-facing error message
  } finally {
    isLoadingConnections.value = false;
    isLoadingTags.value = false;
  }
});

const allConnections = computed(() => connectionsStore.connections);
const allTags = computed(() => tagsStore.tags);

const groupedConnections = computed<GroupedConnection[]>(() => {
  const groups: Record<string, GroupedConnection> = {};
  const untaggedConnections: ConnectionInfo[] = [];

  allConnections.value.forEach(conn => {
    const connTagIds = conn.tag_ids || [];
    if (connTagIds.length === 0) {
      untaggedConnections.push(conn);
    } else {
      connTagIds.forEach((tagId: number) => {
        const tag = allTags.value.find(t => t.id === tagId);
        if (tag) {
          if (!groups[tag.id]) {
            groups[tag.id] = { tag, connections: [] };
          }
          // Avoid adding duplicate connections to the same group
          if (!groups[tag.id].connections.some(c => c.id === conn.id)) {
            groups[tag.id].connections.push(conn);
          }
        } else {
          // Connection has a tag ID that doesn't exist in tagsStore, treat as untagged for this modal
           // Or handle as an error, or create a "missing tag" group
          if (!untaggedConnections.some(c => c.id === conn.id)) {
            untaggedConnections.push(conn);
          }
        }
      });
    }
  });

  const sortedGroups = Object.values(groups).sort((a, b) =>
    a.tag!.name.localeCompare(b.tag!.name)
  );

  if (untaggedConnections.length > 0) {
    return [...sortedGroups, { tag: null, connections: untaggedConnections }];
  }
  return sortedGroups;
});

const filteredGroupedConnections = computed<GroupedConnection[]>(() => {
  if (!searchTerm.value.trim()) {
    return groupedConnections.value;
  }
  const lowerSearchTerm = searchTerm.value.toLowerCase();
  return groupedConnections.value
    .map(group => {
      const filteredConns = group.connections.filter(conn =>
        conn.name.toLowerCase().includes(lowerSearchTerm)
      );
      return { ...group, connections: filteredConns };
    })
    .filter(group => group.connections.length > 0);
});

const isTagGroupSelected = (group: GroupedConnection): boolean => {
  if (group.connections.length === 0) return false;
  return group.connections.every(conn => selectedConnectionIds.value.includes(conn.id));
};

const isTagGroupIndeterminate = (group: GroupedConnection): boolean => {
  if (group.connections.length === 0) return false;
  const selectedCount = group.connections.filter(conn => selectedConnectionIds.value.includes(conn.id)).length;
  return selectedCount > 0 && selectedCount < group.connections.length;
};

const toggleTagGroupSelection = (group: GroupedConnection) => {
  const groupConnectionIds = group.connections.map(conn => conn.id);
  if (isTagGroupSelected(group)) {
    // Deselect all
    selectedConnectionIds.value = selectedConnectionIds.value.filter(id => !groupConnectionIds.includes(id));
  } else {
    // Select all (or add to selection if partially selected)
    groupConnectionIds.forEach(id => {
      if (!selectedConnectionIds.value.includes(id)) {
        selectedConnectionIds.value.push(id);
      }
    });
  }
};

watch(() => props.visible, (newValue) => {
  if (newValue) {
    // Reset state when modal becomes visible, except perhaps targetPath if desired
    // searchTerm.value = '';
    // selectedConnectionIds.value = [];
    // transferMethod.value = 'auto';
    // If stores might be empty, fetch again or ensure they are fresh
    if (connectionsStore.connections.length === 0) {
      connectionsStore.fetchConnections().catch(error => console.error(t('sendFilesModal.errorFetchingConnections'), error));
    }
    if (tagsStore.tags.length === 0) {
      tagsStore.fetchTags().catch(error => console.error(t('sendFilesModal.errorFetchingTags'), error));
    }
  }
});

const handleSend = async () => {
  if (selectedConnectionIds.value.length === 0 || !targetPath.value.trim()) {
    uiNotificationsStore.showError(t('sendFilesModal.validationError')); // Assuming you add this key
    return;
  }

  const sourceItems: SourceItem[] = itemsToSendInternal.value;

  const payload = {
    sourceConnectionId: props.sourceConnectionId, // +++ 添加 sourceConnectionId 到 payload +++
    connectionIds: [...selectedConnectionIds.value], // 这些是目标服务器IDs
    sourceItems,
    remoteTargetPath: targetPath.value.trim(),
    transferMethod: transferMethod.value,
  };

  // 验证 sourceConnectionId 是否存在
  if (payload.sourceConnectionId === null || payload.sourceConnectionId === undefined) {
    console.error('Source Connection ID is missing in SendFilesModal payload:', payload);
    uiNotificationsStore.showError(t('sendFilesModal.errorSourceConnectionMissing', 'Source server information is missing. Cannot initiate transfer.'));
    return;
  }

  try {
    const response = await apiClient.post('/transfers/send', payload);
    // Assuming the backend returns something like { taskId: "some-id" } on success
    if (response.data && response.data.taskId) {
      uiNotificationsStore.showSuccess(t('sendFilesModal.transferInitiated', { taskId: response.data.taskId }));
    } else {
      uiNotificationsStore.showSuccess(t('sendFilesModal.transferInitiatedGeneric'));
    }
    emit('update:visible', false);
  } catch (error: any) {
    console.error('Failed to initiate transfer:', error);
    const errorMessage = error.response?.data?.message || error.message || t('sendFilesModal.transferFailedError');
    uiNotificationsStore.showError(errorMessage);
    // Do not close modal on error
  }
};

const handleCancel = () => {
  emit('update:visible', false);
};

// Fallback i18n messages are now removed as they are expected to be in the locale JSON files.
</script>
