<template>
  <div class="team-management-view">
    <TeamManagementOverview
      :selected-season-id="selectedSeasonId"
      :scheduler-jobs="schedulerJobs"
      :show-global-job-details="showGlobalJobDetails"
      :teams-count="teams.length"
      :fully-configured-teams-count="fullyConfiguredTeamsCount"
      :partially-configured-teams-count="partiallyConfiguredTeamsCount"
      :teams-without-league-count="teamsWithoutLeagueCount"
      :filtered-team-details="getFilteredTeamDetails(schedulerJobs.match_results?.teamDetails || [])"
      :format-job-date="formatJobDate"
      :filtered-teams="filteredTeams"
      :current-season-label="currentSeason?.season || ''"
      :team-search-query="teamSearchQuery"
      :team-filter="teamFilter"
      :active-team-id="teamToEdit ? teamToEdit.id : null"
      :get-my-tischtennis-status="getMyTischtennisStatus"
      :format-date="formatDate"
      :get-team-job-info="getTeamJobInfo"
      :get-team-documents="getTeamDocuments"
      @update:selected-season-id="selectedSeasonId = $event"
      @season-change="onSeasonChange"
      @toggle-job-details="showGlobalJobDetails = !showGlobalJobDetails"
      @update:team-search-query="teamSearchQuery = $event"
      @update:team-filter="teamFilter = $event"
      @create-new-team="resetToNewTeam(); teamFormIsOpen = true;"
      @edit-team="editTeam"
      @delete-team="deleteTeam"
      @show-pdf-dialog="showPDFDialog"
    />

    <div class="newteam">
      <div class="toggle-new-team">
        <span @click="toggleNewTeam">
          <span class="add">{{ teamFormIsOpen ? '-' : '+' }}</span>
          {{ teamToEdit === null ? t('teamManagement.newTeam') : t('teamManagement.editTeam') }}
        </span>
        <button v-if="teamToEdit !== null" @click="resetToNewTeam">{{ t('teamManagement.createNewTeam') }}</button>
      </div>
      
      <div v-if="teamFormIsOpen" class="new-team-form">
        <div class="workspace-header">
          <div>
            <div class="workspace-label">{{ teamToEdit ? t('teamManagement.activeTeam') : t('teamManagement.newTeam') }}</div>
            <h3>{{ teamToEdit ? teamToEdit.name : t('teamManagement.newTeam') }}</h3>
          </div>
          <div v-if="teamToEdit" class="workspace-meta">
            <span class="workspace-badge" :class="getMyTischtennisStatus(teamToEdit).complete ? 'complete' : (getMyTischtennisStatus(teamToEdit).partial ? 'partial' : 'missing')">
              {{
                getMyTischtennisStatus(teamToEdit).complete
                  ? t('teamManagement.fullyConfigured')
                  : (getMyTischtennisStatus(teamToEdit).partial
                    ? t('teamManagement.partiallyConfigured')
                    : t('teamManagement.notConfigured'))
              }}
            </span>
            <span class="workspace-subtle">{{ teamToEdit.league ? teamToEdit.league.name : t('teamManagement.noLeague') }}</span>
          </div>
        </div>

        <div class="workspace-section-switcher">
          <button type="button" class="workspace-section-button" :class="{ active: activeEditorSection === 'basic' }" @click="activeEditorSection = 'basic'">
            {{ t('teamManagement.basicSettings') }}
          </button>
          <button v-if="teamToEdit && teamToEdit.leagueId" type="button" class="workspace-section-button" :class="{ active: activeEditorSection === 'stats' }" @click="activeEditorSection = 'stats'">
            {{ t('teamManagement.playerStats') }}
          </button>
          <button v-if="teamToEdit" type="button" class="workspace-section-button" :class="{ active: activeEditorSection === 'documents' }" @click="activeEditorSection = 'documents'">
            {{ t('teamManagement.documents') }}
          </button>
          <button v-if="teamToEdit" type="button" class="workspace-section-button" :class="{ active: activeEditorSection === 'jobs' }" @click="activeEditorSection = 'jobs'">
            {{ t('teamManagement.automaticJobs') }}
          </button>
          <button v-if="teamToEdit" type="button" class="workspace-section-button" :class="{ active: activeEditorSection === 'myTischtennis' }" @click="activeEditorSection = 'myTischtennis'">
            {{ t('teamManagement.myTischtennis') }}
          </button>
        </div>

        <div v-if="activeEditorSection === 'basic'" class="workspace-section-panel basic-settings">
            <div class="workspace-panel-header">
              <div>
                <span class="section-title">⚙️ {{ t('teamManagement.basicSettings') }}</span>
                <p class="workspace-panel-copy">{{ t('teamManagement.basicSettingsIntro') }}</p>
              </div>
            </div>
            <div v-if="teamToEdit" class="settings-summary-grid">
              <div class="settings-summary-card">
                <span class="settings-summary-label">{{ t('teamManagement.teamName') }}</span>
                <strong>{{ teamToEdit.name }}</strong>
              </div>
              <div class="settings-summary-card">
                <span class="settings-summary-label">{{ t('teamManagement.league') }}</span>
                <strong>{{ teamToEdit.league ? teamToEdit.league.name : t('teamManagement.noLeague') }}</strong>
              </div>
              <div class="settings-summary-card">
                <span class="settings-summary-label">{{ t('teamManagement.season') }}</span>
                <strong>{{ teamToEdit.season?.season || t('teamManagement.seasonUnknown') }}</strong>
              </div>
            </div>
            <div class="settings-form-grid">
              <label>
                <span>{{ t('teamManagement.teamName') }}:</span> 
                <input type="text" v-model="newTeamName" :placeholder="t('teamManagement.teamNamePlaceholder')">
              </label>
              
              <label>
                <span>{{ t('teamManagement.league') }}:</span>
                <select v-model="newLeagueId">
                  <option value="">{{ t('teamManagement.noLeague') }}</option>
                  <option v-for="league in filteredLeagues" :key="league.id" :value="league.id">
                    {{ league.name }}
                  </option>
                </select>
              </label>
            </div>
            <div class="form-actions">
              <button @click="addNewTeam" :disabled="!newTeamName.trim()">
                {{ teamToEdit ? t('teamManagement.change') : t('teamManagement.createAndEdit') }}
              </button>
              <button @click="resetNewTeam" v-if="teamToEdit === null" class="cancel-action">
                {{ t('teamManagement.clearFields') }}
              </button>
              <button @click="resetToNewTeam" v-if="teamToEdit !== null" class="cancel-action">
                {{ t('teamManagement.createNewTeam') }}
              </button>
            </div>
        </div>

        <div v-if="teamToEdit && teamToEdit.leagueId && activeEditorSection === 'stats'" class="workspace-section-panel player-stats">
          <div class="workspace-panel-header">
            <div>
              <span class="section-title">📊 {{ t('teamManagement.playerStats') }}</span>
              <p class="workspace-panel-copy">{{ t('teamManagement.playerStatsIntro') }}</p>
            </div>
            <button @click="refreshPlayerStats" :disabled="loadingStats" class="btn-sm">
              {{ loadingStats ? '⏳' : '🔄' }} {{ t('teamManagement.refreshStats') }}
            </button>
          </div>
          <div v-if="playerStats.length > 0" class="stats-summary-grid">
            <div class="settings-summary-card">
              <span class="settings-summary-label">{{ t('teamManagement.player') }}</span>
              <strong>{{ playerStats.length }}</strong>
            </div>
            <div class="settings-summary-card">
              <span class="settings-summary-label">{{ t('teamManagement.season') }}</span>
              <strong>{{ totalSeasonAppearances }}</strong>
            </div>
            <div class="settings-summary-card">
              <span class="settings-summary-label">{{ isSecondHalf ? t('teamManagement.secondHalf') : t('teamManagement.firstHalf') }}</span>
              <strong>{{ totalHalfAppearances }}</strong>
            </div>
          </div>
          
          <div v-if="loadingStats" class="loading-stats">{{ t('teamManagement.loadingStats') }}</div>
          
          <div v-else-if="playerStats.length === 0" class="no-stats">
            {{ t('teamManagement.noPlayerStats') }}
          </div>
          
          <table v-else class="stats-table">
            <thead>
              <tr>
                <th>{{ t('teamManagement.player') }}</th>
                <th :title="t('teamManagement.qttr')">(Q)TTR</th>
                <th :title="t('teamManagement.seasonFull')">{{ t('teamManagement.season') }}</th>
                <th :title="isSecondHalf ? t('teamManagement.secondHalfFull') : t('teamManagement.firstHalfFull')">
                  {{ isSecondHalf ? t('teamManagement.secondHalf') : t('teamManagement.firstHalf') }}
                </th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="stat in playerStats" :key="stat.memberId">
                <td class="player-name">{{ stat.firstName }} {{ stat.lastName }}</td>
                <td class="stat-value">
                  <span v-if="memberById[stat.memberId]">
                    {{ memberById[stat.memberId].qttr ?? memberById[stat.memberId].ttr ?? '–' }}
                  </span>
                  <span v-else>–</span>
                </td>
                <td class="stat-value">{{ stat.totalSeason }}</td>
                <td class="stat-value">{{ isSecondHalf ? stat.totalSecondHalf : stat.totalFirstHalf }}</td>
              </tr>
            </tbody>
          </table>
        </div>

        <div v-if="teamToEdit && activeEditorSection === 'documents'" class="workspace-section-panel advanced-settings">
            <div class="workspace-panel-header">
              <div>
                <span class="section-title">📋 {{ t('teamManagement.documents') }}</span>
                <p class="workspace-panel-copy">{{ t('teamManagement.documentsIntro') }}</p>
              </div>
            </div>
            <div class="document-status-grid">
              <div class="document-status-card">
                <div class="document-status-head">
                  <strong>{{ t('teamManagement.codeList') }}</strong>
                  <span class="document-status-badge" :class="getTeamDocuments(teamToEdit.id, 'code_list').length ? 'complete' : 'missing'">
                    {{ getTeamDocuments(teamToEdit.id, 'code_list').length ? t('teamManagement.documentAvailable') : t('teamManagement.documentMissing') }}
                  </span>
                </div>
                <p class="document-status-meta">
                  {{ getLatestTeamDocument(teamToEdit.id, 'code_list') ? t('teamManagement.latestUpload', { date: formatDate(getLatestTeamDocument(teamToEdit.id, 'code_list').createdAt) }) : t('teamManagement.noDocumentUploadYet') }}
                </p>
                <div class="document-status-actions">
                  <button @click="uploadCodeList" class="btn-upload-sm">
                    📋 {{ getTeamDocuments(teamToEdit.id, 'code_list').length ? t('teamManagement.uploadNewVersion') : t('teamManagement.codeList') }}
                  </button>
                  <button
                    v-if="getLatestTeamDocument(teamToEdit.id, 'code_list')"
                    type="button"
                    class="btn-secondary btn-upload-sm"
                    @click="showPDFDialog(teamToEdit.id, 'code_list')"
                  >
                    {{ t('teamManagement.openDocument') }}
                  </button>
                  <button
                    v-if="getLatestTeamDocument(teamToEdit.id, 'code_list')"
                    type="button"
                    class="btn-secondary btn-upload-sm"
                    @click="parsePDF(getLatestTeamDocument(teamToEdit.id, 'code_list'))"
                    :disabled="!!parsingDocuments[getLatestTeamDocument(teamToEdit.id, 'code_list').id]"
                  >
                    {{ t('teamManagement.parseDocument') }}
                  </button>
                </div>
              </div>
              <div class="document-status-card">
                <div class="document-status-head">
                  <strong>{{ t('teamManagement.pinList') }}</strong>
                  <span class="document-status-badge" :class="getTeamDocuments(teamToEdit.id, 'pin_list').length ? 'complete' : 'missing'">
                    {{ getTeamDocuments(teamToEdit.id, 'pin_list').length ? t('teamManagement.documentAvailable') : t('teamManagement.documentMissing') }}
                  </span>
                </div>
                <p class="document-status-meta">
                  {{ getLatestTeamDocument(teamToEdit.id, 'pin_list') ? t('teamManagement.latestUpload', { date: formatDate(getLatestTeamDocument(teamToEdit.id, 'pin_list').createdAt) }) : t('teamManagement.noDocumentUploadYet') }}
                </p>
                <div class="document-status-actions">
                  <button @click="uploadPinList" class="btn-upload-sm">
                    🔐 {{ getTeamDocuments(teamToEdit.id, 'pin_list').length ? t('teamManagement.uploadNewVersion') : t('teamManagement.pinList') }}
                  </button>
                  <button
                    v-if="getLatestTeamDocument(teamToEdit.id, 'pin_list')"
                    type="button"
                    class="btn-secondary btn-upload-sm"
                    @click="showPDFDialog(teamToEdit.id, 'pin_list')"
                  >
                    {{ t('teamManagement.openDocument') }}
                  </button>
                  <button
                    v-if="getLatestTeamDocument(teamToEdit.id, 'pin_list')"
                    type="button"
                    class="btn-secondary btn-upload-sm"
                    @click="parsePDF(getLatestTeamDocument(teamToEdit.id, 'pin_list'))"
                    :disabled="!!parsingDocuments[getLatestTeamDocument(teamToEdit.id, 'pin_list').id]"
                  >
                    {{ t('teamManagement.parseDocument') }}
                  </button>
                </div>
              </div>
            </div>
        </div>

        <div v-if="teamToEdit && activeEditorSection === 'jobs'" class="workspace-section-panel advanced-settings">
          <div v-if="getTeamJobInfo(teamToEdit)" class="team-job-info compact">
              <span class="section-title">🔄 {{ t('teamManagement.automaticJobs') }}</span>
            <div v-if="getTeamJobInfo(teamToEdit).lastRun" class="team-job-details">
              <div class="team-job-item">
                <span class="team-job-label">{{ t('teamManagement.lastUpdated') }}:</span>
                <span class="team-job-value">{{ formatJobDate(getTeamJobInfo(teamToEdit).lastRun) }}</span>
              </div>
              <div v-if="getTeamJobInfo(teamToEdit).success !== null" class="team-job-item">
                <span class="team-job-label">{{ t('teamManagement.status') }}:</span>
                <span v-if="getTeamJobInfo(teamToEdit).success" class="team-job-status success">✓ {{ t('teamManagement.successful') }}</span>
                <span v-else class="team-job-status error">✗ {{ t('teamManagement.error') }}</span>
              </div>
            </div>
            <div v-else class="team-job-details">
              <span class="team-job-no-data">{{ t('teamManagement.noAutomaticUpdate') }}</span>
            </div>
          </div>
        </div>

        <div v-if="teamToEdit && activeEditorSection === 'myTischtennis'" class="workspace-section-panel advanced-settings">
          <div class="mytischtennis-config compact">
            <div class="workspace-panel-header">
              <div>
                <span class="section-title">🏓 {{ t('teamManagement.myTischtennis') }}</span>
                <p class="workspace-panel-copy">{{ t('teamManagement.myTischtennisIntro') }}</p>
              </div>
              <button 
                v-if="getMyTischtennisStatus(teamToEdit).complete"
                @click="fetchTeamDataManually"
                :disabled="fetchingTeamData"
                class="btn-sm"
              >
                {{ fetchingTeamData ? '⏳' : '🔄' }} {{ t('teamManagement.manualFetch') }}
              </button>
            </div>
            <div class="mytt-status-card">
              <div class="mytt-status-line">
                <span class="mytt-status-label">{{ t('teamManagement.configurationStatus') }}</span>
                <span v-if="getMyTischtennisStatus(teamToEdit).complete" class="status-badge complete">✓ {{ t('teamManagement.fullyConfigured') }}</span>
                <span v-else-if="getMyTischtennisStatus(teamToEdit).partial" class="status-badge partial">⚠ {{ t('teamManagement.partiallyConfigured') }}</span>
                <span v-else class="status-badge missing">✗ {{ t('teamManagement.notConfigured') }}</span>
              </div>
              <p v-if="getMyTischtennisStatus(teamToEdit).missing" class="mytt-status-copy">
                {{ getMyTischtennisStatus(teamToEdit).missing }}
              </p>
              <p v-else class="mytt-status-copy">
                {{ t('teamManagement.noIssues') }}
              </p>
            </div>
            
            <div class="compact-input-row">
              <input 
                type="text" 
                v-model="myTischtennisUrl" 
                @keyup.enter="parseMyTischtennisUrl"
                :placeholder="t('teamManagement.myTischtennisUrlPlaceholder')"
                class="compact-url-input"
                :disabled="parsingUrl"
              >
              <button type="button" class="btn-secondary btn-upload-sm" @click="parseMyTischtennisUrl" :disabled="parsingUrl || !myTischtennisUrl.trim()">
                {{ parsingUrl ? '⏳' : t('teamManagement.parseUrlAction') }}
              </button>
            </div>
            
            <div v-if="myTischtennisError" class="compact-message error">⚠️ {{ myTischtennisError }}</div>
            <div v-if="myTischtennisSuccess" class="compact-message success">✅ {{ myTischtennisSuccess }}</div>
          </div>
        </div>
      </div>
    </div>
    
    <!-- PDF-Dialog -->
    <div v-if="showPDFViewer" class="pdf-dialog-overlay" @click="closePDFDialog">
      <div class="pdf-dialog" @click.stop>
        <div class="pdf-dialog-header">
          <h3>{{ pdfDialogTitle }}</h3>
          <button @click="closePDFDialog" class="close-btn">✕</button>
        </div>
        <div class="pdf-dialog-content">
          <iframe 
            v-if="pdfUrl" 
            :src="pdfUrl" 
            class="pdf-viewer"
            frameborder="0"
          ></iframe>
          <div v-else class="no-pdf">
            <p>PDF konnte nicht geladen werden.</p>
          </div>
        </div>
      </div>
    </div>
    
    <!-- Info Dialog -->
    <InfoDialog
        v-model="infoDialog.isOpen"
        :title="infoDialog.title"
        :message="infoDialog.message"
        :details="infoDialog.details"
        :type="infoDialog.type"
    />
    
    <!-- Confirm Dialog -->
    <ConfirmDialog
        v-model="confirmDialog.isOpen"
        :title="confirmDialog.title"
        :message="confirmDialog.message"
        :details="confirmDialog.details"
        :type="confirmDialog.type"
        @confirm="handleConfirmResult(true)"
        @cancel="handleConfirmResult(false)"
    />
  </div>
</template>

<script>
import { ref, onMounted, computed, watch } from 'vue';
import { useStore } from 'vuex';
import SeasonSelector from '../components/SeasonSelector.vue';
import apiClient from '../apiClient.js';
import { getSafeErrorMessage, getSafeMessage } from '../utils/errorMessages.js';
import i18n from '../i18n';

import InfoDialog from '../components/InfoDialog.vue';
import ConfirmDialog from '../components/ConfirmDialog.vue';
import TeamListCard from '../components/team/TeamListCard.vue';
import TeamManagementOverview from '../components/team/TeamManagementOverview.vue';
import { buildInfoConfig, buildConfirmConfig } from '../utils/dialogUtils.js';

export default {
  name: 'TeamManagementView',
  components: {
    SeasonSelector,
    InfoDialog,
    ConfirmDialog,
    TeamListCard,
    TeamManagementOverview
  },
  setup() {
    const store = useStore();
    const t = (key, params) => i18n.global.t(key, params);
    
    // Dialog States
    const infoDialog = ref({
      isOpen: false,
      title: '',
      message: '',
      details: '',
      type: 'info',
      size: 'small',
      closeOnOverlay: true,
    });
    const confirmDialog = ref({
      isOpen: false,
      title: '',
      message: '',
      details: '',
      type: 'info',
      confirmText: t('common.confirm'),
      cancelText: t('common.cancel'),
      showCancel: true,
      resolveCallback: null
    });
    
    // Reactive data
    const teams = ref([]);
    const leagues = ref([]);
    const teamFormIsOpen = ref(false);
    const teamToEdit = ref(null);
    const newTeamName = ref('');
    const newLeagueId = ref('');
    const selectedSeasonId = ref(null);
    const currentSeason = ref(null);
    const teamDocuments = ref([]);
    const parsingInProgress = ref(false);
    const parsingDocuments = ref({});
    const teamSearchQuery = ref('');
    const teamFilter = ref('all');
    const activeEditorSection = ref('basic');
    const showGlobalJobDetails = ref(false);
    
    // PDF-Dialog Variablen
    const showPDFViewer = ref(false);
    const pdfUrl = ref('');
    const pdfDialogTitle = ref('');
    
    // MyTischtennis URL Parser
    const myTischtennisUrl = ref('');
    const parsedMyTischtennisData = ref(null);
    const parsingUrl = ref(false);
    const configuringTeam = ref(false);
    const fetchingTeamData = ref(false);
    const myTischtennisError = ref('');
    const myTischtennisSuccess = ref('');
    
    // Player Stats
    const playerStats = ref([]);
    const loadingStats = ref(false);
    const memberById = ref({});
    
    // Scheduler Jobs Info
    const schedulerJobs = ref({
      rating_updates: null,
      match_results: null
    });
    
    // Computed
    const selectedClub = computed(() => store.state.currentClub);
    const authToken = computed(() => store.state.token);
    const filteredLeagues = computed(() => {
      if (!selectedSeasonId.value) return [];
      return leagues.value.filter(league => league.seasonId == selectedSeasonId.value);
    });
    const isSecondHalf = computed(() => {
      const now = new Date();
      return now.getMonth() >= 0 && now.getMonth() <= 5; // Januar (0) bis Juni (5) = Rückrunde
    });
    const fullyConfiguredTeamsCount = computed(() => teams.value.filter(team => getMyTischtennisStatus(team).complete).length);
    const partiallyConfiguredTeamsCount = computed(() => teams.value.filter(team => getMyTischtennisStatus(team).partial).length);
    const teamsWithoutLeagueCount = computed(() => teams.value.filter(team => !team.leagueId).length);
    const totalSeasonAppearances = computed(() => playerStats.value.reduce((sum, stat) => sum + (Number(stat.totalSeason) || 0), 0));
    const totalHalfAppearances = computed(() => playerStats.value.reduce((sum, stat) => sum + (Number(isSecondHalf.value ? stat.totalSecondHalf : stat.totalFirstHalf) || 0), 0));
    const filteredTeams = computed(() => {
      const search = teamSearchQuery.value.trim().toLowerCase();
      return teams.value.filter(team => {
        const status = getMyTischtennisStatus(team);
        const matchesSearch = !search || [
          team.name,
          team.league?.name,
          team.season?.season
        ].filter(Boolean).some(value => String(value).toLowerCase().includes(search));

        if (!matchesSearch) return false;

        if (teamFilter.value === 'configured') return status.complete;
        if (teamFilter.value === 'attention') return !status.complete;
        if (teamFilter.value === 'noLeague') return !team.leagueId;
        return true;
      });
    });
    
    // Methods
    const toggleNewTeam = () => {
      teamFormIsOpen.value = !teamFormIsOpen.value;
      if (!teamFormIsOpen.value) {
        resetNewTeam();
      }
    };
    
    const resetToNewTeam = () => {
      teamToEdit.value = null;
      activeEditorSection.value = 'basic';
      resetNewTeam();
    };
    
    const resetNewTeam = () => {
      newTeamName.value = '';
      newLeagueId.value = '';
      activeEditorSection.value = 'basic';
    };
    
    const loadTeams = async () => {
      if (!selectedClub.value || !selectedSeasonId.value) {
        return;
      }
      
      try {
        const response = await apiClient.get(`/club-teams/club/${selectedClub.value}?seasonid=${selectedSeasonId.value}`);
        teams.value = response.data;
        
        // Lade alle Team-Dokumente nach dem Laden der Teams
        await loadAllTeamDocuments();
        
        // Aktualisiere Job-Informationen, damit Team-Filterung korrekt funktioniert
        await loadSchedulerJobsInfo();
      } catch (error) {
        console.error('Fehler beim Laden der Club-Teams:', error);
      }
    };
    
    const loadLeagues = async () => {
      if (!selectedClub.value) return;
      
      try {
        const seasonParam = selectedSeasonId.value ? `?seasonid=${selectedSeasonId.value}` : '';
        const response = await apiClient.get(`/club-teams/leagues/${selectedClub.value}${seasonParam}`);
        leagues.value = response.data;
      } catch (error) {
        console.error('Fehler beim Laden der Spielklassen:', error);
      }
    };
    
    const addNewTeam = async () => {
      if (!newTeamName.value.trim() || !selectedClub.value || !selectedSeasonId.value) return;
      
      try {
        const teamData = {
          name: newTeamName.value.trim(),
          leagueId: newLeagueId.value || null,
          seasonId: selectedSeasonId.value
        };
        
        if (teamToEdit.value) {
          // Bearbeitung eines bestehenden Teams
          await apiClient.put(`/club-teams/${teamToEdit.value.id}`, teamData);
          await loadTeams();
          resetNewTeam();
          teamFormIsOpen.value = false;
          teamToEdit.value = null;
        } else {
          // Erstellen eines neuen Teams
          const response = await apiClient.post(`/club-teams/club/${selectedClub.value}`, teamData);
          const newTeam = response.data;
          
          await loadTeams();
          
          // Neues Team automatisch auswählen und bearbeiten
          teamToEdit.value = newTeam;
          newTeamName.value = newTeam.name;
          newLeagueId.value = newTeam.leagueId || '';
          teamFormIsOpen.value = true; // Formular bleibt offen für weitere Bearbeitung
        }
      } catch (error) {
        console.error('Fehler beim Speichern des Club-Teams:', error);
      }
    };
    
    const editTeam = async (team) => {
      teamToEdit.value = team;
      newTeamName.value = team.name;
      newLeagueId.value = team.leagueId || '';
      teamFormIsOpen.value = true;
      activeEditorSection.value = 'basic';
      await loadTeamDocuments();
      // Aktualisiere Job-Informationen, damit Team-spezifische Daten aktuell sind
      await loadSchedulerJobsInfo();
    };
    
    const deleteTeam = async (team) => {
      const confirmed = await showConfirm(
        t('teamManagement.deleteTeamTitle'),
        t('teamManagement.deleteTeamConfirm', { name: team.name }),
        '',
        'danger'
      );
      if (!confirmed) {
        return;
      }
      
      try {
        await apiClient.delete(`/club-teams/${team.id}`);
        await loadTeams();
      } catch (error) {
        console.error('Fehler beim Löschen des Club-Teams:', error);
        await showInfo(t('messages.error'), getSafeErrorMessage(error, t('teamManagement.errorDeletingTeam')), '', 'error');
      }
    };

    const uploadCodeList = () => {
      if (!teamToEdit.value) return;
      if (parsingInProgress.value) {
        return;
      }
      
      const input = document.createElement('input');
      input.type = 'file';
      input.accept = '.pdf,.doc,.docx,.txt,.csv';
      input.onchange = async (event) => {
        const file = event.target.files[0];
        if (!file) return;
        await uploadAndParseDocument(file, 'code_list');
      };
      input.click();
    };

    const uploadPinList = () => {
      if (!teamToEdit.value) return;
      if (parsingInProgress.value) {
        return;
      }
      
      const input = document.createElement('input');
      input.type = 'file';
      input.accept = '.pdf,.doc,.docx,.txt,.csv';
      input.onchange = async (event) => {
        const file = event.target.files[0];
        if (!file) return;
        await uploadAndParseDocument(file, 'pin_list');
      };
      input.click();
    };
    
    const formatDate = (dateString) => {
      return new Date(dateString).toLocaleDateString('de-DE');
    };

    const formatFileSize = (bytes) => {
      if (bytes === 0) return '0 Bytes';
      const k = 1024;
      const sizes = ['Bytes', 'KB', 'MB', 'GB'];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    };
    
    const formatJobDate = (dateString) => {
      if (!dateString) return t('myTischtennisAccount.never');
      const date = new Date(dateString);
      const now = new Date();
      const diffMs = now - date;
      const diffMins = Math.floor(diffMs / 60000);
      const diffHours = Math.floor(diffMs / 3600000);
      const diffDays = Math.floor(diffMs / 86400000);
      
      if (diffMins < 1) return t('myTischtennisAccount.justNow');
      if (diffMins < 60) return t('myTischtennisAccount.minutesAgo', { count: diffMins });
      if (diffHours < 24) return t('myTischtennisAccount.hoursAgo', { count: diffHours });
      if (diffDays === 1) return t('myTischtennisAccount.yesterday');
      if (diffDays < 7) return t('myTischtennisAccount.daysAgo', { count: diffDays });
      
      // Format: DD.MM.YYYY HH:MM
      return date.toLocaleDateString('de-DE', {
        day: '2-digit',
        month: '2-digit',
        year: 'numeric',
        hour: '2-digit',
        minute: '2-digit'
      });
    };

    const loadTeamDocuments = async () => {
      if (!teamToEdit.value) return;
      
      try {
        const response = await apiClient.get(`/team-documents/club-team/${teamToEdit.value.id}`);
        teamDocuments.value = response.data;
      } catch (error) {
        console.error('Fehler beim Laden der Team-Dokumente:', error);
      }
    };
    
    const loadAllTeamDocuments = async () => {
      if (!selectedClub.value) return;
      
      try {
        // Lade alle Dokumente für alle Teams des Clubs
        const allDocuments = [];
        for (const team of teams.value) {
          try {
            const response = await apiClient.get(`/team-documents/club-team/${team.id}`);
            allDocuments.push(...response.data);
          } catch (error) {
            continue;
          }
        }
        teamDocuments.value = allDocuments;
      } catch (error) {
        console.error('Fehler beim Laden aller Team-Dokumente:', error);
      }
    };

    const uploadAndParseDocument = async (file, documentType) => {
      if (!teamToEdit.value?.leagueId) {
        await showInfo(
          t('messages.warning'),
          t('teamManagement.teamHasNoLeague'),
          t('teamManagement.assignLeagueBeforeDocuments'),
          'warning'
        );
        return;
      }

      if (parsingInProgress.value) {
        return;
      }

      parsingInProgress.value = true;

      try {
        const documentLabel = documentType === 'code_list' ? t('teamManagement.codeList') : t('teamManagement.pinList');
        const isValid = await validateTeamDocumentFile(file, documentLabel);
        if (!isValid) {
          return;
        }

        const formData = new FormData();
        formData.append('document', file);
        formData.append('documentType', documentType);

        const uploadResponse = await apiClient.post(`/team-documents/club-team/${teamToEdit.value.id}/upload`, formData, {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        });

        const fileExtension = file.name.toLowerCase().split('.').pop();

        if (fileExtension === 'pdf' || fileExtension === 'txt') {
          const parseResponse = await apiClient.post(`/team-documents/${uploadResponse.data.id}/parse?leagueid=${teamToEdit.value.leagueId}`);
          const { parseResult, saveResult } = parseResponse.data;

          let message = t('teamManagement.documentParsedSummary', {
            label: documentLabel,
            matchesFound: parseResult.matchesFound,
            created: saveResult.created,
            updated: saveResult.updated
          });

          if (saveResult.errors.length > 0) {
            message += `\n\n${t('teamManagement.errorsCount', { count: saveResult.errors.length })}\n`;
            message += saveResult.errors.slice(0, 3).join('\n');
            if (saveResult.errors.length > 3) {
              message += `\n${t('teamManagement.moreErrors', { count: saveResult.errors.length - 3 })}`;
            }
          }

          let dialogTitle = t('messages.success');
          let dialogType = 'success';

          if (parseResult.matchesFound === 0) {
            dialogTitle = t('teamManagement.noMatchesFoundTitle');
            dialogType = 'warning';
            if (parseResult.debugInfo) {
              message += `\n\n${t('teamManagement.noMatchesFoundDetails', { lines: parseResult.debugInfo.totalLines })}`;
            }
          } else if (saveResult.errors.length > 0) {
            dialogTitle = t('messages.warning');
            dialogType = 'warning';
          }

          await showInfo(dialogTitle, message, '', dialogType);
        } else {
          await showInfo(t('messages.info'), t('teamManagement.documentUploaded', { label: documentLabel, fileName: file.name }), '', 'info');
        }

        await loadTeamDocuments();
      } catch (error) {
        console.error('Fehler beim Hochladen und Parsen der Datei:', error);
        const message = getSafeErrorMessage(error, t('teamManagement.errorUploadingDocument'));
        await showInfo(t('messages.error'), message, '', 'error');
      } finally {
        parsingInProgress.value = false;
      }
    };

    const parsePDF = async (document) => {
      const team = teams.value.find(t => t.id === document.clubTeamId);
      if (!team || !team.leagueId) {
        await showInfo(
          t('messages.warning'),
          t('teamManagement.teamHasNoLeague'),
          t('teamManagement.assignLeagueBeforeParsing'),
          'warning'
        );
        return;
      }

      if (parsingDocuments.value[document.id]) {
        return;
      }

      parsingDocuments.value = {
        ...parsingDocuments.value,
        [document.id]: true
      };
      
      try {
        const response = await apiClient.post(`/team-documents/${document.id}/parse?leagueid=${team.leagueId}`);
        const { parseResult, saveResult } = response.data;

        let message = t('teamManagement.matchesSummary', {
          matchesFound: parseResult.matchesFound,
          created: saveResult.created,
          updated: saveResult.updated
        });

        let dialogTitle = t('messages.success');
        let dialogType = 'success';

        if (parseResult.matchesFound === 0) {
          dialogTitle = t('teamManagement.noMatchesFoundTitle');
          dialogType = 'warning';
          if (parseResult.debugInfo) {
            message += `\n\n${t('teamManagement.noMatchesFoundDetails', { lines: parseResult.debugInfo.totalLines })}`;
          }
        } else if (saveResult.errors.length > 0) {
          dialogTitle = t('messages.warning');
          dialogType = 'warning';
          message += `\n\n${t('teamManagement.errorsCount', { count: saveResult.errors.length })}\n`;
          message += saveResult.errors.slice(0, 3).join('\n');
          if (saveResult.errors.length > 3) {
            message += `\n${t('teamManagement.moreErrors', { count: saveResult.errors.length - 3 })}`;
          }
        }

        await showInfo(dialogTitle, message, '', dialogType);
        await loadTeamDocuments();
      } catch (error) {
        console.error('Fehler beim Parsen der PDF:', error);
        const responseData = error?.response?.data || {};
        const status = error?.response?.status;
        let errorMessage = getSafeErrorMessage(error, t('teamManagement.errorParsingPdf'));
        let details = '';

        if (status === 404 && responseData.error === 'documentnotfound') {
          errorMessage = t('teamManagement.documentNotFound');
        } else if (status === 400 && responseData.error === 'missingleagueid') {
          errorMessage = t('teamManagement.missingLeagueForTeam');
        } else if (error.code === 'ENOENT' || (typeof error?.message === 'string' && error.message.includes('ENOENT'))) {
          errorMessage = t('teamManagement.pdfFileNotFound');
          details = t('teamManagement.reuploadFile');
        }

        await showInfo(t('messages.error'), errorMessage, details, 'error');
      } finally {
        const { [document.id]: _ignored, ...rest } = parsingDocuments.value;
        parsingDocuments.value = rest;
      }
    };
    
    const onSeasonChange = (season) => {
      if (season) {
        currentSeason.value = season;
        selectedSeasonId.value = season.id;
        loadTeams();
        loadLeagues();
      }
    };
    
    // Load scheduler jobs info
    const loadSchedulerJobsInfo = async () => {
      try {
        const clubIdParam = selectedClub.value ? `?clubId=${selectedClub.value}` : '';
        const response = await apiClient.get(`/logs/scheduler/last-executions${clubIdParam}`);
        if (response.data.success) {
          schedulerJobs.value = response.data.data;
        }
      } catch (error) {
        console.error('Fehler beim Laden der Job-Informationen:', error);
      }
    };
    
    // Filter team details to only show teams from current club
    const getFilteredTeamDetails = (teamDetails) => {
      if (!teamDetails || !selectedClub.value) return teamDetails;
      // Filter by checking if team exists in current club's teams
      return teamDetails.filter(team => {
        return teams.value.some(t => t.id === team.clubTeamId);
      });
    };
    
    // Get job info for a specific team
    const getTeamJobInfo = (team) => {
      if (!team || !team.id || !schedulerJobs.value.match_results?.teamDetails) {
        return null;
      }
      
      const teamDetail = schedulerJobs.value.match_results.teamDetails.find(
        td => td.clubTeamId === team.id
      );
      
      if (!teamDetail) {
        return null;
      }
      
      return {
        lastRun: teamDetail.lastRun,
        success: teamDetail.success
      };
    };
    
    // Lifecycle
    onMounted(async () => {
      // Lade Ligen beim ersten Laden der Seite (ohne Saison-Filter)
      await loadLeagues();
      // Lade Job-Informationen
      await loadSchedulerJobsInfo();
      
      // Warte kurz, damit SeasonSelector die Saison setzen kann
      // Dann lade Teams, falls eine Saison ausgewählt wurde
      setTimeout(() => {
        if (selectedSeasonId.value && selectedClub.value) {
          loadTeams();
        }
      }, 100);
    });
    
    // PDF-Dialog Funktionen
    const getTeamDocuments = (teamId, documentType) => {
      return teamDocuments.value.filter(doc => 
        doc.clubTeamId === teamId && doc.documentType === documentType
      );
    };

    const getLatestTeamDocument = (teamId, documentType) => {
      return getTeamDocuments(teamId, documentType)
        .slice()
        .sort((a, b) => new Date(b.createdAt || 0) - new Date(a.createdAt || 0))[0] || null;
    };
    
    const showPDFDialog = async (teamId, documentType) => {
      const documents = getTeamDocuments(teamId, documentType);
      if (documents.length === 0) return;
      
      const document = documents[0]; // Nehme das erste Dokument
      const team = teams.value.find(t => t.id === teamId);
      
      pdfDialogTitle.value = `${team?.name || t('teamManagement.team')} - ${documentType === 'code_list' ? t('teamManagement.codeList') : t('teamManagement.pinList')}`;
      
      try {
        // Lade das PDF über die API
        const response = await apiClient.get(`/team-documents/${document.id}/download`, {
          responseType: 'blob'
        });
        
        // Erstelle eine URL für das PDF
        const blob = new Blob([response.data], { type: 'application/pdf' });
        pdfUrl.value = URL.createObjectURL(blob);
        showPDFViewer.value = true;
      } catch (error) {
        console.error('Fehler beim Laden des PDFs:', error);
        await showInfo(t('messages.error'), t('teamManagement.errorLoadingPdf'), '', 'error');
      }
    };
    
    const closePDFDialog = () => {
      showPDFViewer.value = false;
      if (pdfUrl.value) {
        URL.revokeObjectURL(pdfUrl.value);
        pdfUrl.value = '';
      }
    };
    
    // Dialog Helper Methods
    const showInfo = async (title, message, details = '', type = 'info') => {
      infoDialog.value = buildInfoConfig({ title, message, details, type });
    };
    
    const showConfirm = async (title, message, details = '', type = 'info', options = {}) => {
      return new Promise((resolve) => {
        confirmDialog.value = buildConfirmConfig({
          title,
          message,
          details,
          type,
          resolveCallback: resolve,
          ...options,
        });
      });
    };
    
    const handleConfirmResult = (confirmed) => {
      if (confirmDialog.value.resolveCallback) {
        confirmDialog.value.resolveCallback(confirmed);
        confirmDialog.value.resolveCallback = null;
      }
      confirmDialog.value.isOpen = false;
    };
    
    // MyTischtennis URL Parser Methods
    const parseMyTischtennisUrl = async () => {
      if (!myTischtennisUrl.value || !myTischtennisUrl.value.trim()) {
        return;
      }
      
      parsingUrl.value = true;
      myTischtennisError.value = '';
      myTischtennisSuccess.value = '';
      parsedMyTischtennisData.value = null;
      
      try {
        const response = await apiClient.post('/mytischtennis/parse-url', {
          url: myTischtennisUrl.value.trim()
        });
        
        if (response.data.success) {
          parsedMyTischtennisData.value = response.data.data;
          
          // Automatisch konfigurieren
          await configureTeamFromUrl();
        }
      } catch (error) {
        console.error('Fehler beim Parsen der URL:', error);
        myTischtennisError.value = getSafeErrorMessage(error, t('teamManagement.errorParsingUrl'));
        await showInfo(t('messages.error'), myTischtennisError.value, '', 'error');
      } finally {
        parsingUrl.value = false;
      }
    };
    
    const configureTeamFromUrl = async () => {
      if (!parsedMyTischtennisData.value) {
        return;
      }
      
      // Für Tabellen-URLs: Biete Liga-Konfiguration an
      if (parsedMyTischtennisData.value.urlType === 'table') {
        const confirmed = await showConfirm(
          t('teamManagement.configureLeagueTitle'),
          t('teamManagement.tableUrlDetected'),
          t('teamManagement.configureLeagueDetails', {
            association: parsedMyTischtennisData.value.association,
            season: parsedMyTischtennisData.value.season,
            league: parsedMyTischtennisData.value.groupname,
            groupId: parsedMyTischtennisData.value.groupId
          }),
          'info'
        );
        
        if (confirmed) {
          await configureLeagueFromUrl();
        }
        return;
      }
      
      // Für Team-URLs: Normale Konfiguration
      if (!teamToEdit.value) {
        await showInfo(
          t('teamManagement.selectTeamTitle'),
          t('teamManagement.selectTeamFirst'),
          t('teamManagement.selectTeamForConfiguration'),
          'warning'
        );
        return;
      }
      
      configuringTeam.value = true;
      myTischtennisError.value = '';
      myTischtennisSuccess.value = '';
      
      try {
        const response = await apiClient.post('/mytischtennis/configure-team', {
          url: myTischtennisUrl.value.trim(),
          clubTeamId: teamToEdit.value.id,
          createLeague: true,
          createSeason: true
        });
        
        if (response.data.success) {
          myTischtennisSuccess.value = t('teamManagement.teamConfiguredSuccess');
          await showInfo(
            t('messages.success'),
            t('teamManagement.teamConfiguredSuccess'),
            t('teamManagement.teamConfiguredDetails', {
              league: response.data.data.league.name,
              season: response.data.data.season.name
            }),
            'success'
          );
          
          // Teams und Ligen neu laden
          await loadTeams();
          await loadLeagues();
          
          // Aktuelles Team mit neuen Daten aktualisieren
          if (teamToEdit.value) {
            const updatedTeam = teams.value.find(t => t.id === teamToEdit.value.id);
            if (updatedTeam) {
              teamToEdit.value = updatedTeam;
              // Team-Dokumente neu laden
              await loadTeamDocuments();
            }
          }
          
          // Parsed Data löschen
          clearParsedData();
        }
      } catch (error) {
        console.error('Fehler bei der Konfiguration:', error);
        myTischtennisError.value = getSafeErrorMessage(error, t('teamManagement.errorConfiguringTeam'));
        await showInfo(t('messages.error'), myTischtennisError.value, '', 'error');
      } finally {
        configuringTeam.value = false;
      }
    };
    
    const configureLeagueFromUrl = async () => {
      if (!parsedMyTischtennisData.value || parsedMyTischtennisData.value.urlType !== 'table') {
        return;
      }
      
      configuringTeam.value = true;
      myTischtennisError.value = '';
      myTischtennisSuccess.value = '';
      
      try {
        const response = await apiClient.post('/mytischtennis/configure-league', {
          url: myTischtennisUrl.value.trim(),
          createSeason: true
        });
        
        if (response.data.success) {
          myTischtennisSuccess.value = t('teamManagement.leagueConfiguredSuccess');
          await showInfo(
            t('messages.success'),
            t('teamManagement.leagueConfiguredSuccess'),
            t('teamManagement.leagueConfiguredDetails', {
              league: response.data.data.league.name,
              season: response.data.data.season?.name || t('teamManagement.notCreated'),
              association: response.data.data.league.association,
              groupId: response.data.data.league.myTischtennisGroupId
            }),
            'success'
          );
          
          // Teams und Ligen neu laden
          await loadTeams();
          await loadLeagues();
          
          // Parsed Data löschen
          clearParsedData();
        }
      } catch (error) {
        console.error('Fehler bei der Liga-Konfiguration:', error);
        myTischtennisError.value = getSafeErrorMessage(error, t('teamManagement.errorConfiguringLeague'));
        await showInfo(t('messages.error'), myTischtennisError.value, '', 'error');
      } finally {
        configuringTeam.value = false;
      }
    };
    
    const clearParsedData = () => {
      parsedMyTischtennisData.value = null;
      myTischtennisUrl.value = '';
      myTischtennisError.value = '';
      myTischtennisSuccess.value = '';
    };
    
    const getMyTischtennisStatus = (team) => {
      if (!team) {
        return { complete: false, partial: false, missing: '', tooltip: '' };
      }
      
      const hasTeamId = !!team.myTischtennisTeamId;
      const hasLeague = !!team.league;
      const hasLeagueConfig = hasLeague && 
        !!team.league.myTischtennisGroupId && 
        !!team.league.association && 
        !!team.league.groupname;
      
      const missingItems = [];
      if (!hasTeamId) missingItems.push(t('teamManagement.teamId'));
      if (!hasLeague) missingItems.push(t('teamManagement.league'));
      if (hasLeague && !team.league.myTischtennisGroupId) missingItems.push(t('teamManagement.groupId'));
      if (hasLeague && !team.league.association) missingItems.push(t('teamManagement.association'));
      if (hasLeague && !team.league.groupname) missingItems.push(t('teamManagement.groupName'));
      
      const complete = hasTeamId && hasLeagueConfig;
      const partial = (hasTeamId || hasLeagueConfig) && !complete;
      
      let tooltip = '';
      if (complete) {
        tooltip = t('teamManagement.autoFetchEnabled');
      } else if (partial) {
        tooltip = t('teamManagement.missingItems', { items: missingItems.join(', ') });
      } else {
        tooltip = t('teamManagement.enterUrlForAutoConfig');
      }
      
      return {
        complete,
        partial,
        missing: missingItems.length > 0 ? t('teamManagement.missingItems', { items: missingItems.join(', ') }) : '',
        tooltip
      };
    };
    
    const refreshPlayerStats = async () => {
      if (!teamToEdit.value || !teamToEdit.value.leagueId) {
        return;
      }
      
      loadingStats.value = true;
      
      try {
        // Mitglieder mit (Q)TTR laden, um Werte anzuzeigen
        try {
          const membersResp = await apiClient.get(`/clubmembers/get/${selectedClub.value}/true`);
          const map = {};
          for (const m of membersResp.data || []) {
            map[m.id] = { ttr: m.ttr ?? null, qttr: m.qttr ?? null };
          }
          memberById.value = map;
        } catch (e) {
          memberById.value = {};
        }

        const response = await apiClient.get(
          `/matches/leagues/${selectedClub.value}/stats/${teamToEdit.value.leagueId}`,
          {
            params: { seasonid: currentSeason.value?.id }
          }
        );
        
        playerStats.value = response.data;
      } catch (error) {
        console.error('Error loading player stats:', error);
        await showInfo(t('messages.error'), t('teamManagement.errorLoadingStats'), '', 'danger');
      } finally {
        loadingStats.value = false;
      }
    };
    
    const fetchTeamDataManually = async () => {
      if (!teamToEdit.value || !teamToEdit.value.id) {
        return;
      }
      
      fetchingTeamData.value = true;
      myTischtennisError.value = '';
      myTischtennisSuccess.value = '';
      
      try {

        const startResponse = await apiClient.post('/mytischtennis/fetch-team-data/async', {
          clubTeamId: teamToEdit.value.id
        });

        const jobId = startResponse?.data?.jobId;
        if (!jobId) {
          throw new Error(t('teamManagement.asyncJobStartFailed'));
        }

        const maxPollAttempts = 120; // ~4 Minuten bei 2s Intervall
        let completedResponse = null;
        for (let attempt = 0; attempt < maxPollAttempts; attempt++) {
          await new Promise((resolve) => setTimeout(resolve, 2000));
          const pollResponse = await apiClient.get(`/mytischtennis/fetch-team-data/jobs/${jobId}`, {
            timeout: 15000
          });
          const job = pollResponse?.data?.job;
          if (!job) continue;

          if (job.status === 'completed') {
            completedResponse = job.result;
            break;
          }

          if (job.status === 'failed') {
            const failedMsg = getSafeMessage(job.error, t('teamManagement.dataFetchFailed'));
            throw new Error(failedMsg);
          }
        }

        if (!completedResponse) {
          throw new Error(t('teamManagement.fetchTimedOut'));
        }

        if (completedResponse && completedResponse.success) {
          const successMessage = getSafeMessage(completedResponse.message, t('teamManagement.teamDataFetched'));
          myTischtennisSuccess.value = successMessage;
          
          const teamName = getSafeMessage(completedResponse.data?.teamName, teamToEdit.value?.name || t('teamManagement.unknownTeam'));
          const fetchedCount = getSafeMessage(String(completedResponse.data?.fetchedCount ?? ''), '0');
          let detailsMessage = t('teamManagement.teamDataFetchedDetails', { team: teamName, count: fetchedCount });
          
          if (completedResponse.data?.tableUpdate) {
            const tableUpdate = getSafeMessage(completedResponse.data.tableUpdate);
            if (tableUpdate) {
              detailsMessage += `\n\n${t('teamManagement.tableUpdateLabel')}\n${tableUpdate}`;
            }
          }
          
          await showInfo(
            t('messages.success'),
            successMessage,
            detailsMessage,
            'success'
          );
        } else if (completedResponse && completedResponse.success === false) {
          const errorTitle = completedResponse.needsMyTischtennisReauth ? t('teamManagement.mytischtennisLoginRequired') : t('messages.error');
          const errorMessage = getSafeMessage(completedResponse.error, t('teamManagement.dataFetchFailed'));
          const details = completedResponse.debug ? getSafeMessage(JSON.stringify(completedResponse.debug, null, 2)) : '';
          await showInfo(
            errorTitle,
            errorMessage,
            details,
            completedResponse.needsMyTischtennisReauth ? 'warning' : 'error'
          );
          myTischtennisError.value = errorMessage;
        }
      } catch (error) {
        console.error('Fehler beim Abrufen der Team-Daten:', error);
        const isTimeout = error?.code === 'ECONNABORTED' || /Zeitüberschreitung/i.test(String(error?.message || ''));
        const errData = error?.response?.data || {};
        const errorMsg = isTimeout
          ? t('teamManagement.fetchTimeoutShort')
          : getSafeMessage(error?.message || errData.message || errData.error, t('teamManagement.dataFetchFailed'));
        const details = errData.debug ? getSafeMessage(JSON.stringify(errData.debug, null, 2)) : '';
        myTischtennisError.value = errorMsg;
        await showInfo(t('messages.error'), errorMsg, details, isTimeout ? 'warning' : 'error');
      } finally {
        fetchingTeamData.value = false;
      }
    };
    
    // Watch teamToEdit to load stats when a team is selected
    watch(teamToEdit, (newTeam) => {
      if (newTeam && newTeam.leagueId) {
        refreshPlayerStats();
      } else {
        playerStats.value = [];
      }
    });
    
    // Watch selectedSeasonId to load teams when season changes
    watch(selectedSeasonId, (newSeasonId) => {
      if (newSeasonId && selectedClub.value) {
        loadTeams();
        loadLeagues();
      }
    });
    
    const validateTeamDocumentFile = async (file, label) => {
      if (!file) {
        return false;
      }
      const maxSize = 10 * 1024 * 1024; // 10 MB, entspricht Backend-Limit
      const allowedExtensions = ['pdf', 'doc', 'docx', 'txt', 'csv'];
      const allowedMimeTypes = [
        'application/pdf',
        'application/msword',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'text/plain',
        'text/csv',
        'application/octet-stream'
      ];

      const extension = file.name.includes('.') ? file.name.split('.').pop().toLowerCase() : '';
      if (!allowedExtensions.includes(extension)) {
        await showInfo(t('teamManagement.invalidFileTypeTitle'), t('teamManagement.invalidFileExtension', { label, extensions: allowedExtensions.join(', ') }), '', 'warning');
        return false;
      }

      if (file.type && !allowedMimeTypes.includes(file.type)) {
        await showInfo(t('teamManagement.invalidFileTypeTitle'), t('teamManagement.invalidMimeType', { label, type: file.type }), '', 'warning');
        return false;
      }

      if (file.size > maxSize) {
        await showInfo(t('teamManagement.fileTooLargeTitle'), t('teamManagement.fileTooLarge', { label }), '', 'warning');
        return false;
      }

      return true;
    };
    
    return {
      t,
      infoDialog,
      confirmDialog,
      showInfo,
      showConfirm,
      handleConfirmResult,
      teams,
      leagues,
      teamFormIsOpen,
      teamToEdit,
      newTeamName,
      newLeagueId,
      selectedSeasonId,
      currentSeason,
      teamDocuments,
      teamSearchQuery,
      teamFilter,
      activeEditorSection,
      showGlobalJobDetails,
      filteredTeams,
      parsingInProgress,
      parsingDocuments,
      showPDFViewer,
      pdfUrl,
      pdfDialogTitle,
      myTischtennisUrl,
      parsedMyTischtennisData,
      parsingUrl,
      configuringTeam,
      fetchingTeamData,
      myTischtennisError,
      myTischtennisSuccess,
      playerStats,
      loadingStats,
      filteredLeagues,
      isSecondHalf,
      fullyConfiguredTeamsCount,
      partiallyConfiguredTeamsCount,
      teamsWithoutLeagueCount,
      totalSeasonAppearances,
      totalHalfAppearances,
      toggleNewTeam,
      resetToNewTeam,
      resetNewTeam,
      addNewTeam,
      editTeam,
      deleteTeam,
      uploadCodeList,
      uploadPinList,
      loadTeamDocuments,
      loadAllTeamDocuments,
      parsePDF,
      getTeamDocuments,
      getLatestTeamDocument,
      showPDFDialog,
      closePDFDialog,
      formatDate,
      formatFileSize,
      onSeasonChange,
      parseMyTischtennisUrl,
      configureTeamFromUrl,
      configureLeagueFromUrl,
      clearParsedData,
      getMyTischtennisStatus,
      fetchTeamDataManually,
      refreshPlayerStats
      ,memberById,
      schedulerJobs,
      formatJobDate,
      loadSchedulerJobsInfo,
      getFilteredTeamDetails,
      getTeamJobInfo
    };
  }
};
</script>

<style scoped>
.team-management-view {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.team-management-hero {
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius);
  background: var(--background-light);
  padding: 0.9rem;
}

.team-management-hero-header {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: flex-start;
  flex-wrap: wrap;
  margin-bottom: 0.85rem;
}

.team-management-hero-copy h2 {
  margin: 0 0 0.25rem;
}

.team-management-hero-copy p {
  margin: 0;
  color: var(--text-muted);
}

.team-management-hero-actions {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
}

.team-management-season-selector {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.team-management-hero-label {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.scheduler-jobs-summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: 0.65rem 0.85rem;
  margin: 0.85rem 0 0.75rem;
  background: var(--background-light);
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius);
}

.scheduler-jobs-summary-copy {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.scheduler-jobs-summary-text {
  font-size: 0.85rem;
  color: var(--text-muted);
}

.scheduler-jobs-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  min-width: 96px;
  padding: 0.4rem 0.75rem;
  border: 1px solid var(--border-color);
  border-radius: 999px;
  background: white;
  cursor: pointer;
  font-weight: 600;
  color: var(--text-color);
  line-height: 1;
  white-space: nowrap;
}

.scheduler-jobs-toggle-icon {
  color: var(--text-muted);
}

.scheduler-jobs-toggle-text {
  color: inherit;
}

.team-management-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 0.75rem;
  margin: 1rem 0;
}

.team-summary-card {
  background: white;
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius);
  padding: 0.8rem 0.9rem;
}

.team-summary-label {
  display: block;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.team-summary-value {
  display: block;
  margin-top: 0.2rem;
  font-size: 1.15rem;
  color: var(--text-color);
}

.newteam {
  margin-bottom: 1rem;
}

.toggle-new-team {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1rem;
}

.toggle-new-team span {
  cursor: pointer;
  font-weight: 600;
  color: var(--primary-color);
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.add {
  background: var(--primary-color);
  color: white;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
}

.new-team-form {
  background: var(--background-light);
  padding: 0.75rem;
  border-radius: var(--border-radius);
  border: 1px solid var(--border-color);
  margin-bottom: 0.5rem;
}

.workspace-header {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: flex-start;
  margin-bottom: 1rem;
}

.workspace-label {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.workspace-section-switcher {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.workspace-section-button {
  padding: 0.45rem 0.8rem;
  border: 1px solid var(--border-color);
  border-radius: 999px;
  background: white;
  color: var(--text-color);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
}

.workspace-section-button.active {
  background: var(--primary-light);
  border-color: var(--primary-color);
  color: var(--primary-dark);
}

.workspace-section-panel {
  background: white;
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius);
  padding: 0.9rem;
}

.workspace-header h3 {
  margin: 0.2rem 0 0;
}

.workspace-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.35rem;
}

.workspace-badge {
  font-size: 0.8rem;
  font-weight: 600;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
}

.workspace-badge.complete {
  background: #e8f6ed;
  color: #1b6f3a;
}

.workspace-badge.partial {
  background: #fff5e6;
  color: #a85d00;
}

.workspace-badge.missing {
  background: #fdeceb;
  color: #9d2b28;
}

.workspace-subtle {
  font-size: 0.85rem;
  color: var(--text-muted);
}

.form-layout-two-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

.basic-settings {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.advanced-settings {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

@media (max-width: 900px) {
  .form-layout-two-columns {
    grid-template-columns: 1fr;
  }
}

.new-team-form label {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}

.new-team-form label span {
  font-weight: 600;
  color: var(--text-color);
  min-width: 120px;
  flex-shrink: 0;
}

.new-team-form input,
.new-team-form select {
  flex: 1;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius-small);
  font-size: 0.9rem;
}

.new-team-form input:focus,
.new-team-form select:focus {
  outline: none;
  border-color: var(--primary-color);
  box-shadow: 0 0 0 1px var(--primary-light);
}

.form-actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.form-actions button {
  padding: 0.4rem 1rem;
  border: none;
  border-radius: var(--border-radius-small);
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  transition: var(--transition);
}

.form-actions button:not(.cancel-action) {
  background: var(--primary-color);
  color: white;
}

.form-actions button:not(.cancel-action):hover {
  background: var(--primary-dark);
}

.form-actions button:not(.cancel-action):disabled {
  background: var(--text-muted);
  cursor: not-allowed;
}

.cancel-action {
  background: var(--background-light);
  color: var(--text-color);
  border: 1px solid var(--border-color);
}

.cancel-action:hover {
  background: var(--border-color);
}

.teams-list h3 {
  margin-bottom: 0.5rem;
  color: var(--text-color);
  font-size: 1.1rem;
}

.teams-list-header {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: flex-start;
  margin-bottom: 0.75rem;
}

.teams-list-tools {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  min-width: min(420px, 100%);
}

.team-search-input {
  width: 100%;
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--border-color);
  border-radius: 10px;
  background: var(--surface-color);
  color: var(--text-color);
}

.team-search-input:focus {
  outline: none;
  border-color: var(--primary-color);
  box-shadow: 0 0 0 3px rgba(47, 122, 95, 0.14);
}

.team-filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
}

.team-filter-chip {
  border: 1px solid var(--border-color);
  background: var(--surface-muted);
  color: var(--text-color);
  border-radius: 999px;
  padding: 0.35rem 0.75rem;
  font-size: 0.85rem;
  cursor: pointer;
  font-weight: 600;
}

.team-filter-chip.active {
  background: rgba(47, 122, 95, 0.12);
  border-color: var(--primary-soft);
  color: var(--primary-strong);
  font-weight: 600;
}

.no-teams {
  text-align: center;
  padding: 2rem;
  color: var(--text-muted);
  background: var(--background-light);
  border-radius: var(--border-radius);
  border: 1px solid var(--border-color);
}

.teams-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1rem;
}

.team-card {
  background: white;
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius);
  padding: 0.75rem;
  cursor: pointer;
  transition: var(--transition);
}

.team-card.active {
  border-color: var(--primary-color);
  box-shadow: 0 0 0 1px var(--primary-light);
}

.team-card:hover {
  border-color: var(--primary-color);
  box-shadow: var(--shadow-small);
  transform: translateY(-2px);
}

.team-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 0.5rem;
}

.team-header-copy {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.team-header h4 {
  margin: 0;
  color: var(--text-color);
  font-size: 1.05rem;
}

.team-league-inline {
  font-size: 0.85rem;
  color: var(--text-muted);
}

.team-open-hint {
  font-size: 0.78rem;
  color: var(--primary-color);
}

.team-actions {
  display: flex;
  gap: 0.5rem;
}

.team-actions button {
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.25rem;
  border-radius: var(--border-radius-small);
  transition: var(--transition);
}

.btn-delete:hover {
  background: #fee;
}

.team-card-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin-bottom: 0.6rem;
}

.team-card-meta {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin-bottom: 0.75rem;
}

.team-card-meta-item {
  font-size: 0.875rem;
  color: var(--text-muted);
  line-height: 1.35;
}

.workspace-panel-header {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: flex-start;
  margin-bottom: 0.9rem;
}

.workspace-panel-copy {
  margin: 0.25rem 0 0;
  color: var(--text-muted);
  font-size: 0.92rem;
}

.document-status-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0.9rem;
}

.document-status-card,
.mytt-status-card {
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius);
  background: var(--background-light);
  padding: 0.9rem;
}

.document-status-head,
.mytt-status-line {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  align-items: flex-start;
}

.document-status-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.8rem;
  font-weight: 600;
  padding: 0.22rem 0.55rem;
  border-radius: 999px;
}

.document-status-badge.complete {
  background: #d9f5e3;
  color: #1f7a3f;
}

.document-status-badge.missing {
  background: #fdeaea;
  color: #b23b3b;
}

.document-status-meta,
.mytt-status-copy {
  margin: 0.55rem 0 0;
  color: var(--text-muted);
  line-height: 1.4;
}

.document-status-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  margin-top: 0.8rem;
}

.settings-summary-grid,
.stats-summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0.75rem;
  margin-bottom: 0.9rem;
}

.settings-summary-card {
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius);
  background: var(--background-light);
  padding: 0.8rem 0.9rem;
}

.settings-summary-label {
  display: block;
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-bottom: 0.25rem;
}

.settings-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 0.9rem;
}

.mytt-status-label {
  font-weight: 600;
  color: var(--text-color);
}

@media (max-width: 768px) {
  .team-management-hero-header {
    flex-direction: column;
  }

  .scheduler-jobs-summary {
    flex-direction: column;
    align-items: flex-start;
  }

  .teams-list-header,
  .workspace-header {
    flex-direction: column;
  }

  .teams-list-tools {
    min-width: 100%;
  }

  .teams-grid {
    grid-template-columns: 1fr;
  }
  
  .team-header {
    flex-direction: column;
    gap: 1rem;
  }
  
  .team-actions {
    align-self: flex-end;
  }
}

/* Upload-Buttons Styles */
.upload-actions.compact {
  margin-top: 0.5rem;
  padding: 0.5rem 0.75rem;
  background: var(--background-light);
  border-radius: 4px;
  border: 1px solid var(--border-color);
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.upload-actions.compact .section-title {
  flex-shrink: 0;
}

.upload-buttons-compact {
  display: flex;
  gap: 0.5rem;
  flex: 1;
  justify-content: flex-start;
}

.btn-upload-sm {
  padding: 4px 10px;
  font-size: 0.85rem;
  border: 1px solid transparent;
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
  transition: var(--transition);
  background: linear-gradient(135deg, var(--primary-color), var(--primary-hover));
  color: var(--text-on-primary);
}

.btn-upload-sm:hover {
  transform: translateY(-1px);
}

/* Legacy styles */
.upload-actions {
  margin-top: 1rem;
  padding: 0.75rem;
  background: var(--background-light);
  border-radius: var(--border-radius);
  border: 1px solid var(--border-color);
}

.upload-actions h4 {
  margin: 0 0 0.4rem 0;
  color: var(--text-color);
  font-size: 0.95rem;
}

.upload-buttons {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.upload-btn {
  padding: 0.4rem 1rem;
  border: 1px solid transparent;
  border-radius: 10px;
  font-weight: 600;
  cursor: pointer;
  transition: var(--transition);
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.875rem;
}

.code-list-btn {
  background: linear-gradient(135deg, var(--primary-color), var(--primary-hover));
  color: var(--text-on-primary);
}

.code-list-btn:hover {
  transform: translateY(-1px);
}

.pin-list-btn {
  background: rgba(181, 110, 65, 0.14);
  border-color: rgba(181, 110, 65, 0.24);
  color: #8a4f28;
}

.pin-list-btn:hover {
  background: rgba(181, 110, 65, 0.2);
}

@media (max-width: 768px) {
  .upload-buttons {
    flex-direction: column;
  }
  
  .upload-btn {
    justify-content: center;
  }
}

/* Upload-Bestätigung */
.upload-confirmation {
  margin-top: 0.75rem;
  padding: 0.75rem;
  background: var(--surface-muted);
  border-radius: var(--border-radius);
  border: 1px solid var(--border-color);
}

.selected-file-info {
  background: rgba(15, 23, 42, 0.05);
  padding: 0.5rem;
  border-radius: var(--border-radius-small);
  margin-bottom: 0.5rem;
  font-size: 0.85rem;
  line-height: 1.4;
}

.action-buttons {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}


.confirm-parse-btn {
  background: linear-gradient(135deg, var(--primary-color), var(--primary-hover));
  color: var(--text-on-primary);
  border: 1px solid transparent;
  padding: 0.4rem 1rem;
  border-radius: 10px;
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  transition: var(--transition);
}

.confirm-parse-btn:hover:not(:disabled) {
  transform: translateY(-1px);
}

.confirm-parse-btn:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

.cancel-parse-btn {
  background: var(--surface-color);
  color: var(--text-color);
  border: 1px solid var(--border-color);
  padding: 0.4rem 1rem;
  border-radius: 10px;
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  transition: var(--transition);
}

.cancel-parse-btn:hover {
  background: var(--surface-muted);
  border-color: var(--primary-soft);
}

.selected-file {
  display: block;
  margin-top: 0.5rem;
  font-size: 0.875rem;
  color: #2e7d32;
  font-weight: 600;
}

.parse-options {
  display: flex;
  gap: 1rem;
  align-items: end;
  flex-wrap: wrap;
}

.parse-options label {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 200px;
}

.parse-options label span {
  font-weight: 600;
  color: var(--text-color);
}

/* PDF-Parsing Styles */
.pdf-parsing-section.compact {
  margin-top: 0.5rem;
  padding: 0.5rem;
  background: var(--background-light);
  border-radius: 4px;
  border: 1px solid var(--border-color);
}

.pdf-parsing-section.compact .section-title {
  display: block;
  margin-bottom: 0.5rem;
}

.document-table.compact {
  width: 100%;
  border-collapse: collapse;
  background: white;
  border-radius: 3px;
  overflow: hidden;
  font-size: 0.85rem;
}

.document-table.compact th {
  background: var(--background-light);
  padding: 4px 8px;
  text-align: left;
  font-weight: 600;
  font-size: 0.8rem;
  border-bottom: 1px solid var(--border-color);
  color: var(--text-color);
}

.document-table.compact td {
  padding: 4px 8px;
  border-bottom: 1px solid var(--border-color);
  font-size: 0.8rem;
}

/* Legacy styles */
.pdf-parsing-section {
  margin-top: 1rem;
  padding: 0.75rem;
  background: var(--background-light);
  border-radius: var(--border-radius);
  border: 1px solid var(--border-color);
}

.pdf-parsing-section h4 {
  margin: 0 0 0.4rem 0;
  color: var(--text-color);
  font-size: 0.95rem;
}

.document-table {
  width: 100%;
  border-collapse: collapse;
  background: white;
  border-radius: var(--border-radius-small);
  overflow: hidden;
}

.document-table th {
  background: var(--background-light);
  padding: 0.25rem 0.4rem;
  text-align: left;
  font-weight: 600;
  font-size: 0.85rem;
  border-bottom: 2px solid var(--border-color);
  color: var(--text-color);
}

.document-table td {
  padding: 0.25rem 0.4rem;
  border-bottom: 1px solid var(--border-color);
  font-size: 0.85rem;
}

.document-row:hover {
  background: var(--background-light);
}

.document-row:last-child td {
  border-bottom: none;
}

.document-name {
  font-weight: 500;
  color: var(--text-color);
}

.document-type {
  font-size: 0.875rem;
  color: var(--text-muted);
  background: var(--primary-light);
  padding: 0.25rem 0.5rem;
  border-radius: var(--border-radius-small);
  display: inline-block;
  width: fit-content;
}

.document-size {
  font-size: 0.75rem;
  color: var(--text-muted);
}

.document-actions {
  display: flex;
  gap: 1rem;
  align-items: center;
}

.type-badge {
  font-size: 0.75rem;
  padding: 0.2rem 0.4rem;
  border-radius: var(--border-radius-small);
  display: inline-block;
  white-space: nowrap;
  font-weight: 600;
}

.type-badge.code_list {
  background: #e3f2fd;
  color: #1976d2;
}

.type-badge.pin_list {
  background: #fff3e0;
  color: #f57c00;
}

.parse-btn {
  padding: 0.3rem 0.6rem;
  background: #2196F3;
  color: white;
  border: none;
  border-radius: var(--border-radius-small);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  transition: var(--transition);
  white-space: nowrap;
}

.parse-btn:hover:not(:disabled) {
  background: #1976D2;
}

.parse-btn:disabled {
  background: var(--text-muted);
  cursor: not-allowed;
  opacity: 0.5;
}

/* Team-Dokumente Styles */
.team-documents {
  margin-top: 0.2rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border-color);
}

.documents-label {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 0.3rem;
}

.document-icons {
  display: flex;
  gap: 0.5rem;
}

.document-icon {
  background: none;
  border: 2px solid var(--border-color);
  border-radius: var(--border-radius-small);
  padding: 0.5rem;
  cursor: pointer;
  font-size: 1.25rem;
  transition: var(--transition);
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 2.5rem;
  height: 2.5rem;
}

.document-icon:hover {
  border-color: var(--primary-color);
  background: var(--primary-color);
  color: white;
  transform: translateY(-2px);
}

.code-list-icon:hover {
  border-color: #4CAF50;
  background: #4CAF50;
}

.pin-list-icon:hover {
  border-color: #FF9800;
  background: #FF9800;
}

/* PDF-Dialog Styles */
.pdf-dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.pdf-dialog {
  background: white;
  border-radius: var(--border-radius-medium);
  width: 90%;
  height: 90%;
  max-width: 1200px;
  max-height: 800px;
  display: flex;
  flex-direction: column;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}

.pdf-dialog-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 1.5rem;
  border-bottom: 1px solid var(--border-color);
  background: var(--background-light);
  border-radius: var(--border-radius-medium) var(--border-radius-medium) 0 0;
}

.pdf-dialog-header h3 {
  margin: 0;
  color: var(--text-primary);
  font-size: 1.25rem;
}

.close-btn {
  background: none;
  border: none;
  font-size: 1.5rem;
  cursor: pointer;
  color: var(--text-muted);
  padding: 0.25rem;
  border-radius: var(--border-radius-small);
  transition: var(--transition);
}

.close-btn:hover {
  background: var(--background-light);
  color: var(--text-primary);
}

.pdf-dialog-content {
  flex: 1;
  padding: 0;
  overflow: hidden;
}

.pdf-viewer {
  width: 100%;
  height: 100%;
  border: none;
}

.no-pdf {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: var(--text-muted);
}

@media (max-width: 768px) {
  .document-item {
    flex-direction: column;
    align-items: flex-start;
    gap: 1rem;
  }
  
  .document-actions {
    width: 100%;
    justify-content: space-between;
  }
  
  .parse-options {
    flex-direction: column;
    align-items: stretch;
  }
  
  .parse-options label {
    min-width: auto;
  }
}

/* MyTischtennis URL Parser Styles */
.mytischtennis-config.compact {
  margin-top: 0.5rem;
  padding: 0.5rem 0.75rem;
  background: var(--background-light);
  border-radius: 4px;
  border: 1px solid var(--border-color);
}

.mytischtennis-header-compact {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}

.section-title {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--primary-color);
  flex-shrink: 0;
}

.status-inline {
  flex: 1;
  display: flex;
  justify-content: flex-end;
}

.badge-sm {
  display: inline-block;
  padding: 2px 6px;
  font-size: 0.75rem;
  border-radius: 3px;
  font-weight: 500;
}

.badge-sm.complete {
  background-color: #d4edda;
  color: #155724;
}

.badge-sm.partial {
  background-color: #fff3cd;
  color: #856404;
}

.badge-sm.missing {
  background-color: #f8d7da;
  color: #721c24;
}

.btn-sm {
  padding: 4px 8px;
  font-size: 0.85rem;
  background-color: var(--primary-color);
  color: white;
  border: none;
  border-radius: 3px;
  cursor: pointer;
  transition: background-color 0.2s;
}

.btn-sm:hover:not(:disabled) {
  background-color: var(--primary-color-dark);
}

.btn-sm:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.compact-input-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.compact-url-input {
  flex: 1;
  padding: 6px 10px;
  font-size: 0.85rem;
  border: 1px solid var(--border-color);
  border-radius: 3px;
}

.inline-status {
  font-size: 1rem;
}

.compact-message {
  margin-top: 0.5rem;
  padding: 6px 10px;
  font-size: 0.85rem;
  border-radius: 3px;
}

.compact-message.error {
  background-color: #f8d7da;
  color: #721c24;
  border: 1px solid #f5c6cb;
}

.compact-message.success {
  background-color: #d4edda;
  color: #155724;
  border: 1px solid #c3e6cb;
}

/* Player Stats */
.player-stats {
  margin-top: 1rem;
  padding: 0.5rem;
  background: var(--background-light);
  border-radius: var(--border-radius);
  border: 1px solid var(--border-color);
}

.stats-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.5rem;
}

.loading-stats, .no-stats {
  text-align: center;
  padding: 1rem;
  color: var(--text-muted);
  font-size: 0.9rem;
}

.stats-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.stats-table thead th {
  background: var(--primary-color);
  color: white;
  padding: 4px 6px;
  text-align: left;
  font-weight: 600;
  font-size: 0.8rem;
}

.stats-table tbody tr {
  border-bottom: 1px solid var(--border-color);
}

.stats-table tbody tr:hover {
  background: var(--background-hover);
}

.stats-table td {
  padding: 4px 6px;
}

.stats-table .player-name {
  font-weight: 500;
}

.stats-table .stat-value {
  text-align: center;
  font-weight: 600;
  color: var(--primary-color);
}

/* Legacy styles (can be removed if not used elsewhere) */
.mytischtennis-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
  gap: 1rem;
}

.mytischtennis-config h4 {
  margin: 0;
  color: var(--primary-color);
  font-size: 1.1rem;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-shrink: 0;
}

.current-status {
  flex-shrink: 0;
}

.fetch-btn {
  padding: 0.5rem 1rem;
  background: #2196F3;
  color: white;
  border: none;
  border-radius: var(--border-radius-small);
  cursor: pointer;
  font-weight: 600;
  font-size: 0.85rem;
  transition: var(--transition);
  white-space: nowrap;
}

.fetch-btn:hover:not(:disabled) {
  background: #1976D2;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(33, 150, 243, 0.3);
}

.fetch-btn:disabled {
  background: var(--text-muted);
  cursor: not-allowed;
  opacity: 0.5;
}

.status-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.28rem 0.78rem;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 600;
  white-space: nowrap;
  border: 1px solid transparent;
}

.status-badge.complete {
  background: rgba(47, 122, 95, 0.12);
  color: #1f5f49;
  border-color: rgba(47, 122, 95, 0.24);
}

.status-badge.partial {
  background: rgba(181, 110, 65, 0.14);
  color: #8a4f28;
  border-color: rgba(181, 110, 65, 0.28);
}

.status-badge.missing {
  background: rgba(200, 74, 56, 0.12);
  color: #8b3327;
  border-color: rgba(200, 74, 56, 0.24);
}

.mytischtennis-status {
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border-color);
}

.mytischtennis-status .status-badge {
  font-size: 0.8rem;
  padding: 0.2rem 0.6rem;
}

.mytischtennis-url-input {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.mytischtennis-url-input label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.mytischtennis-url-input span {
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--text-secondary);
}

.url-input {
  width: 100%;
  padding: 0.5rem;
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius-small);
  font-size: 0.9rem;
}

.url-input:focus {
  outline: none;
  border-color: var(--primary-color);
  box-shadow: 0 0 0 2px rgba(33, 150, 243, 0.1);
}

.url-input:disabled {
  background: var(--background-light);
  cursor: wait;
}

.parsing-indicator {
  padding: 0.5rem;
  background: #e3f2fd;
  border: 1px solid #2196F3;
  border-radius: var(--border-radius-small);
  color: #1976D2;
  font-size: 0.9rem;
  text-align: center;
  font-weight: 600;
}

.error-message {
  margin-top: 1rem;
  padding: 0.75rem;
  background: #ffebee;
  border: 1px solid #ef5350;
  border-radius: var(--border-radius-small);
  color: #c62828;
  font-size: 0.9rem;
}

.success-message {
  margin-top: 1rem;
  padding: 0.75rem;
  background: #e8f5e9;
  border: 1px solid #66bb6a;
  border-radius: var(--border-radius-small);
  color: #2e7d32;
  font-size: 0.9rem;
}

/* Scheduler Jobs Info */
.scheduler-jobs-info {
  margin-bottom: 1rem;
  padding: 0.75rem;
  background: var(--background-light);
  border-radius: var(--border-radius);
  border: 1px solid var(--border-color);
  font-size: 0.875rem;
}

.job-info {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.job-info:last-child {
  margin-bottom: 0;
}

.job-label {
  font-weight: 600;
  color: var(--text-color);
  min-width: 150px;
}

.job-details {
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.job-count {
  color: var(--primary-color);
  font-weight: 500;
}

.job-error {
  color: #dc3545;
  font-weight: 500;
}

.job-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.team-details {
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border-color);
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.team-detail-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8rem;
  padding: 0.25rem 0.5rem;
  background: white;
  border-radius: 3px;
}

.team-name {
  flex: 1;
  color: var(--text-color);
}

.team-status {
  font-weight: bold;
  font-size: 0.9rem;
}

.team-status.success {
  color: #28a745;
}

.team-status.error {
  color: #dc3545;
}

/* Team Job Info */
.team-job-info.compact {
  margin-top: 0.5rem;
  padding: 0.5rem 0.75rem;
  background: var(--background-light);
  border-radius: 4px;
  border: 1px solid var(--border-color);
}

.team-job-details {
  margin-top: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.team-job-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
}

.team-job-label {
  font-weight: 600;
  color: var(--text-muted);
  min-width: 120px;
}

.team-job-value {
  color: var(--text-color);
}

.team-job-status {
  font-weight: 500;
}

.team-job-status.success {
  color: #28a745;
}

.team-job-status.error {
  color: #dc3545;
}

.team-job-no-data {
  color: var(--text-muted);
  font-size: 0.85rem;
  font-style: italic;
}

.team-job-status-row {
  margin-top: 0.3rem;
  padding-top: 0.3rem;
  border-top: 1px solid var(--border-color);
}

.team-job-status-value {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.8rem;
}

.team-job-status-icon {
  font-weight: bold;
  font-size: 0.9rem;
}

.team-job-status-icon.success {
  color: #28a745;
}

.team-job-status-icon.error {
  color: #dc3545;
}
</style>
