<!-- src/pages/pay/service/authorize_preauthcharge.vue -->
<template>
  <div class="flex">


    <!-- Main Content -->
    <div class="flex-1 px-8 py-6">

      <!-- Breadcrumbs & Header -->
      <div class="text-sm breadcrumbs mb-6">
        <ul>
          <li><router-link :to="{ name: 'home' }">Home</router-link></li>
          <li><router-link :to="{ name: 'payService', params: { id: serviceId } }">Payment Confirmation</router-link></li>
          <li>Payment Authorization</li>
        </ul>
      </div>

      <!-- 2x2 Grid Layout -->
      <div class="max-w-6xl">
        <h1 class="text-3xl font-bold mb-8">Payment Authorization Authorize.net</h1>

        <!-- Top Row: Charge Breakdown and Payment Method -->
        <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
          <!-- Service Details -->
          <div class="bg-base-100 rounded-lg p-6">
            <h3 class="text-lg font-semibold mb-4">Service Details</h3>
            <div class="space-y-3">
              <div class="flex justify-between">
                <span>Service Type:</span>
                <span class="badge" :class="getServiceTypeColor(service.type_service_call)">
                  {{ getServiceTypeName(service.type_service_call) }}
                </span>
              </div>
              <div class="flex justify-between">
                <span>Scheduled Date:</span>
                <span>{{ service.scheduled_date ? formatScheduledDate(service.scheduled_date) : 'Not scheduled' }}</span>
              </div>
              <div class="flex flex-col space-y-2">
                <span><strong>Description:</strong></span>
                <div class="bg-base-200 p-2 rounded text-sm">{{ service.description || 'No description provided' }}</div>
              </div>
              <hr class="my-3">
              <div class="flex justify-between font-bold text-lg">
                <span>Service Cost:</span>
                <span>${{ service.service_cost || '0.00' }}</span>
              </div>
            </div> <!-- close space-y-3 -->
          </div> <!-- close bg-base-100 -->

          <!-- Credit Card Selection -->
          <div class="bg-base-100 rounded-lg p-6">
            <h3 class="text-lg font-semibold mb-4">Payment Method</h3>
            <div v-if="credit_cards.length > 1" class="space-y-2">
              <div v-for="card in credit_cards" :key="card.id"
                   @click="selectCard(card.id)"
                   :class="[
                     'p-3 rounded-md cursor-pointer border-2 transition-all duration-200',
                     selectedCardId === card.id || (!selectedCardId && selectedCard && selectedCard.id === card.id)
                       ? 'bg-primary text-primary-content border-primary'
                       : 'bg-base-200 hover:bg-base-300 border-transparent'
                   ]">
                <div class="flex justify-between items-center mb-1">
                  <div class="font-semibold">{{ card.type_of_card }}</div>
                  <div class="flex gap-2">
                    <div v-if="card.main_card" class="badge badge-outline badge-sm">Primary</div>
                    <div v-if="selectedCardId === card.id || (!selectedCardId && selectedCard && selectedCard.id === card.id)"
                         class="w-3 h-3 bg-current rounded-full"></div>
                  </div>
                </div>
                <div class="font-mono text-sm">
                  <div> **** **** **** {{ card.last_four_digits }}</div>
                  <div>{{ card.name_on_card }}</div>
                  <div>Expires: {{ card.expiration_month }}/{{ card.expiration_year }}</div>
                </div>
              </div>
            </div>
            <div v-else-if="credit_cards.length === 1" class="bg-base-200 p-4 rounded-md">
              <div class="flex justify-between items-center mb-2">
                <div class="font-semibold">{{ credit_cards[0].type_of_card }}</div>
                <div v-if="credit_cards[0].main_card" class="badge badge-primary">Primary</div>
              </div>
              <div class="font-mono text-sm">
                <div> **** **** **** {{ credit_cards[0].last_four_digits }}</div>
                <div>{{ credit_cards[0].name_on_card }}</div>
                <div>Expires: {{ credit_cards[0].expiration_month }}/{{ credit_cards[0].expiration_year }}</div>
              </div>
            </div>
            <div v-else class="text-gray-500 p-4">
              No payment methods available
            </div>
          </div>
        </div>

        <!-- Error/Success Messages -->
        <div class="mb-6">
          <div v-if="error" class="alert alert-error">
            <span>{{ error }}</span>
          </div>
          <div v-if="success" class="alert alert-success">
            <span>{{ success }}</span>
          </div>
        </div>

        <!-- Bottom Section: Action Buttons -->
        <div class="bg-base-100 rounded-lg p-6">
          <div class="flex flex-col lg:flex-row lg:items-center gap-6">
            <!-- Charge Amount Input - Always visible -->
            <div class="flex-1">
              <h3 class="text-lg font-semibold mb-2">Charge/Preauthorize Amount</h3>
              <div class="form-control">
                <div class="relative">
                  <span class="absolute left-3 top-1/2 transform -translate-y-1/2 text-sm z-10">$</span>
                  <input
                    id="chargeAmountInput"
                    v-model="chargeAmount"
                    type="number"
                    step="0.01"
                    class="input input-bordered input-sm w-full pl-6"
                    placeholder="0.00"
                    :disabled="loading"
                    min="0.01"
                    autofocus
                  />
                </div>
              </div>
            </div>

            <!-- Action Buttons -->
            <div class="flex gap-3 mt-4">
              <router-link :to="{ name: 'payService', params: { id: serviceId } }">
                <button class="btn btn-ghost">Cancel</button>
              </router-link>
              <button
                @click="handlePreauthorize"
                class="btn btn-success"
                :disabled="loading || chargeAmount <= 0 || isNaN(Number(chargeAmount))"
              >
                <span v-if="loading && action === 'preauthorize'" class="loading loading-spinner loading-sm"></span>
                Preauthorize
              </button>
              <button
                @click="handleChargeNow"
                class="btn btn-warning"
                :disabled="loading || chargeAmount <= 0 || isNaN(Number(chargeAmount))"
              >
                <span v-if="loading && action === 'charge'" class="loading loading-spinner loading-sm"></span>
                 Charge
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import axios from 'axios'
import authHeader from '../../../services/auth.header'
import { notify } from "@kyvg/vue3-notification"
import type {
  AxiosResponse,
  AxiosError,
  CustomerFormData,
  CreditCardFormData,
  WhoAmIResponse
} from '../../../types/models'

const route = useRoute()
const router = useRouter()

interface ServiceFormData {
  id: number;
  scheduled_date: string;
  customer_id: number;
  customer_name: string;
  customer_address: string;
  customer_town: string;
  type_service_call: number;
  description: string;
  service_cost: string;
  payment_card_id: number;
}

// Reactive data
const serviceId = ref(route.params.id as string)
const loaded = ref(false)
const chargeAmount = ref(0)
const loading = ref(false)
const action = ref('') // 'preauthorize' or 'charge'
const error = ref('')
const success = ref('')
const selectedCardId = ref(null as number | null) // Track which card is selected
const user = ref({
  user_id: 0,
})
const service = ref<ServiceFormData>({
  id: 0,
  scheduled_date: '',
  customer_id: 0,
  customer_name: '',
  customer_address: '',
  customer_town: '',
  type_service_call: 0,
  description: '',
  service_cost: '',
  payment_card_id: 0,
})
const credit_cards = ref<CreditCardFormData[]>([
  {
    id: 0,
    name_on_card: '',
    main_card: false,
    card_number: '',
    expiration_month: '',
    type_of_card: '',
    last_four_digits: '',
    expiration_year: '',
    security_number: '',
  }
])
const customer = ref<CustomerFormData>({
  id: 0,
  user_id: 0,
  customer_first_name: '',
  customer_last_name: '',
  customer_town: '',
  customer_address: '',
  customer_state: 0,
  customer_zip: '',
  customer_apt: '',
  customer_home_type: 0,
  customer_phone_number: '',
  account_number: '',
})

// Computed
const selectedCard = computed(() => {
  // If user has selected a card manually, use that
  if (selectedCardId.value) {
    return credit_cards.value.find((card) => card.id === selectedCardId.value)
  }
  // Otherwise use automatic selection logic
  // First try to find payment_card_id from service
  if (service.value.payment_card_id && service.value.payment_card_id > 0) {
    return credit_cards.value.find((card) => card.id === service.value.payment_card_id)
  }
  // Otherwise return the primary card (main_card = true)
  return credit_cards.value.find((card) => card.main_card === true) ||
         credit_cards.value.find((card) => card.id > 0) || // Any card if no primary
         null
})

// Watchers
watch(() => route.params.id, (newId) => {
  if (newId !== serviceId.value) {
    resetState()
    serviceId.value = newId as string
    loadData(newId as string)
  }
})

// Lifecycle
onMounted(() => {
  loadData(serviceId.value)
})

// Functions
const resetState = () => {
  loading.value = false
  action.value = ''
  error.value = ''
  success.value = ''
  chargeAmount.value = 0
  serviceId.value = route.params.id as string
}

const loadData = (serviceId: string) => {
  userStatus()
  getServiceOrder(serviceId)
}

const userStatus = () => {
  let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
  axios({
    method: 'get',
    url: path,
    withCredentials: true,
    headers: authHeader(),
  })
    .then((response: AxiosResponse<WhoAmIResponse>) => {
      if (response.data.ok) {
        user.value = response.data.user;
      }
    })
}

const getServiceOrder = (serviceId: number | string) => {
  let path = import.meta.env.VITE_BASE_URL + "/service/" + serviceId;
  axios({
    method: "get",
    url: path,
    withCredentials: true,
    headers: authHeader(),
  })
    .then((response: AxiosResponse<{ ok?: boolean; service?: ServiceFormData } | ServiceFormData[] | ServiceFormData>) => {
      let serviceData: ServiceFormData | undefined;
      if (response.data) {
        // Handle different API response structures
        if ('service' in response.data && response.data.service) {
          // API returns {ok: true, service: {...}} structure
          serviceData = response.data.service;
        } else if (Array.isArray(response.data)) {
          serviceData = response.data[0]; // Array response
        } else if ('id' in response.data) {
          serviceData = response.data as ServiceFormData; // Direct object response
        }

        if (serviceData && serviceData.id) {
          service.value = {
            id: serviceData.id,
            scheduled_date: serviceData.scheduled_date,
            customer_id: serviceData.customer_id,
            customer_name: serviceData.customer_name,
            customer_address: serviceData.customer_address,
            customer_town: serviceData.customer_town,
            type_service_call: serviceData.type_service_call,
            description: serviceData.description,
            service_cost: serviceData.service_cost,
            payment_card_id: serviceData.payment_card_id || 0,
          };

          // Fetch related data
          getCustomer(service.value.customer_id);
          getCreditCards(service.value.customer_id);
        } else {
          console.error("API Error: Invalid service data received:", serviceData);
          notify({
            title: "Error",
            text: "Invalid service data received",
            type: "error",
          });
        }
      } else {
        console.error("API Error: No response data received");
        notify({
          title: "Error",
          text: "Could not get service data",
          type: "error",
        });
      }
    })
    .catch((err: Error) => {
      console.error("API Error in getServiceOrder:", err);
      notify({
        title: "Error",
        text: "Could not get service data",
        type: "error",
      });
    });
}

const getCreditCards = (user_id: number) => {
  let path = import.meta.env.VITE_BASE_URL + '/payment/cards/' + user_id;
  axios({
    method: 'get',
    url: path,
    headers: authHeader(),
  }).then((response: AxiosResponse<CreditCardFormData[]>) => {
    console.log('Credit cards loaded:', response.data?.length || 0, 'cards');
    credit_cards.value = response.data || [];
  }).catch((err: Error) => {
    console.error('Failed to load credit cards:', err);
    credit_cards.value = [];
  });
}

const getCustomer = (userid: number) => {
  let path = import.meta.env.VITE_BASE_URL + '/customer/' + userid;
  axios({
    method: 'get',
    url: path,
    headers: authHeader(),
  }).then((response: AxiosResponse<CustomerFormData>) => {
    customer.value = response.data
  })
}

const handlePreauthorize = async () => {
  await processPayment('preauthorize')
}

const handleChargeNow = async () => {
  await processPayment('charge')
}

const processPayment = async (actionType: string) => {
  if (!selectedCard.value) {
    error.value = 'No credit card found for this customer'
    return
  }

  loading.value = true
  action.value = actionType
  error.value = ''
  success.value = ''

  try {
    // Step 2: If payment method is credit, perform the pre-authorization
    if (actionType === 'preauthorize') {
      if (!chargeAmount.value || chargeAmount.value <= 0) {
        throw new Error("Pre-authorization amount must be greater than zero.");
      }

      const authPayload = {
        card_id: selectedCard.value!.id,
        preauthorize_amount: chargeAmount.value.toFixed(2),
        service_id: service.value.id,
        delivery_id: null, // No delivery for services
      };

      const authPath = `${import.meta.env.VITE_AUTHORIZE_URL}/api/payments/authorize/saved-card/${customer.value.id}`;

      const response = await axios.post(authPath, authPayload, { withCredentials: true, headers: authHeader() });

      // Update payment type to 11 after successful preauthorization
      try {
        await axios.put(`${import.meta.env.VITE_BASE_URL}/payment/authorize/service/${service.value.id}`, {
          card_id: selectedCard.value!.id,
          status: actionType === 'preauthorize' ? 1 : 3
        }, { headers: authHeader() });
      } catch (updateError) {
        console.error('Failed to update payment type after preauthorization:', updateError);
      }

      // On successful authorization, show success and redirect
      success.value = `Preauthorization successful! Transaction ID: ${response.data?.auth_net_transaction_id || 'N/A'}`;
      setTimeout(() => {
        router.push({ name: "customerProfile", params: { id: customer.value.id } });
      }, 2000);
    } else { // Handle 'charge' action
      if (!chargeAmount.value || chargeAmount.value <= 0) {
        throw new Error("Charge amount must be greater than zero.");
      }

      // Create a payload that matches the backend's TransactionCreateByCardID schema
      const chargePayload = {
        card_id: selectedCard.value!.id,
        charge_amount: chargeAmount.value.toFixed(2),
        service_id: service.value.id,
        delivery_id: null, // No delivery for services
        // You can add other fields here if your schema requires them
      };

      // Use the correct endpoint for charging a saved card
      const chargePath = `${import.meta.env.VITE_AUTHORIZE_URL}/api/payments/charge/saved-card/${customer.value.id}`;

      console.log('=== DEBUG: Charge payload ===');
      console.log('Calling endpoint:', chargePath);
      console.log('Final payload being sent:', chargePayload);

      const response = await axios.post(chargePath, chargePayload, { withCredentials: true, headers: authHeader() });

      // Update service cost to the charged amount using new dedicated API
      try {
        await axios.put(
          `${import.meta.env.VITE_BASE_URL}/service/update-cost/${service.value.id}`,
          { service_cost: chargeAmount.value },
          { headers: authHeader(), withCredentials: true }
        );
        console.log(`✅ Updated service cost to ${chargeAmount.value} for service ${service.value.id}`);
      } catch (costError) {
        console.error('❌ Failed to update service cost:', costError);
      }

      // Update payment status after successful charge
      try {
        await axios.put(`${import.meta.env.VITE_BASE_URL}/payment/capture/service/${service.value.id}`, {
          card_id: selectedCard.value!.id,
          status: 3  // Approved status
        }, {
          headers: authHeader(),
          withCredentials: true
        });
      } catch (updateError) {
        console.error('Failed to update payment status after charge:', updateError);
      }

      // Status codes: 0 = APPROVED, 1 = DECLINED (based on backend TransactionStatus enum)
      if (response.data && response.data.status === 0) { // 0 = APPROVED
        success.value = `Charge successful! Transaction ID: ${response.data.auth_net_transaction_id || 'N/A'}`;
        setTimeout(() => {
          router.push({ name: "customerProfile", params: { id: customer.value.id } });
        }, 2000);
      } else {
        // The error message from your backend will be more specific now
        throw new Error(`Payment charge failed: ${response.data?.rejection_reason || 'Unknown error'}`);
      }
    }
  } catch (err: unknown) {
    const axiosErr = err as AxiosError<{ detail?: string }>;
    console.log(err)
    error.value = axiosErr.response?.data?.detail || `Failed to ${actionType} payment`
    notify({
      title: "Error",
      text: error.value,
      type: "error",
    })
  } finally {
    loading.value = false
    action.value = ''
  }
}

const getServiceTypeName = (typeId: number): string => {
  const typeMap: { [key: number]: string } = { 0: 'Tune-up', 1: 'No Heat', 2: 'Fix', 3: 'Tank Install', 4: 'Other' };
  return typeMap[typeId] || 'Unknown';
}

const getServiceTypeColor = (typeId: number): string => {
  const colorMap: { [key: number]: string } = { 0: 'primary', 1: 'error', 2: 'warning', 3: 'info', 4: 'neutral' };
  return `badge-${colorMap[typeId] || 'neutral'}`;
}

const selectCard = (cardId: number) => {
  selectedCardId.value = cardId;
}

const formatScheduledDate = (dateString: string): string => {
  if (!dateString) return 'Not scheduled';
  return dateString; // Could format with dayjs if needed
}
</script>

<style scoped></style>
