<template>
    <div class="orders-panel">
        <div class="orders-toolbar" :class="{ 'orders-toolbar-global': globalMode }">
            <label class="orders-toggle">
                <input v-model="showCompleted" type="checkbox">
                <span>{{ $t('orders.showCompleted') }}</span>
            </label>
            <div v-if="globalMode" class="orders-filters">
                <input
                    v-model="searchQuery"
                    type="search"
                    class="orders-search"
                    :placeholder="$t('orders.searchPlaceholder')"
                >
                <select v-model="statusFilter">
                    <option value="">{{ $t('orders.filterAllStatuses') }}</option>
                    <option v-for="status in statusOptions" :key="status.value" :value="status.value">
                        {{ status.label }}
                    </option>
                </select>
                <select v-model="clubFilter">
                    <option value="">{{ $t('orders.filterAllClubs') }}</option>
                    <option v-for="club in availableClubs" :key="club.id" :value="String(club.id)">
                        {{ club.name }}
                    </option>
                </select>
                <select v-model="completionFilter">
                    <option value="">{{ $t('orders.filterAllCompletionStates') }}</option>
                    <option value="paid">{{ $t('orders.filterPaid') }}</option>
                    <option value="handed_over">{{ $t('orders.filterHandedOver') }}</option>
                </select>
            </div>
            <button type="button" class="btn-secondary" :disabled="loading" @click="loadOrders">
                {{ $t('common.refresh') }}
            </button>
        </div>

        <div v-if="!globalMode" class="order-create-card">
            <div class="order-create-grid">
                <label>
                    <span>{{ $t('orders.item') }}</span>
                    <input v-model.trim="newOrder.item" type="text" :placeholder="$t('orders.itemPlaceholder')">
                </label>
                <label>
                    <span>{{ $t('orders.cost') }}</span>
                    <input v-model="newOrder.cost" type="number" min="0" step="0.01">
                </label>
                <label>
                    <span>{{ $t('orders.paid') }}</span>
                    <input v-model="newOrder.paidAmount" type="number" min="0" step="0.01">
                </label>
                <label>
                    <span>{{ $t('orders.budget') }}</span>
                    <input v-model="newOrder.budget" type="number" min="0" step="0.01">
                </label>
                <label class="orders-checkbox-label">
                    <span>{{ $t('orders.paidConfirmed') }}</span>
                    <input v-model="newOrder.paidConfirmed" type="checkbox">
                </label>
                <label>
                    <span>{{ $t('orders.status') }}</span>
                    <select v-model="newOrder.status">
                        <option v-for="status in statusOptions" :key="status.value" :value="status.value">
                            {{ status.label }}
                        </option>
                    </select>
                </label>
            </div>
            <div class="order-create-actions">
                <button type="button" class="btn-primary" :disabled="creatingOrder || !newOrder.item" @click="createOrder">
                    {{ $t('orders.addOrder') }}
                </button>
                <span class="orders-create-hint">{{ $t('orders.dateAutoHint') }}</span>
            </div>
        </div>

        <div v-if="loading" class="orders-state orders-state-info">{{ $t('orders.loading') }}</div>
        <div v-else-if="error" class="orders-state orders-state-error">{{ error }}</div>
        <div v-else-if="filteredOrders.length === 0" class="orders-state orders-state-empty">
            {{ globalMode ? $t('orders.noOrdersGlobal') : $t('orders.noOrdersMember') }}
        </div>

        <div v-else class="orders-table-wrap">
            <table class="orders-table">
                <thead>
                    <tr>
                        <th v-if="globalMode">{{ $t('orders.club') }}</th>
                        <th v-if="globalMode">{{ $t('orders.member') }}</th>
                        <th>{{ $t('orders.item') }}</th>
                        <th>{{ $t('orders.status') }}</th>
                        <th>{{ $t('orders.orderDate') }}</th>
                        <th>{{ $t('orders.statusDate') }}</th>
                        <th>{{ $t('orders.cost') }}</th>
                        <th>{{ $t('orders.paid') }}</th>
                        <th>{{ $t('orders.paidConfirmed') }}</th>
                        <th>{{ $t('orders.budget') }}</th>
                        <th>{{ $t('orders.open') }}</th>
                        <th>{{ $t('orders.history') }}</th>
                        <th>{{ $t('common.save') }}</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="order in filteredOrders" :key="order.id">
                        <td v-if="globalMode">{{ order.club?.name || '–' }}</td>
                        <td v-if="globalMode">{{ formatMemberName(order.member) }}</td>
                        <td>
                            <input v-model.trim="order.draftItem" type="text" class="orders-inline-input">
                        </td>
                        <td>
                            <select v-model="order.draftStatus">
                                <option v-for="status in statusOptions" :key="status.value" :value="status.value">
                                    {{ status.label }}
                                </option>
                            </select>
                        </td>
                        <td>{{ formatDateTime(order.orderDate || order.createdAt) }}</td>
                        <td>{{ formatDateTime(order.statusDate || order.updatedAt) }}</td>
                        <td>
                            <input v-model="order.draftCost" type="number" min="0" step="0.01" class="orders-inline-input orders-inline-input-number">
                        </td>
                        <td>
                            <input v-model="order.draftPaidAmount" type="number" min="0" step="0.01" class="orders-inline-input orders-inline-input-number">
                        </td>
                        <td class="orders-cell-center">
                            <input v-model="order.draftPaidConfirmed" type="checkbox">
                        </td>
                        <td>
                            <input v-model="order.draftBudget" type="number" min="0" step="0.01" class="orders-inline-input orders-inline-input-number">
                        </td>
                        <td>{{ formatCurrency(calculateOpenAmount(order)) }}</td>
                        <td>
                            <details class="orders-history-details">
                                <summary>{{ order.historyEntries?.length || 0 }}</summary>
                                <div class="orders-history-list">
                                    <div v-for="entry in order.historyEntries || []" :key="entry.id" class="orders-history-entry">
                                        <strong>{{ statusLabel(entry.status) }}</strong>
                                        <span>{{ formatDateTime(entry.changedAt) }}</span>
                                        <span>{{ formatCurrency(entry.cost) }} / {{ formatCurrency(entry.paidAmount) }} / {{ entry.paidConfirmed ? 'bezahlt' : 'offen' }} / {{ formatCurrency(entry.budget) }}</span>
                                    </div>
                                </div>
                            </details>
                        </td>
                        <td>
                            <button
                                type="button"
                                class="btn-primary btn-small"
                                :disabled="savingOrderIds.includes(order.id) || !hasOrderChanges(order)"
                                @click="saveOrder(order)"
                            >
                                {{ savingOrderIds.includes(order.id) ? $t('common.loading') : $t('common.save') }}
                            </button>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</template>

<script>
import apiClient from '../apiClient.js';
import { getSafeErrorMessage } from '../utils/errorMessages.js';

const STATUS_OPTIONS = [
    { value: 'requested', labelKey: 'orders.statusRequested' },
    { value: 'ordered', labelKey: 'orders.statusOrdered' },
    { value: 'arrived', labelKey: 'orders.statusArrived' },
    { value: 'handed_over', labelKey: 'orders.statusHandedOver' }
];

const normalizeAmount = (value) => {
    const parsed = Number.parseFloat(value ?? 0);
    if (!Number.isFinite(parsed)) {
        return 0;
    }
    return Math.max(0, Number(parsed.toFixed(2)));
};

const sortHistoryNewestFirst = (entries = []) => {
    return [...entries].sort((a, b) => {
        const aTime = new Date(a?.changedAt || a?.updatedAt || a?.createdAt || 0).getTime();
        const bTime = new Date(b?.changedAt || b?.updatedAt || b?.createdAt || 0).getTime();
        return bTime - aTime;
    });
};

export default {
    name: 'OrdersPanel',
    props: {
        clubId: {
            type: [String, Number],
            default: null
        },
        member: {
            type: Object,
            default: null
        },
        globalMode: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            orders: [],
            loading: false,
            error: '',
            creatingOrder: false,
            savingOrderIds: [],
            searchQuery: '',
            statusFilter: '',
            clubFilter: '',
            completionFilter: '',
            showCompleted: false,
            newOrder: {
                item: '',
                status: 'requested',
                cost: '',
                paidAmount: '',
                budget: '',
                paidConfirmed: false
            }
        };
    },
    computed: {
        statusOptions() {
            return STATUS_OPTIONS.map((status) => ({
                ...status,
                label: this.$t(status.labelKey)
            }));
        },
        availableClubs() {
            const map = new Map();
            this.orders.forEach((order) => {
                if (order.club?.id != null) {
                    map.set(String(order.club.id), { id: String(order.club.id), name: order.club.name });
                }
            });
            return Array.from(map.values()).sort((a, b) => a.name.localeCompare(b.name, 'de-DE'));
        },
        filteredOrders() {
            return this.orders.filter((order) => {
                if (this.statusFilter && order.status !== this.statusFilter) {
                    return false;
                }
                if (this.clubFilter && String(order.clubId) !== String(this.clubFilter)) {
                    return false;
                }
                const isPaid = Boolean(order.paidConfirmed);
                const isHandedOver = order.status === 'handed_over';
                const isCompleted = isPaid && isHandedOver;
                if (!this.showCompleted && isCompleted) {
                    return false;
                }
                if (this.completionFilter === 'paid' && !isPaid) {
                    return false;
                }
                if (this.completionFilter === 'handed_over' && !isHandedOver) {
                    return false;
                }
                if (!this.searchQuery.trim()) {
                    return true;
                }
                const search = this.searchQuery.trim().toLowerCase();
                const haystack = [
                    order.item,
                    order.club?.name,
                    order.member?.firstName,
                    order.member?.lastName
                ].filter(Boolean).join(' ').toLowerCase();
                return haystack.includes(search);
            });
        }
    },
    watch: {
        clubId() {
            if (!this.globalMode && this.member?.id) {
                this.loadOrders();
            }
        },
        member: {
            deep: false,
            handler() {
                if (!this.globalMode && this.member?.id) {
                    this.loadOrders();
                }
            }
        }
    },
    mounted() {
        this.loadOrders();
    },
    methods: {
        hydrateOrder(order) {
            return {
                ...order,
                cost: normalizeAmount(order.cost),
                paidAmount: normalizeAmount(order.paidAmount),
                openAmount: normalizeAmount(order.openAmount),
                historyEntries: sortHistoryNewestFirst(order.historyEntries || []),
                draftItem: order.item || '',
                draftStatus: order.status || 'requested',
                draftCost: String(normalizeAmount(order.cost)),
                draftPaidAmount: String(normalizeAmount(order.paidAmount)),
                draftPaidConfirmed: Boolean(order.paidConfirmed),
                draftBudget: String(normalizeAmount(order.budget))
            };
        },
        async loadOrders() {
            if (!this.globalMode && (!this.clubId || !this.member?.id)) {
                this.orders = [];
                return;
            }
            this.loading = true;
            this.error = '';
            try {
                const url = this.globalMode
                    ? '/member-orders/global'
                    : `/member-orders/${this.clubId}/${this.member.id}`;
                const response = await apiClient.get(url);
                const orders = response.data?.orders || [];
                this.orders = orders.map((order) => this.hydrateOrder(order));
            } catch (error) {
                this.error = getSafeErrorMessage(error, this.$t('orders.errorLoading'));
            } finally {
                this.loading = false;
            }
        },
        async createOrder() {
            if (!this.clubId || !this.member?.id || !this.newOrder.item.trim()) {
                return;
            }
            this.creatingOrder = true;
            this.error = '';
            try {
                const response = await apiClient.post(`/member-orders/${this.clubId}/${this.member.id}`, {
                    item: this.newOrder.item.trim(),
                    status: this.newOrder.status,
                    cost: normalizeAmount(this.newOrder.cost),
                    paidAmount: normalizeAmount(this.newOrder.paidAmount),
                    budget: normalizeAmount(this.newOrder.budget),
                    paidConfirmed: Boolean(this.newOrder.paidConfirmed)
                });
                if (response.data?.order) {
                    this.orders.unshift(this.hydrateOrder(response.data.order));
                    this.newOrder = {
                        item: '',
                        status: 'requested',
                        cost: '',
                        paidAmount: '',
                        budget: '',
                        paidConfirmed: false
                    };
                }
            } catch (error) {
                this.error = getSafeErrorMessage(error, this.$t('orders.errorSaving'));
            } finally {
                this.creatingOrder = false;
            }
        },
        hasOrderChanges(order) {
            return order.draftItem !== (order.item || '')
                || order.draftStatus !== order.status
                || normalizeAmount(order.draftCost) !== normalizeAmount(order.cost)
                || normalizeAmount(order.draftPaidAmount) !== normalizeAmount(order.paidAmount)
                || Boolean(order.draftPaidConfirmed) !== Boolean(order.paidConfirmed)
                || normalizeAmount(order.draftBudget) !== normalizeAmount(order.budget);
        },
        async saveOrder(order) {
            this.savingOrderIds.push(order.id);
            this.error = '';
            try {
                const response = await apiClient.patch(`/member-orders/${order.clubId}/${order.memberId}/${order.id}`, {
                    item: order.draftItem,
                    status: order.draftStatus,
                    cost: normalizeAmount(order.draftCost),
                    paidAmount: normalizeAmount(order.draftPaidAmount),
                    budget: normalizeAmount(order.draftBudget),
                    paidConfirmed: Boolean(order.draftPaidConfirmed)
                });
                if (response.data?.order) {
                    const updated = this.hydrateOrder(response.data.order);
                    this.orders = this.orders.map((entry) => entry.id === order.id ? updated : entry);
                }
            } catch (error) {
                this.error = getSafeErrorMessage(error, this.$t('orders.errorSaving'));
            } finally {
                this.savingOrderIds = this.savingOrderIds.filter((id) => id !== order.id);
            }
        },
        formatCurrency(value) {
            return new Intl.NumberFormat('de-DE', {
                style: 'currency',
                currency: 'EUR'
            }).format(normalizeAmount(value));
        },
        formatDateTime(value) {
            if (!value) {
                return '–';
            }
            return new Intl.DateTimeFormat('de-DE', {
                dateStyle: 'medium',
                timeStyle: 'short'
            }).format(new Date(value));
        },
        formatMemberName(member) {
            if (!member) {
                return '–';
            }
            return [member.firstName, member.lastName].filter(Boolean).join(' ');
        },
        calculateOpenAmount(order) {
            return Math.max(0, normalizeAmount(order.draftCost) - normalizeAmount(order.draftPaidAmount));
        },
        statusLabel(status) {
            return this.$t(STATUS_OPTIONS.find((entry) => entry.value === status)?.labelKey || 'orders.statusRequested');
        }
    }
};
</script>

<style scoped>
.orders-panel {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    min-width: 0;
}

.orders-toolbar,
.orders-filters,
.order-create-actions {
    display: flex;
    gap: 0.75rem;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
}

.orders-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.9rem;
    color: var(--text-color);
}

.orders-checkbox-label {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: 0.35rem;
}

.orders-checkbox-label input[type='checkbox'],
.orders-cell-center input[type='checkbox'] {
    width: 1.05rem;
    height: 1.05rem;
}

.orders-cell-center {
    text-align: center;
}

.orders-filters {
    justify-content: flex-start;
    flex: 1;
}

.orders-search {
    min-width: 220px;
    flex: 1 1 240px;
}

.order-create-card,
.orders-state {
    border: 1px solid var(--border-color);
    border-radius: 14px;
    padding: 1rem;
    background: var(--surface-muted);
}

.order-create-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 0.85rem;
}

.order-create-grid label,
.orders-table td,
.orders-table th {
    min-width: 0;
}

.order-create-grid label span {
    display: block;
    margin-bottom: 0.35rem;
    font-size: 0.85rem;
    font-weight: 700;
}

.orders-create-hint {
    color: var(--text-light);
    font-size: 0.9rem;
}

.orders-table-wrap {
    overflow: auto;
    border: 1px solid var(--border-color);
    border-radius: 14px;
    background: var(--surface-color);
}

.orders-table {
    width: 100%;
    min-width: 980px;
    border-collapse: collapse;
}

.orders-table th,
.orders-table td {
    padding: 0.75rem;
    vertical-align: top;
    white-space: nowrap;
}

.orders-inline-input {
    width: 100%;
    min-width: 9rem;
}

.orders-inline-input-number {
    min-width: 6.5rem;
}

.orders-history-details summary {
    cursor: pointer;
    list-style: none;
}

.orders-history-list {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin-top: 0.5rem;
    min-width: 16rem;
}

.orders-history-entry {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    font-size: 0.85rem;
    white-space: normal;
}

.orders-state-info {
    color: var(--primary-strong);
}

.orders-state-error {
    color: #9b2c2c;
    background: #fff5f5;
    border-color: rgba(155, 44, 44, 0.2);
}

.orders-state-empty {
    color: var(--text-light);
}

.btn-small {
    padding: 0.45rem 0.7rem;
}

@media (max-width: 768px) {
    .orders-search,
    .orders-filters select,
    .order-create-grid,
    .orders-toolbar button,
    .order-create-actions button {
        width: 100%;
    }

    .orders-toolbar-global {
        align-items: stretch;
    }
}
</style>
