<template>
  <div class="club-requests-page">
    <header class="page-header card">
      <div>
        <p class="page-eyebrow">TT-Verein</p>
        <h2>Anfragen</h2>
        <p class="page-subtitle">
          Kontaktanfragen, Probetrainings, Mitgliedschaftsanfragen und Sponsoringanfragen in einer Arbeitsfläche.
        </p>
      </div>
      <button type="button" class="btn-primary" @click="resetForm">Neue Anfrage</button>
    </header>

    <section v-if="!currentClub" class="card empty-state">
      <h3>Kein Verein ausgewählt</h3>
      <p>Bitte zuerst einen Verein auswählen, um Vereinsanfragen zu verwalten.</p>
    </section>

    <template v-else>
      <section class="requests-stats-grid">
        <article class="card stat-card">
          <span class="stat-label">Offen</span>
          <strong class="stat-value">{{ requestStats.open }}</strong>
        </article>
        <article class="card stat-card">
          <span class="stat-label">In Bearbeitung</span>
          <strong class="stat-value">{{ requestStats.inProgress }}</strong>
        </article>
        <article class="card stat-card">
          <span class="stat-label">Probetraining</span>
          <strong class="stat-value">{{ requestStats.trialTraining }}</strong>
        </article>
        <article class="card stat-card">
          <span class="stat-label">Mitgliedschaft</span>
          <strong class="stat-value">{{ requestStats.membership }}</strong>
        </article>
      </section>

      <section class="requests-layout">
        <div class="requests-main">
          <section class="card requests-filter-card">
            <div class="requests-filter-grid">
              <label>
                <span>Status</span>
                <select v-model="filters.status">
                  <option value="">Alle</option>
                  <option value="open">Offen</option>
                  <option value="in_progress">In Bearbeitung</option>
                  <option value="waiting">Wartend</option>
                  <option value="converted">Überführt</option>
                  <option value="rejected">Abgelehnt</option>
                  <option value="archived">Archiviert</option>
                </select>
              </label>
              <label>
                <span>Typ</span>
                <select v-model="filters.type">
                  <option value="">Alle</option>
                  <option value="contact">Kontakt</option>
                  <option value="trial_training">Probetraining</option>
                  <option value="membership">Mitgliedschaft</option>
                  <option value="sponsoring">Sponsoring</option>
                </select>
              </label>
              <label class="filter-search">
                <span>Suche</span>
                <input v-model.trim="filters.search" type="text" placeholder="Name, E-Mail oder Betreff" />
              </label>
            </div>
          </section>

          <section class="card requests-list-card">
            <div class="section-header requests-list-header">
              <h3>Eingang</h3>
              <button type="button" class="btn-secondary" @click="loadRequests" :disabled="loading">
                {{ loading ? 'Lädt…' : 'Neu laden' }}
              </button>
            </div>

            <p v-if="loadError" class="state-banner state-banner-error">{{ loadError }}</p>
            <p v-else-if="loading" class="state-banner">Anfragen werden geladen…</p>
            <p v-else-if="filteredRequests.length === 0" class="state-banner">Keine Anfragen im aktuellen Filter.</p>

            <div v-else class="requests-list">
              <button
                v-for="request in filteredRequests"
                :key="request.id"
                type="button"
                class="request-row"
                :class="{ active: selectedRequest?.id === request.id }"
                @click="selectRequest(request)"
              >
                <div class="request-row-main">
                  <div class="request-row-topline">
                    <strong>{{ request.subject || requestDisplayType(request.requestType) }}</strong>
                    <span class="request-status-badge" :class="`status-${request.status}`">{{ requestDisplayStatus(request.status) }}</span>
                  </div>
                  <p class="request-row-person">{{ requestDisplayName(request) }}</p>
                  <p class="request-row-meta">
                    <span>{{ requestDisplayType(request.requestType) }}</span>
                    <span v-if="request.workflowStage">{{ requestDisplayWorkflowStage(request.workflowStage) }}</span>
                    <span>{{ request.email || 'Keine E-Mail' }}</span>
                    <span>{{ formatDateTime(request.receivedAt || request.createdAt) }}</span>
                  </p>
                </div>
              </button>
            </div>
          </section>
        </div>

        <aside class="requests-side">
          <section class="card request-form-card">
            <div class="section-header">
              <h3>{{ form.id ? 'Anfrage bearbeiten' : 'Neue Anfrage' }}</h3>
            </div>
            <form class="request-form" @submit.prevent="submitRequest">
              <label>
                <span>Typ</span>
                <select v-model="form.requestType" required>
                  <option value="contact">Kontakt</option>
                  <option value="trial_training">Probetraining</option>
                  <option value="membership">Mitgliedschaft</option>
                  <option value="sponsoring">Sponsoring</option>
                </select>
              </label>
              <label>
                <span>Betreff</span>
                <input v-model.trim="form.subject" type="text" placeholder="Betreff" required />
              </label>
              <div class="request-form-grid">
                <label>
                  <span>Vorname</span>
                  <input v-model.trim="form.firstName" type="text" />
                </label>
                <label>
                  <span>Nachname</span>
                  <input v-model.trim="form.lastName" type="text" />
                </label>
              </div>
              <div class="request-form-grid">
                <label>
                  <span>E-Mail</span>
                  <input v-model.trim="form.email" type="email" />
                </label>
                <label>
                  <span>Telefon</span>
                  <input v-model.trim="form.phone" type="text" />
                </label>
              </div>
              <label>
                <span>Nachricht</span>
                <textarea v-model.trim="form.message" rows="5" placeholder="Anfrageinhalt"></textarea>
              </label>
              <div class="request-form-actions">
                <button type="submit" class="btn-primary" :disabled="saving">{{ saving ? 'Speichert…' : 'Speichern' }}</button>
                <button type="button" class="btn-secondary" @click="resetForm">Zurücksetzen</button>
              </div>
            </form>
          </section>

          <section v-if="selectedRequest" class="card request-detail-card">
            <div class="section-header">
              <h3>Details</h3>
            </div>
            <div class="detail-stack">
              <div>
                <span class="detail-label">Status</span>
                <select v-model="selectedRequest.status" @change="updateRequestStatus(selectedRequest)">
                  <option value="open">Offen</option>
                  <option value="in_progress">In Bearbeitung</option>
                  <option value="waiting">Wartend</option>
                  <option value="converted">Überführt</option>
                  <option value="rejected">Abgelehnt</option>
                  <option value="archived">Archiviert</option>
                </select>
              </div>
              <div>
                <span class="detail-label">Betreff</span>
                <p>{{ selectedRequest.subject || 'Kein Betreff' }}</p>
              </div>
              <div v-if="selectedRequest.workflowStage">
                <span class="detail-label">Workflow</span>
                <p>{{ requestDisplayWorkflowStage(selectedRequest.workflowStage) }}</p>
              </div>
              <div>
                <span class="detail-label">Person</span>
                <p>{{ requestDisplayName(selectedRequest) }}</p>
              </div>
              <div>
                <span class="detail-label">Nachricht</span>
                <p class="detail-message">{{ selectedRequest.message || 'Keine Nachricht hinterlegt.' }}</p>
              </div>
            </div>

            <div class="notes-block">
              <div class="section-header notes-header">
                <h4>Notizen</h4>
              </div>
              <p v-if="!selectedRequest.notes?.length" class="notes-empty">Noch keine Notizen vorhanden.</p>
              <div v-else class="notes-list">
                <article v-for="note in selectedRequest.notes" :key="note.id || note.createdAt" class="note-item">
                  <p>{{ note.body }}</p>
                  <small>{{ formatDateTime(note.createdAt) }}</small>
                </article>
              </div>
              <form class="note-form" @submit.prevent="addNote">
                <textarea v-model.trim="newNote" rows="3" placeholder="Interne Notiz hinzufügen"></textarea>
                <button type="submit" class="btn-secondary" :disabled="noteSaving || !newNote">Notiz speichern</button>
              </form>
            </div>
          </section>
        </aside>
      </section>
    </template>

    <InfoDialog
      v-model="infoDialog.isOpen"
      :title="infoDialog.title"
      :message="infoDialog.message"
      :details="infoDialog.details"
      :type="infoDialog.type"
    />

    <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 { mapGetters } from 'vuex';
import apiClient from '../apiClient.js';
import InfoDialog from '../components/InfoDialog.vue';
import ConfirmDialog from '../components/ConfirmDialog.vue';
import { buildConfirmConfig, buildInfoConfig, safeErrorMessage } from '../utils/dialogUtils.js';

function normalizeRequest(payload = {}) {
  return {
    id: payload.id,
    requestType: payload.requestType || payload.request_type || 'contact',
    status: payload.status || 'open',
    workflowStage: payload.workflowStage || payload.workflow_stage || '',
    priority: payload.priority || 'normal',
    subject: payload.subject || '',
    firstName: payload.firstName || payload.first_name || '',
    lastName: payload.lastName || payload.last_name || '',
    email: payload.email || '',
    phone: payload.phone || '',
    message: payload.message || '',
    receivedAt: payload.receivedAt || payload.received_at || payload.createdAt || payload.created_at || null,
    createdAt: payload.createdAt || payload.created_at || null,
    updatedAt: payload.updatedAt || payload.updated_at || null,
    notes: Array.isArray(payload.notes)
      ? payload.notes.map((note) => ({
        id: note.id,
        body: note.body || note.note || '',
        createdAt: note.createdAt || note.created_at || null,
      }))
      : [],
  };
}

export default {
  name: 'ClubRequestsView',
  components: {
    InfoDialog,
    ConfirmDialog,
  },
  data() {
    return {
      loading: false,
      saving: false,
      noteSaving: false,
      loadError: '',
      requests: [],
      selectedRequestId: null,
      newNote: '',
      filters: {
        status: '',
        type: '',
        search: '',
      },
      form: {
        id: null,
        requestType: 'contact',
        subject: '',
        firstName: '',
        lastName: '',
        email: '',
        phone: '',
        message: '',
      },
      infoDialog: {
        isOpen: false,
        title: '',
        message: '',
        details: '',
        type: 'info',
      },
      confirmDialog: {
        isOpen: false,
        title: '',
        message: '',
        details: '',
        type: 'info',
        resolveCallback: null,
      },
    };
  },
  computed: {
    ...mapGetters(['currentClub']),
    filteredRequests() {
      const search = this.filters.search.trim().toLowerCase();
      return this.requests.filter((request) => {
        if (this.filters.status && request.status !== this.filters.status) return false;
        if (this.filters.type && request.requestType !== this.filters.type) return false;
        if (!search) return true;
        const haystack = [
          request.subject,
          request.firstName,
          request.lastName,
          request.email,
          request.message,
        ].join(' ').toLowerCase();
        return haystack.includes(search);
      });
    },
    selectedRequest() {
      return this.requests.find((request) => String(request.id) === String(this.selectedRequestId)) || null;
    },
    requestStats() {
      return {
        open: this.requests.filter((request) => request.status === 'open').length,
        inProgress: this.requests.filter((request) => request.status === 'in_progress').length,
        trialTraining: this.requests.filter((request) => request.requestType === 'trial_training').length,
        membership: this.requests.filter((request) => request.requestType === 'membership').length,
      };
    },
  },
  watch: {
    currentClub: {
      immediate: true,
      async handler(newClub) {
        if (!newClub) {
          this.requests = [];
          this.selectedRequestId = null;
          return;
        }
        await this.loadRequests();
      },
    },
    '$route.query': {
      immediate: true,
      handler() {
        this.applyRouteQuery();
      },
    },
    selectedRequest(request) {
      if (request) {
        this.form = {
          id: request.id,
          requestType: request.requestType,
          subject: request.subject,
          firstName: request.firstName,
          lastName: request.lastName,
          email: request.email,
          phone: request.phone,
          message: request.message,
        };
      }
    },
  },
  methods: {
    applyRouteQuery() {
      const routeStatus = typeof this.$route?.query?.status === 'string' ? this.$route.query.status : '';
      const routeRequestId = this.$route?.query?.requestId;

      if (['open', 'in_progress', 'waiting', 'converted', 'rejected', 'archived'].includes(routeStatus)) {
        this.filters.status = routeStatus;
      }

      if (routeRequestId && this.requests.some((request) => String(request.id) === String(routeRequestId))) {
        this.selectedRequestId = String(routeRequestId);
      }
    },
    async showInfo(title, message, details = '', type = 'info') {
      this.infoDialog = buildInfoConfig({ title, message, details, type });
    },
    async showConfirm(title, message, details = '', type = 'info', options = {}) {
      return new Promise((resolve) => {
        this.confirmDialog = buildConfirmConfig({
          title,
          message,
          details,
          type,
          resolveCallback: resolve,
          ...options,
        });
      });
    },
    handleConfirmResult(confirmed) {
      if (this.confirmDialog.resolveCallback) {
        this.confirmDialog.resolveCallback(confirmed);
        this.confirmDialog.resolveCallback = null;
      }
      this.confirmDialog.isOpen = false;
    },
    requestDisplayType(type) {
      return {
        contact: 'Kontakt',
        trial_training: 'Probetraining',
        membership: 'Mitgliedschaft',
        sponsoring: 'Sponsoring',
      }[type] || 'Anfrage';
    },
    requestDisplayStatus(status) {
      return {
        open: 'Offen',
        in_progress: 'In Bearbeitung',
        waiting: 'Wartend',
        converted: 'Überführt',
        rejected: 'Abgelehnt',
        archived: 'Archiviert',
      }[status] || status;
    },
    requestDisplayWorkflowStage(stage) {
      return {
        contact_replied: 'Kontakt beantwortet',
        trial_training_scheduled: 'Probetraining terminiert',
        trial_training_feedback_recorded: 'Probetraining nachbereitet',
        membership_reviewed: 'Mitgliedsanfrage geprüft',
        admission_prepared: 'Aufnahme vorbereitet',
        member_record_created: 'Mitglied angelegt',
        sepa_pending: 'SEPA ausstehend',
        onboarding_completed: 'Onboarding abgeschlossen',
        sponsoring_contacted: 'Sponsoring kontaktiert',
      }[stage] || stage;
    },
    requestDisplayName(request) {
      const parts = [request.firstName, request.lastName].filter(Boolean).join(' ').trim();
      return parts || request.email || 'Unbekannte Person';
    },
    formatDateTime(value) {
      if (!value) return '–';
      const date = new Date(value);
      if (Number.isNaN(date.getTime())) return '–';
      return new Intl.DateTimeFormat('de-DE', {
        dateStyle: 'medium',
        timeStyle: 'short',
      }).format(date);
    },
    selectRequest(request) {
      this.selectedRequestId = request.id;
      this.newNote = '';
    },
    resetForm() {
      this.selectedRequestId = null;
      this.newNote = '';
      this.form = {
        id: null,
        requestType: 'contact',
        subject: '',
        firstName: '',
        lastName: '',
        email: '',
        phone: '',
        message: '',
      };
    },
    async loadRequests() {
      if (!this.currentClub) return;
      this.loading = true;
      this.loadError = '';
      try {
        const response = await apiClient.get(`/club-requests/${this.currentClub}`);
        const entries = Array.isArray(response.data?.requests)
          ? response.data.requests
          : Array.isArray(response.data)
            ? response.data
            : [];
        this.requests = entries.map(normalizeRequest);
        this.applyRouteQuery();
        if (this.selectedRequestId && !this.selectedRequest) {
          this.selectedRequestId = null;
        }
        if (!this.selectedRequestId && this.requests.length > 0) {
          this.selectedRequestId = this.requests[0].id;
        }
      } catch (error) {
        this.loadError = safeErrorMessage(error, 'Anfragen konnten nicht geladen werden.');
      } finally {
        this.loading = false;
      }
    },
    async submitRequest() {
      if (!this.currentClub) return;
      this.saving = true;
      const payload = {
        requestType: this.form.requestType,
        subject: this.form.subject,
        firstName: this.form.firstName,
        lastName: this.form.lastName,
        email: this.form.email,
        phone: this.form.phone,
        message: this.form.message,
      };
      try {
        if (this.form.id) {
          await apiClient.put(`/club-requests/${this.currentClub}/${this.form.id}`, payload);
        } else {
          await apiClient.post(`/club-requests/${this.currentClub}`, payload);
        }
        await this.loadRequests();
        await this.showInfo('Erfolg', 'Anfrage gespeichert.', '', 'success');
        this.resetForm();
      } catch (error) {
        await this.showInfo('Fehler', safeErrorMessage(error, 'Anfrage konnte nicht gespeichert werden.'), '', 'error');
      } finally {
        this.saving = false;
      }
    },
    async updateRequestStatus(request) {
      if (!this.currentClub || !request?.id) return;
      try {
        await apiClient.patch(`/club-requests/${this.currentClub}/${request.id}/status`, {
          status: request.status,
        });
        await this.loadRequests();
      } catch (error) {
        await this.showInfo('Fehler', safeErrorMessage(error, 'Status konnte nicht aktualisiert werden.'), '', 'error');
      }
    },
    async addNote() {
      if (!this.currentClub || !this.selectedRequest?.id || !this.newNote) return;
      this.noteSaving = true;
      try {
        await apiClient.post(`/club-requests/${this.currentClub}/${this.selectedRequest.id}/notes`, {
          body: this.newNote,
        });
        this.newNote = '';
        await this.loadRequests();
      } catch (error) {
        await this.showInfo('Fehler', safeErrorMessage(error, 'Notiz konnte nicht gespeichert werden.'), '', 'error');
      } finally {
        this.noteSaving = false;
      }
    },
  },
};
</script>

<style scoped>
.club-requests-page {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.page-header {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: flex-start;
  padding: 1.25rem;
}

.page-eyebrow {
  margin: 0 0 0.35rem;
  color: var(--text-light);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.8rem;
  font-weight: 700;
}

.page-header h2,
.section-header h3,
.notes-header h4 {
  margin: 0;
}

.page-subtitle {
  margin: 0.35rem 0 0;
  color: var(--text-secondary);
}

.empty-state {
  padding: 1.25rem;
}

.requests-stats-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1rem;
}

.stat-card {
  padding: 1rem;
}

.stat-label {
  display: block;
  color: var(--text-light);
  font-size: 0.9rem;
}

.stat-value {
  display: block;
  margin-top: 0.35rem;
  font-size: 1.55rem;
}

.requests-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(320px, 0.95fr);
  gap: 1rem;
}

.requests-main,
.requests-side {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.requests-filter-card,
.requests-list-card,
.request-form-card,
.request-detail-card {
  padding: 1rem;
}

.requests-filter-grid,
.request-form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.85rem;
}

.filter-search {
  grid-column: 1 / -1;
}

.requests-list-header,
.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.85rem;
}

.state-banner {
  margin: 0;
  padding: 0.85rem 1rem;
  border-radius: 12px;
  background: rgba(24, 70, 54, 0.06);
  color: var(--text-secondary);
}

.state-banner-error {
  background: rgba(207, 84, 84, 0.12);
  color: #922f2f;
}

.requests-list {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}

.request-row {
  width: 100%;
  text-align: left;
  border: 1px solid rgba(24, 70, 54, 0.08);
  background: rgba(255, 255, 255, 0.9);
  border-radius: 14px;
  padding: 0.95rem 1rem;
  cursor: pointer;
}

.request-row.active {
  border-color: rgba(47, 122, 95, 0.45);
  box-shadow: inset 0 0 0 1px rgba(47, 122, 95, 0.25);
}

.request-row-topline,
.request-row-meta {
  display: flex;
  gap: 0.55rem;
  flex-wrap: wrap;
  align-items: center;
}

.request-row-person {
  margin: 0.35rem 0;
  color: var(--text-secondary);
}

.request-row-meta {
  color: var(--text-light);
  font-size: 0.88rem;
}

.request-status-badge {
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  padding: 0.2rem 0.55rem;
  font-size: 0.78rem;
  font-weight: 700;
  background: rgba(24, 70, 54, 0.08);
}

.status-open { background: rgba(214, 150, 28, 0.14); color: #8a5b08; }
.status-in_progress { background: rgba(61, 118, 196, 0.14); color: #234f90; }
.status-waiting { background: rgba(160, 112, 64, 0.14); color: #8a5b1d; }
.status-converted { background: rgba(47, 122, 95, 0.14); color: #1d5f48; }
.status-rejected,
.status-archived { background: rgba(207, 84, 84, 0.14); color: #922f2f; }

.request-form,
.detail-stack,
.notes-block,
.note-form {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

.request-form-actions {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.detail-label {
  display: block;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--text-light);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 0.2rem;
}

.detail-message {
  white-space: pre-wrap;
}

.notes-empty {
  margin: 0;
  color: var(--text-light);
}

.notes-list {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}

.note-item {
  padding: 0.75rem 0.85rem;
  border-radius: 12px;
  background: rgba(24, 70, 54, 0.05);
}

.note-item p,
.note-item small {
  margin: 0;
}

.note-item small {
  display: block;
  margin-top: 0.35rem;
  color: var(--text-light);
}

@media (max-width: 980px) {
  .requests-layout,
  .requests-stats-grid {
    grid-template-columns: 1fr 1fr;
  }

  .requests-layout {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 640px) {
  .page-header,
  .requests-filter-grid,
  .request-form-grid,
  .requests-stats-grid {
    grid-template-columns: 1fr;
  }

  .page-header {
    flex-direction: column;
  }
}
</style>
