<template>
  <div class="modal-backdrop open" @click.self="closeForm">
    <div class="modal-container" ref="formModalRef" style="min-width: 550px;">
      <div class="modal-header">
        <h3>Create New Expense</h3>
        <button class="close-button" @click="closeForm" aria-label="Close">
          <svg class="icon">
            <use xlink:href="#icon-close" />
          </svg>
        </button>
      </div>
      <div class="modal-body">
        <form @submit.prevent="handleSubmit" class="expense-form">
          <div class="form-group">
            <label for="description" class="form-label">Description</label>
            <input type="text" id="description" v-model="formData.description" class="form-input" required
              placeholder="What was this expense for?" />
          </div>

          <div class="form-group">
            <label for="totalAmount" class="form-label">Total Amount</label>
            <div class="amount-input-group">
              <span class="currency-symbol">$</span>
              <input type="number" id="totalAmount" v-model.number="formData.total_amount" class="form-input" required
                min="0.01" step="0.01" placeholder="0.00" />
            </div>
          </div>

          <div class="form-group">
            <label for="paidBy" class="form-label">Paid By</label>
            <select id="paidBy" v-model="formData.paid_by_user_id" class="form-input" required>
              <option value="" disabled>Select who paid</option>
              <option v-for="user in availableUsers" :key="user.id" :value="user.id">
                {{ user.name || user.email }}
              </option>
            </select>
          </div>

          <div class="form-group">
            <label for="splitType" class="form-label">Split Type</label>
            <select id="splitType" v-model="formData.split_type" class="form-input" required
              @change="onSplitTypeChange">
              <option value="EQUAL">Equal Split</option>
              <option value="EXACT_AMOUNTS">Exact Amounts</option>
              <option value="PERCENTAGE">Percentage</option>
              <option value="SHARES">Shares</option>
              <option value="ITEM_BASED">Item Based</option>
            </select>
          </div>

          <div class="form-group">
            <label for="expenseDate" class="form-label">Date</label>
            <input type="date" id="expenseDate" v-model="formData.expense_date" class="form-input" :max="today" />
          </div>

          <!-- Split Details Section -->
          <div v-if="showSplitConfiguration" class="form-group">
            <label class="form-label">{{ splitConfigurationLabel }}</label>

            <!-- EXACT_AMOUNTS -->
            <div v-if="formData.split_type === 'EXACT_AMOUNTS'" class="splits-container">
              <div v-for="(split, index) in formData.splits_in" :key="index" class="split-item">
                <select v-model="split.user_id" class="form-input split-user-select" required>
                  <option value="" disabled>Select user</option>
                  <option v-for="user in availableUsers" :key="user.id" :value="user.id">
                    {{ user.name || user.email }}
                  </option>
                </select>
                <input type="number" v-model.number="split.owed_amount" class="form-input" min="0.01" step="0.01"
                  placeholder="Amount" required />
                <button type="button" class="btn btn-danger btn-sm" @click="removeSplit(index)"
                  :disabled="formData.splits_in!.length <= 1">
                  <svg class="icon icon-sm">
                    <use xlink:href="#icon-trash" />
                  </svg>
                </button>
              </div>
              <div class="split-summary">
                <span>Total: ${{ exactAmountTotal.toFixed(2) }}</span>
                <span v-if="exactAmountTotal !== formData.total_amount" class="validation-error">
                  (Should equal ${{ formData.total_amount.toFixed(2) }})
                </span>
              </div>
              <button type="button" class="btn btn-secondary btn-sm" @click="addSplit">
                Add Split
              </button>
            </div>

            <!-- PERCENTAGE -->
            <div v-else-if="formData.split_type === 'PERCENTAGE'" class="splits-container">
              <div v-for="(split, index) in formData.splits_in" :key="index" class="split-item">
                <select v-model="split.user_id" class="form-input split-user-select" required>
                  <option value="" disabled>Select user</option>
                  <option v-for="user in availableUsers" :key="user.id" :value="user.id">
                    {{ user.name || user.email }}
                  </option>
                </select>
                <div class="percentage-input-group">
                  <input type="number" v-model.number="split.share_percentage" class="form-input" min="0.01" max="100"
                    step="0.01" placeholder="Percentage" required />
                  <span class="percentage-symbol">%</span>
                </div>
                <span class="split-amount-preview">
                  ${{ calculatePercentageAmount(split.share_percentage).toFixed(2) }}
                </span>
                <button type="button" class="btn btn-danger btn-sm" @click="removeSplit(index)"
                  :disabled="formData.splits_in!.length <= 1">
                  <svg class="icon icon-sm">
                    <use xlink:href="#icon-trash" />
                  </svg>
                </button>
              </div>
              <div class="split-summary">
                <span>Total: {{ percentageTotal.toFixed(2) }}%</span>
                <span v-if="Math.abs(percentageTotal - 100) > 0.01" class="validation-error">
                  (Should equal 100%)
                </span>
              </div>
              <button type="button" class="btn btn-secondary btn-sm" @click="addSplit">
                Add Split
              </button>
            </div>

            <!-- SHARES -->
            <div v-else-if="formData.split_type === 'SHARES'" class="splits-container">
              <div v-for="(split, index) in formData.splits_in" :key="index" class="split-item">
                <select v-model="split.user_id" class="form-input split-user-select" required>
                  <option value="" disabled>Select user</option>
                  <option v-for="user in availableUsers" :key="user.id" :value="user.id">
                    {{ user.name || user.email }}
                  </option>
                </select>
                <input type="number" v-model.number="split.share_units" class="form-input" min="1" step="1"
                  placeholder="Shares" required />
                <span class="split-amount-preview">
                  ${{ calculateShareAmount(split.share_units).toFixed(2) }}
                </span>
                <button type="button" class="btn btn-danger btn-sm" @click="removeSplit(index)"
                  :disabled="formData.splits_in!.length <= 1">
                  <svg class="icon icon-sm">
                    <use xlink:href="#icon-trash" />
                  </svg>
                </button>
              </div>
              <div class="split-summary">
                <span>Total shares: {{ sharesTotal }}</span>
              </div>
              <button type="button" class="btn btn-secondary btn-sm" @click="addSplit">
                Add Split
              </button>
            </div>

            <!-- ITEM_BASED -->
            <div v-else-if="formData.split_type === 'ITEM_BASED'" class="item-based-info">
              <div class="info-box">
                <svg class="icon">
                  <use xlink:href="#icon-info" />
                </svg>
                <div>
                  <p><strong>Item-Based Split</strong></p>
                  <p>The expense will be automatically split based on item prices and who added each item to the list.
                  </p>
                  <p v-if="props.itemId">Split will be based on the selected item only.</p>
                  <p v-else>Split will be based on all priced items in the list.</p>
                </div>
              </div>
            </div>
          </div>

          <!-- Validation Messages -->
          <div v-if="validationErrors.length > 0" class="validation-messages">
            <div v-for="error in validationErrors" :key="error" class="validation-error">
              {{ error }}
            </div>
          </div>

          <div class="form-actions">
            <button type="button" class="btn btn-neutral" @click="closeForm">Cancel</button>
            <button type="submit" class="btn btn-primary ml-2" :disabled="isSubmitting || !isFormValid">
              <span v-if="isSubmitting" class="spinner-dots-sm"><span /><span /><span /></span>
              <span v-else>Create Expense</span>
            </button>
          </div>
        </form>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue';
import { apiClient, API_ENDPOINTS } from '@/config/api';
import { useNotificationStore } from '@/stores/notifications';
import { useAuthStore } from '@/stores/auth';
import type { ExpenseCreate, ExpenseSplitCreate } from '@/types/expense';
import type { UserPublic } from '@/types/user';
import { onClickOutside } from '@vueuse/core';

const props = defineProps<{
  listId?: number;
  groupId?: number;
  itemId?: number;
}>();

const emit = defineEmits<{
  (e: 'close'): void;
  (e: 'created', expense: any): void;
}>();

const notificationStore = useNotificationStore();
const authStore = useAuthStore();
const formModalRef = ref<HTMLElement | null>(null);
const isSubmitting = ref(false);
const availableUsers = ref<UserPublic[]>([]);

const today = computed(() => {
  const date = new Date();
  return date.toISOString().split('T')[0];
});

const formData = ref<ExpenseCreate>({
  description: '',
  total_amount: 0,
  currency: 'USD',
  expense_date: today.value,
  split_type: 'EQUAL',
  list_id: props.listId,
  group_id: props.groupId,
  item_id: props.itemId,
  paid_by_user_id: authStore.user?.id || 0,
  splits_in: []
});

// Computed properties for split configuration
const showSplitConfiguration = computed(() => {
  return ['EXACT_AMOUNTS', 'PERCENTAGE', 'SHARES', 'ITEM_BASED'].includes(formData.value.split_type);
});

const splitConfigurationLabel = computed(() => {
  switch (formData.value.split_type) {
    case 'EXACT_AMOUNTS': return 'Specify exact amounts for each person';
    case 'PERCENTAGE': return 'Specify percentage for each person';
    case 'SHARES': return 'Specify number of shares for each person';
    case 'ITEM_BASED': return 'Item-based split configuration';
    default: return 'Split configuration';
  }
});

// Validation computed properties
const exactAmountTotal = computed(() => {
  if (formData.value.split_type !== 'EXACT_AMOUNTS' || !formData.value.splits_in) return 0;
  return formData.value.splits_in.reduce((sum: number, split: ExpenseSplitCreate) => sum + (split.owed_amount || 0), 0);
});

const percentageTotal = computed(() => {
  if (formData.value.split_type !== 'PERCENTAGE' || !formData.value.splits_in) return 0;
  return formData.value.splits_in.reduce((sum: number, split: ExpenseSplitCreate) => sum + (split.share_percentage || 0), 0);
});

const sharesTotal = computed(() => {
  if (formData.value.split_type !== 'SHARES' || !formData.value.splits_in) return 0;
  return formData.value.splits_in.reduce((sum: number, split: ExpenseSplitCreate) => sum + (split.share_units || 0), 0);
});

const validationErrors = computed(() => {
  const errors: string[] = [];

  if (!formData.value.description) errors.push('Description is required');
  if (!formData.value.total_amount || formData.value.total_amount <= 0) errors.push('Total amount must be greater than 0');
  if (!formData.value.paid_by_user_id) errors.push('Please select who paid for this expense');

  if (formData.value.split_type === 'EXACT_AMOUNTS' && formData.value.splits_in) {
    if (Math.abs(exactAmountTotal.value - formData.value.total_amount) > 0.01) {
      errors.push('Split amounts must equal the total expense amount');
    }
    if (formData.value.splits_in.some((s: ExpenseSplitCreate) => !s.user_id)) {
      errors.push('Please select a user for each split');
    }
  }

  if (formData.value.split_type === 'PERCENTAGE' && formData.value.splits_in) {
    if (Math.abs(percentageTotal.value - 100) > 0.01) {
      errors.push('Percentages must total 100%');
    }
    if (formData.value.splits_in.some((s: ExpenseSplitCreate) => !s.user_id)) {
      errors.push('Please select a user for each split');
    }
  }

  if (formData.value.split_type === 'SHARES' && formData.value.splits_in) {
    if (sharesTotal.value === 0) {
      errors.push('Total shares must be greater than 0');
    }
    if (formData.value.splits_in.some((s: ExpenseSplitCreate) => !s.user_id)) {
      errors.push('Please select a user for each split');
    }
  }

  return errors;
});

const isFormValid = computed(() => {
  return validationErrors.value.length === 0;
});

// Helper functions
const calculatePercentageAmount = (percentage: number | undefined) => {
  if (!percentage) return 0;
  return (formData.value.total_amount * percentage) / 100;
};

const calculateShareAmount = (shares: number | undefined) => {
  if (!shares || sharesTotal.value === 0) return 0;
  return (formData.value.total_amount * shares) / sharesTotal.value;
};

const initializeSplits = () => {
  if (formData.value.split_type === 'EQUAL' || formData.value.split_type === 'ITEM_BASED') {
    formData.value.splits_in = undefined;
  } else {
    formData.value.splits_in = [createEmptySplit()];
  }
};

const createEmptySplit = (): ExpenseSplitCreate => {
  const base = { user_id: 0 };

  switch (formData.value.split_type) {
    case 'EXACT_AMOUNTS':
      return { ...base, owed_amount: 0 };
    case 'PERCENTAGE':
      return { ...base, share_percentage: 0 };
    case 'SHARES':
      return { ...base, share_units: 0 };
    default:
      return { ...base, owed_amount: 0 };
  }
};

const addSplit = () => {
  if (!formData.value.splits_in) {
    formData.value.splits_in = [];
  }
  formData.value.splits_in.push(createEmptySplit());
};

const removeSplit = (index: number) => {
  if (formData.value.splits_in && formData.value.splits_in.length > 1) {
    formData.value.splits_in.splice(index, 1);
  }
};

const onSplitTypeChange = () => {
  initializeSplits();
};

const fetchAvailableUsers = async () => {
  try {
    let endpoint = '';

    if (props.listId) {
      // Get users from list's group or just current user for personal lists
      const listResponse = await apiClient.get(`${API_ENDPOINTS.LISTS.BASE}/${props.listId}`);
      if (listResponse.data.group_id) {
        endpoint = `${API_ENDPOINTS.GROUPS.BASE}/${listResponse.data.group_id}/members`;
      } else {
        // Personal list - only current user
        availableUsers.value = authStore.user ? [authStore.user] : [];
        return;
      }
    } else if (props.groupId) {
      endpoint = `${API_ENDPOINTS.GROUPS.BASE}/${props.groupId}/members`;
    } else {
      // Fallback to current user only
      availableUsers.value = authStore.user ? [authStore.user] : [];
      return;
    }

    const response = await apiClient.get(endpoint);
    availableUsers.value = response.data;
  } catch (error) {
    console.error('Failed to fetch available users:', error);
    availableUsers.value = authStore.user ? [authStore.user] : [];
  }
};

const closeForm = () => {
  emit('close');
};

const handleSubmit = async () => {
  if (!isFormValid.value) {
    notificationStore.addNotification({
      message: 'Please fix the validation errors before submitting',
      type: 'warning'
    });
    return;
  }

  isSubmitting.value = true;
  try {
    const response = await apiClient.post(API_ENDPOINTS.FINANCIALS.EXPENSES, formData.value);
    emit('created', response.data);
    closeForm();
    notificationStore.addNotification({
      message: 'Expense created successfully',
      type: 'success'
    });
  } catch (err) {
    notificationStore.addNotification({
      message: (err instanceof Error ? err.message : String(err)) || 'Failed to create expense',
      type: 'error'
    });
  } finally {
    isSubmitting.value = false;
  }
};

// Initialize
onMounted(() => {
  fetchAvailableUsers();
  initializeSplits();
});

// Watch for changes to ensure current user is selected as payer by default
watch(() => authStore.user, (user) => {
  if (user && !formData.value.paid_by_user_id) {
    formData.value.paid_by_user_id = user.id;
  }
}, { immediate: true });

onClickOutside(formModalRef, closeForm);
</script>

<style scoped>
.expense-form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.form-label {
  font-weight: 600;
  color: #333;
}

.form-input {
  padding: 0.75rem;
  border: 2px solid #111;
  border-radius: 8px;
  font-size: 1rem;
  width: 100%;
}

.amount-input-group {
  position: relative;
  display: flex;
  align-items: center;
}

.currency-symbol {
  position: absolute;
  left: 1rem;
  color: #666;
  z-index: 1;
}

.amount-input-group .form-input {
  padding-left: 2rem;
}

.percentage-input-group {
  position: relative;
  display: flex;
  align-items: center;
}

.percentage-symbol {
  position: absolute;
  right: 1rem;
  color: #666;
  z-index: 1;
}

.percentage-input-group .form-input {
  padding-right: 2rem;
}

.splits-container {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.split-item {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.split-user-select {
  flex: 2;
}

.split-amount-preview {
  min-width: 80px;
  font-size: 0.875rem;
  color: #666;
  text-align: right;
}

.split-summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.5rem;
  background: #f9f9f9;
  border-radius: 4px;
  font-size: 0.875rem;
  font-weight: 600;
}

.validation-error {
  color: #dc2626;
  font-size: 0.875rem;
}

.validation-messages {
  background: #fee2e2;
  border: 1px solid #f87171;
  border-radius: 8px;
  padding: 0.75rem;
}

.item-based-info {
  background: #eff6ff;
  border: 1px solid #bfdbfe;
  border-radius: 8px;
  padding: 1rem;
}

.info-box {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
}

.info-box .icon {
  color: #3b82f6;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  margin-top: 0.125rem;
}

.info-box p {
  margin: 0 0 0.5rem 0;
}

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

.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 1rem;
}

.btn {
  padding: 0.75rem 1.5rem;
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  transition: all 0.2s;
}

.btn-primary {
  background: #111;
  color: white;
  border: none;
}

.btn-primary:hover:not(:disabled) {
  background: #333;
}

.btn-neutral {
  background: #f5f5f5;
  color: #333;
  border: 2px solid #ddd;
}

.btn-neutral:hover {
  background: #e5e5e5;
}

.btn-danger {
  background: #fee2e2;
  color: #dc2626;
  border: none;
}

.btn-danger:hover {
  background: #fecaca;
}

.btn-secondary {
  background: #e5e7eb;
  color: #374151;
  border: none;
}

.btn-secondary:hover {
  background: #d1d5db;
}

.btn-sm {
  padding: 0.5rem;
  font-size: 0.875rem;
}

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

.ml-2 {
  margin-left: 0.5rem;
}

.spinner-dots-sm {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
}

.spinner-dots-sm span {
  width: 4px;
  height: 4px;
  background-color: white;
  border-radius: 50%;
  animation: dot-pulse 1.4s infinite ease-in-out both;
}

.spinner-dots-sm span:nth-child(1) {
  animation-delay: -0.32s;
}

.spinner-dots-sm span:nth-child(2) {
  animation-delay: -0.16s;
}

@keyframes dot-pulse {

  0%,
  80%,
  100% {
    transform: scale(0);
  }

  40% {
    transform: scale(1);
  }
}
</style>
