<!-- src/pages/pay/oil/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: 'payOil', params: { id: deliveryId } }">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">
          <!-- Charge Breakdown -->
          <div class="bg-base-100 rounded-lg p-6">
            <h3 class="text-lg font-semibold mb-4">Charge Breakdown</h3>
            <div class="space-y-2">
              <div class="flex justify-between">
                <span>Gallons Ordered:</span>
                <span>{{ delivery.gallons_ordered || 0 }} gallons</span>
              </div>
              <div class="flex justify-between">
                <span>Price per Gallon:</span>
                <span>${{ delivery.customer_price || 0 }}</span>
              </div>
              <div class="flex justify-between font-semibold">
                <span>Subtotal:</span>
                <span>${{ calculateSubtotal() }}</span>
              </div>
              <div v-if="delivery.prime == 1" class="flex justify-between text-sm">
                <span>Prime Fee (Tier {{ delivery.pricing_tier_prime || 1 }}):</span>
                <span>+ ${{ Number(getTierPrice('prime', delivery.pricing_tier_prime)).toFixed(2) }}</span>
              </div>
              <div v-if="delivery.same_day == 1" class="flex justify-between text-sm">
                <span>Same Day Fee (Tier {{ delivery.pricing_tier_same_day || 1 }}):</span>
                <span>+ ${{ Number(getTierPrice('same_day', delivery.pricing_tier_same_day)).toFixed(2) }}</span>
              </div>
              <div v-if="delivery.emergency == 1" class="flex justify-between text-sm">
                <span>Emergency Fee (Tier {{ delivery.pricing_tier_emergency || 1 }}):</span>
                <span>+ ${{ Number(getTierPrice('emergency', delivery.pricing_tier_emergency)).toFixed(2) }}</span>
              </div>
              <div v-if="promo_active" class="flex justify-between text-success">
                <span>{{ promo.name_of_promotion }}:</span>
                <span>- ${{ discount }}</span>
              </div>
              <hr class="my-3">
              <div class="flex justify-between font-bold text-lg">
                <span>Total:</span>
                <span>${{ calculateTotalAmount() }}</span>
              </div>
            </div> <!-- close space-y-2 -->
          </div> <!-- close bg-base-100 -->

          <!-- Credit Card Display -->
          <div class="bg-base-100 rounded-lg p-6">
            <h3 class="text-lg font-semibold mb-4">Payment Method</h3>
            <div v-if="selectedCard" class="bg-base-200 p-4 rounded-md">
              <div class="flex justify-between items-center mb-2">
                <div class="font-semibold">{{ selectedCard.type_of_card }}</div>
                <div v-if="selectedCard.main_card" class="badge badge-primary">Primary</div>
              </div>
              <div class="mt-3 text-sm font-mono tracking-wider">
                <p>{{ selectedCard.card_number }}</p>
                <p>{{ selectedCard.name_on_card }}</p>
                <p>
                  Exp:
                  <span v-if="Number(selectedCard.expiration_month) < 10">0</span>{{ selectedCard.expiration_month }} / {{ selectedCard.expiration_year }}
                </p>
                <p>CVV: {{ selectedCard.security_number }}</p>
              </div>

              <div class="divider my-2"></div>

              <div class="flex justify-end gap-2">
                <router-link :to="{ name: 'cardedit', params: { id: selectedCard.id }}" class="link link-hover text-xs">Edit</router-link>
              </div>
            </div>
            <div v-else class="text-gray-500 p-4">
              No payment method selected
            </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: Charge Amount Input and 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 - Compact -->
            <div class="flex-1">
              <h3 class="text-lg font-semibold mb-2">Charge Amount</h3>
              <div class="flex">
                <span class="inline-flex items-center px-3 text-sm bg-base-200 rounded-l-lg border border-r-0">$</span>
                <input
                  v-model="chargeAmount"
                  type="number"
                  step="0.01"
                  class="input input-bordered flex-1 rounded-l-none"
                  placeholder="Enter amount"
                  :disabled="loading"
                />
              </div>
            </div>

            <!-- Action Buttons -->
            <div class="flex gap-3 align-bottom">
              <router-link :to="{ name: 'payOil', params: { id: deliveryId } }">
                <button class="btn btn-ghost">Cancel</button>
              </router-link>
              <button
                @click="handlePreauthorize"
                class="btn btn-success"
                :disabled="loading || !chargeAmount"
              >
                <span v-if="loading && action === 'preauthorize'" class="loading loading-spinner loading-sm"></span>
                Preauthorize
              </button>
              <button
                @click="handleChargeNow"
                class="btn btn-warning text-black"
                :disabled="loading || !chargeAmount"
              >
                <span v-if="loading && action === 'charge'" class="loading loading-spinner loading-sm"></span>
                Charge Now
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- Charge Confirmation Modal -->
  <div class="modal" :class="{ 'modal-open': isChargeConfirmationModalVisible }">
    <div class="modal-box">
      <h3 class="font-bold text-lg text-warning">⚠️ Warning: Charge Now</h3>
      <p class="py-4">
        You are about to <strong>immediately charge</strong> this customer's card
        for <strong>${{ chargeAmount.toFixed(2) }}</strong>.
        <br><br>
        This action is <strong>not reversible</strong> and will debit the customer's account immediately.
        <br><br>
        Are you sure you want to proceed with the charge?
      </p>
      <div class="modal-action">
        <button @click="proceedWithCharge" class="btn btn-warning">
          Yes, Charge Now
        </button>
        <button @click="cancelCharge" class="btn btn-ghost">
          Cancel
        </button>
      </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,
  DeliveryFormData,
  CustomerFormData,
  CreditCardFormData,
  PricingData,
  PromoData,
  DeliveryOrderResponse,
  DeliveryTotalResponse,
  OilPricingResponse,
  PromoResponse,
  WhoAmIResponse,
  UpdateStatusResponse
} from '../../../types/models'

// Router and route
const route = useRoute()
const router = useRouter()

// Reactive data
const deliveryId = 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 isChargeConfirmationModalVisible = ref(false)
const user = ref({
  user_id: 0,
})
const delivery = ref<DeliveryFormData>({
  id: 0,
  customer_id: 0,
  customer_name: '',
  customer_address: '',
  customer_town: '',
  customer_state: 0,
  customer_zip: '',
  gallons_ordered: 0,
  customer_asked_for_fill: 0,
  gallons_delivered: 0,
  customer_filled: 0,
  delivery_status: 0,
  when_ordered: '',
  when_delivered: '',
  expected_delivery_date: '',
  automatic: 0,
  oil_id: 0,
  supplier_price: 0,
  customer_price: 0,
  customer_temperature: 0,
  dispatcher_notes: '',
  prime: 0,
  promo_id: 0,
  emergency: 0,
  same_day: 0,
  payment_type: 0,
  payment_card_id: 0,
  driver_employee_id: 0,
  driver_first_name: '',
  driver_last_name: '',
  pre_charge_amount: 0,
  total_price: 0,
  service_id: null,
})
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: '',
})
const pricing = ref<PricingData>({
  price_from_supplier: 0,
  price_for_customer: 0,
  price_for_employee: 0,
  price_same_day: 0,
  price_prime: 0,
  price_emergency: 0,
  date: "",
})
const promo_active = ref(false)
const promo = ref<PromoData>({
  name_of_promotion: '',
  description: '',
  money_off_delivery: 0,
  text_on_ticket: ''
})
const total_amount = ref(0)
const discount = ref(0)
const total_amount_after_discount = ref(0)

// Computed properties
const selectedCard = computed(() => {
  return credit_cards.value.find((card) => card.id === delivery.value.payment_card_id)
})

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

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

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

const loadData = (deliveryId: string) => {
  userStatus()
  getOilOrder(deliveryId)
  sumdelivery(deliveryId)
  getOilPricing()
  updatestatus()
}

const updatestatus = () => {
  let path = import.meta.env.VITE_BASE_URL + '/delivery/updatestatus';
  axios({
    method: 'get',
    url: path,
    headers: authHeader(),
  }).then((response: AxiosResponse<UpdateStatusResponse>) => {
    if (response.data.update)
      console.log("Updated Status of Deliveries")
  })
}

const updateChargeAmount = () => {
  // Only update if we have all necessary data
  if (total_amount_after_discount.value > 0 && pricing.value) {
    chargeAmount.value = calculateTotalAsNumber();
    return true;
  }
  return false;
}

const sumdelivery = (delivery_id: number | string) => {
  let path = import.meta.env.VITE_BASE_URL + "/delivery/total/" + delivery_id;
  axios({
    method: "get",
    url: path,
    withCredentials: true,
  })
    .then((response: AxiosResponse<DeliveryTotalResponse>) => {
      if (response.data.ok) {
        total_amount.value = parseFloat(String(response.data.total_amount)) || 0;
        discount.value = parseFloat(String(response.data.discount)) || 0;
        total_amount_after_discount.value = parseFloat(String(response.data.total_amount_after_discount)) || 0;

        // Try to update charge amount with complete pricing
        const updated = updateChargeAmount();

        // Fallback only if pricing not loaded yet and calculation didn't run
        if (!updated) {
          if (promo_active.value) {
            chargeAmount.value = total_amount_after_discount.value;
          } else {
            chargeAmount.value = total_amount.value;
          }
        }
      }
    })
    .catch(() => {
      notify({
        title: "Error",
        text: "Could not get oil pricing",
        type: "error",
      });
    });
}

const getPromo = (promo_id: number) => {
  let path = import.meta.env.VITE_BASE_URL + "/promo/" + promo_id;
  axios({
    method: "get",
    url: path,
    withCredentials: true,
    headers: authHeader(),
  })
    .then((response: AxiosResponse<PromoResponse>) => {
      if (response.data) {
        promo.value = response.data
        promo_active.value = true

        // Trigger a charge amount update if all data is available
        updateChargeAmount();
      }
    })
}

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 getOilPricing = () => {
  let path = import.meta.env.VITE_BASE_URL + "/info/price/oil/table";
  axios({
    method: "get",
    url: path,
    withCredentials: true,
  })
    .then((response: AxiosResponse<{ ok?: boolean; pricing?: OilPricingResponse }>) => {
      pricing.value = response.data?.pricing || (response.data as unknown as PricingData);
      // Try to update charge amount when pricing is loaded
      updateChargeAmount();
    })
    .catch(() => {
      notify({
        title: "Error",
        text: "Could not get oil pricing",
        type: "error",
      });
    });
}

const getOilOrder = (delivery_id: number | string) => {
  let path = import.meta.env.VITE_BASE_URL + "/delivery/order/" + delivery_id;
  axios({
    method: "get",
    url: path,
    withCredentials: true,
  })
    .then((response: AxiosResponse<DeliveryOrderResponse>) => {
      if (response.data && response.data.ok) {
        delivery.value = response.data.delivery as unknown as DeliveryFormData;
        getCustomer(delivery.value.customer_id)
        getCreditCards(delivery.value.customer_id)
        if (delivery.value.promo_id != null) {
          getPromo(delivery.value.promo_id);
          promo_active.value = true;
        }
      } else {
        console.error("API Error:", response.data.error || "Failed to fetch delivery data.");
      }
    })
    .catch((error: Error) => {
      console.error("API Error in getOilOrder:", error);
      notify({
        title: "Error",
        text: "Could not get delivery",
        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[]>) => {
    credit_cards.value = response.data
  })
}

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 getTierPrice = (serviceType: string, tier: number | undefined): number => {
  const tierNum = tier || 1;
  const key = `price_${serviceType}_tier${tierNum}`;
  const legacyKey = `price_${serviceType}`;
  const price = (pricing.value as any)[key] !== undefined ? (pricing.value as any)[key] : (pricing.value as any)[legacyKey];
  return Number(price || 0);
}

const calculateSubtotal = () => {
  const gallons = delivery.value.gallons_ordered || 0
  const pricePerGallon = delivery.value.customer_price || 0
  return (gallons * pricePerGallon).toFixed(2)
}

const calculateTotalAmount = () => {
  if (total_amount_after_discount.value == null || total_amount_after_discount.value === undefined) {
    return '0.00';
  }

  let totalNum = Number(total_amount_after_discount.value);
  if (isNaN(totalNum)) {
    return '0.00';
  }

  if (delivery.value && delivery.value.prime == 1) {
    totalNum += getTierPrice('prime', delivery.value.pricing_tier_prime);
  }
  if (delivery.value && delivery.value.same_day == 1) {
    totalNum += getTierPrice('same_day', delivery.value.pricing_tier_same_day);
  }
  if (delivery.value && delivery.value.emergency == 1) {
    totalNum += getTierPrice('emergency', delivery.value.pricing_tier_emergency);
  }

  return totalNum.toFixed(2);
}

const calculateTotalAsNumber = () => {
  if (total_amount_after_discount.value == null || total_amount_after_discount.value === undefined) {
    return 0;
  }

  let totalNum = Number(total_amount_after_discount.value);
  if (isNaN(totalNum)) {
    return 0;
  }

  if (delivery.value && delivery.value.prime == 1) {
    totalNum += getTierPrice('prime', delivery.value.pricing_tier_prime);
  }
  if (delivery.value && delivery.value.same_day == 1) {
    totalNum += getTierPrice('same_day', delivery.value.pricing_tier_same_day);
  }
  if (delivery.value && delivery.value.emergency == 1) {
    totalNum += getTierPrice('emergency', delivery.value.pricing_tier_emergency);
  }

  return totalNum;
}

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

const handleChargeNow = async () => {
  if (!selectedCard.value) {
    error.value = 'No credit card found for this customer'
    return
  }
  if (!chargeAmount.value || chargeAmount.value <= 0) {
    error.value = 'Please enter a valid charge amount'
    return
  }
  isChargeConfirmationModalVisible.value = true
}

const proceedWithCharge = async () => {
  isChargeConfirmationModalVisible.value = false
  await processPayment('charge')
}

const cancelCharge = () => {
  isChargeConfirmationModalVisible.value = false
}

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),
        delivery_id: delivery.value.id,
      };

      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/${delivery.value.id}`, {}, { 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),
        delivery_id: delivery.value.id,
        service_id: delivery.value.service_id || null,
        // 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 payment type to 11 after successful charge
      try {
        await axios.put(`${import.meta.env.VITE_BASE_URL}/payment/authorize/${delivery.value.id}`, {}, { headers: authHeader() });
      } catch (updateError) {
        console.error('Failed to update payment type 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 = ''
  }
}
</script>

<style scoped></style>
