<!-- src/pages/pay/auto/authorize_precharge_autho.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: 'auto' }">Automatic Deliveries</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: Customer Info/Payment and Charge Breakdown/Pricing -->
        <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
          <!-- Left Column: Customer Info and Payment Method -->
          <div class="space-y-4">
            <!-- Customer Info Card -->
            <div class="bg-neutral rounded-lg p-5">
              <div class="flex justify-between items-center mb-4">
                <div>
                  <div class="text-xl font-bold">{{ customer.customer_first_name }} {{ customer.customer_last_name }}</div>
                  <div class="text-sm text-gray-400">Account: {{ customer.account_number }}</div>
                </div>
                <router-link v-if="customer && customer.id" :to="{ name: 'customerProfile', params: { id: customer.id } }" class="btn btn-secondary btn-sm">
                  View Profile
                </router-link>
              </div>
              <div>
                <div>{{ customer.customer_address }}</div>
                <div v-if="customer.customer_apt && customer.customer_apt !== 'None'">{{ customer.customer_apt }}</div>
                <div>{{ customer.customer_town }}, {{ customerStateName }} {{ customer.customer_zip }}</div>
                <div class="mt-2">{{ customer.customer_phone_number }}</div>
              </div>
            </div>

            <!-- 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="font-mono text-sm">
                  <div> {{ selectedCard.card_number }}</div>
                  <div>{{ selectedCard.name_on_card }}</div>
                  <div>Expires: {{ selectedCard.expiration_month }}/{{ selectedCard.expiration_year }}</div>
                </div>
              </div>
              <div v-else class="text-gray-500 p-4">
                No payment method selected
              </div>
            </div>
          </div>

          <!-- Right Column: Charge Breakdown and Pricing -->
          <div class="space-y-4">
            <!-- 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 to Fill:</span>
                  <span>{{ calculateGallonsToFill() }} gallons</span>
                </div>
                <div class="flex justify-between">
                  <span>Price per Gallon:</span>
                  <span>${{ pricing.price_for_customer || currentOilPrice }}</span>
                </div>
                <div class="flex justify-between font-semibold">
                  <span>Subtotal:</span>
                  <span>${{ calculateSubtotal() }}</span>
                </div>
                <hr class="my-3">
                <div class="flex justify-between font-bold text-lg">
                  <span>Estimated Total:</span>
                  <span>${{ calculateTotalAmount() }}</span>
                </div>
              </div> <!-- close space-y-2 -->
            </div> <!-- close bg-base-100 -->

            <!-- Pricing Chart Card -->
            <div class="bg-neutral rounded-lg p-5">
              <h3 class="text-xl font-bold mb-4">Today's Price Per Gallon</h3>
              <div class="overflow-x-auto">
                <table class="table table-sm w-full">
                  <thead>
                    <tr>
                      <th>Gallons</th>
                      <th>Total Price</th>
                    </tr>
                  </thead>
                  <tbody>
                     <tr v-for="tier in pricingTiers" :key="tier.gallons" :class="isPricingTierSelected(tier.gallons) ? 'bg-blue-600 text-white hover:bg-blue-600' : 'hover'">
                        <td>{{ tier.gallons }}</td>
                        <td>${{ tier.price.toFixed(2) }}</td>
                     </tr>
                  </tbody>
                </table>
              </div>
            </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 class="flex flex-wrap gap-2 mt-2">
                <button v-for="amount in quickGallonAmounts"
                        :key="amount"
                        @click.prevent="setGallons(amount)"
                        :class="['btn', 'btn-xs', selectedGallonAmount == amount ? 'bg-blue-600 text-white border-blue-600' : 'btn-outline']">
                  {{ amount }} gal
                </button>
              </div>
            </div>

            <!-- Action Buttons -->
            <div class="flex gap-3 align-bottom">
              <router-link :to="{ name: 'auto' }">
                <button class="btn btn-ghost">Cancel</button>
              </router-link>
              <button
                @click="handlePreauthorize"
                class="btn btn-success"
                :disabled="loading || !chargeAmount"
                v-show="!success"
              >
                <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"
                v-show="!success"
              >
                <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,
  CustomerFormData,
  CreditCardFormData,
  PricingData,
  OilPricingResponse,
  WhoAmIResponse,
  AutoDeliveryData
} from '../../../types/models'

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 quickGallonAmounts = ref([100, 125, 150, 175, 200, 220])
const loading = ref(false)
const action = ref('') // 'preauthorize' or 'charge'
const error = ref('')
const success = ref('')
const isChargeConfirmationModalVisible = ref(false)
const transactionId = ref(0)
const user = ref({
  user_id: 0,
})
const autoDelivery = ref<AutoDeliveryData>({
  id: 0,
  customer_id: 0,
  customer_full_name: '',
  customer_address: '',
  customer_town: '',
  customer_state: 0,
  customer_zip: '',
  tank_size: 0,
  estimated_gallons_left: 0,
  estimated_gallons_left_prev_day: 0,
  house_factor: 0,
  auto_status: 0,
  account_number: '',
  last_fill: '',
  days_since_last_fill: 0,
  last_updated: '',
  tank_height: '',
  open_ticket_id: null,
  confidence_score: 20,
  k_factor_source: 'default',
  days_remaining: 999,
  gallons_per_day: 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: '',
})
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 currentOilPrice = ref(0)
const pricingTiers = ref([] as { gallons: number; price: number }[])

// Computed
const selectedCard = computed(() => {
  return credit_cards.value.find((card) => card.main_card) || credit_cards.value[0]
})

const customerStateName = computed(() => {
  const states: Record<number, string> = { 0: 'Massachusetts', 1: 'Rhode Island', 2: 'New Hampshire', 3: 'Maine', 4: 'Vermont', 5: 'Connecticut', 6: 'New York' };
  return states[customer.value.customer_state] || 'Unknown state';
})

const selectedGallonAmount = computed(() => {
  return quickGallonAmounts.value.find(gal => calculatePriceForGallons(gal).toFixed(2) === chargeAmount.value.toFixed(2)) || null;
})

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

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

// Functions
const resetState = () => {
  loading.value = false
  action.value = ''
  error.value = ''
  success.value = ''
  chargeAmount.value = 0
}

const loadData = (deliveryId: string) => {
  userStatus()
  getAutoDelivery(deliveryId)
  getOilPricing()
  getCurrentOilPrice()
}

const getCurrentOilPrice = () => {
  let path = import.meta.env.VITE_BASE_URL + '/info/price/oil'
  axios({
    method: "get",
    url: path,
    withCredentials: true,
    headers: authHeader(),
  })
    .then((response: AxiosResponse<OilPricingResponse>) => {
      currentOilPrice.value = response.data.price_for_customer;
      calculateDefaultChargeAmount()
    })
    .catch(() => {
      notify({
        title: "Error",
        text: "Could not get oil pricing",
        type: "error",
      });
    });
}

const calculateDefaultChargeAmount = () => {
  chargeAmount.value = calculateTotalAsNumber()
}

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);
      calculateDefaultChargeAmount()
    })
    .catch(() => {
      notify({
        title: "Error",
        text: "Could not get oil pricing",
        type: "error",
      });
    });
}

const getAutoDelivery = (delivery_id: number | string) => {
  let path = import.meta.env.VITE_AUTO_URL + "/delivery/delivery/" + delivery_id;
  axios({
    method: "get",
    url: path,
    withCredentials: true,
  })
    .then((response: AxiosResponse<AutoDeliveryData>) => {
      if (response.data && response.data.customer_id) {
        autoDelivery.value = response.data;
        getCustomer(autoDelivery.value.customer_id)
        getCreditCards(autoDelivery.value.customer_id)
      } else {
        console.error("API Error: Failed to fetch auto delivery data.");
      }
    })
    .catch((err: Error) => {
      console.error("API Error in getAutoDelivery:", err);
      notify({
        title: "Error",
        text: "Could not get automatic 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 getPricingTiers = () => {
  let path = import.meta.env.VITE_BASE_URL + "/info/price/oil/tiers";
  axios({
    method: "get",
    url: path,
    withCredentials: true,
    headers: authHeader()
  })
    .then((response: AxiosResponse<Record<string, number>>) => {
      pricingTiers.value = Object.entries(response.data).map(([gallons, price]) => ({ gallons: parseInt(gallons, 10), price: Number(price) }));
    })
    .catch(() => {
      notify({
        title: "Pricing Error",
        text: "Could not retrieve today's pricing.",
        type: "error"
      });
    });
}

const isPricingTierSelected = (tierGallons: number | string): boolean => {
  const calculated = calculateGallonsToFill()
  return calculated == Number(tierGallons)
}

const calculatePriceForGallons = (gallons: number): number => {
  let priceForGallons = 0;
  const sortedTiers = [...pricingTiers.value].sort((a, b) => Number(a.gallons) - Number(b.gallons));

  // Find the highest tier that is less than or equal to the gallons ordered
  let applicableTier = sortedTiers.filter(t => gallons >= Number(t.gallons)).pop();

  if (applicableTier) {
    const pricePerGallon = Number(applicableTier.price) / Number(applicableTier.gallons);
    priceForGallons = gallons * pricePerGallon;
  } else if (sortedTiers.length > 0) {
    // Fallback to the lowest tier's price/gallon if no tier is met (e.g., ordering 50 gallons when lowest tier is 100)
    const lowestTier = sortedTiers[0];
    const pricePerGallon = Number(lowestTier.price) / Number(lowestTier.gallons);
    priceForGallons = gallons * pricePerGallon;
  }

  return priceForGallons;
}

const setGallons = (gallons: number) => {
  chargeAmount.value = calculatePriceForGallons(gallons);
}

const calculateGallonsToFill = () => {
  return Number(autoDelivery.value.tank_size) - autoDelivery.value.estimated_gallons_left
}

const calculateSubtotal = () => {
  const gallons = calculateGallonsToFill()
  const pricePerGallon = pricing.value.price_for_customer || currentOilPrice.value
  return (gallons * pricePerGallon).toFixed(2)
}

const calculateTotalAmount = () => {
  const subtotal = parseFloat(calculateSubtotal())
  let total = subtotal

  // No additional fees for auto preauthorization

  return total.toFixed(2)
}

const calculateTotalAsNumber = () => {
  return parseFloat(calculateTotalAmount())
}

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

const handleChargeNow = async () => {
  loading.value = true
  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: null,
        auto_id: deliveryId.value,
      };

      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() });

      if (!response.data.auth_net_transaction_id || response.data.auth_net_transaction_id.trim() === '') {
        throw new Error("Failed transaction: No Authorize.net transaction ID received");
      }

      transactionId.value = response.data.id;

      // Update auto_delivery status to 3
      await axios.put(`${import.meta.env.VITE_AUTO_URL}/delivery/update_status/${deliveryId.value}`, {}, { withCredentials: true, headers: authHeader() });

      // Create Tickets_Auto_Delivery after successful preauthorize
      const ticketPayload = {
        gallons_delivered: 0,
        payment_type: 11, // 11 for preauthorize, 1 for charge
        payment_card_id: selectedCard.value!.id,
        payment_status: 1 // Pre-authorized status (ready for capture)
      };
      const ticketUrl = `${import.meta.env.VITE_AUTO_URL}/confirm/auto/create/${deliveryId.value}`;
      const ticketResponse = await axios.post(ticketUrl, ticketPayload, { withCredentials: true, headers: authHeader() });
      console.log('Ticket response data:', ticketResponse.data, 'type:', typeof ticketResponse.data, 'keys:', ticketResponse.data ? Object.keys(ticketResponse.data) : 'no data');

      // Update transaction auto_id to ticket ID
      if (transactionId.value && ticketResponse.data) {
        const data = Array.isArray(ticketResponse.data) ? ticketResponse.data[0] : ticketResponse.data;
        if (data && data.auto_ticket_id !== undefined) {
          await axios.put(`${import.meta.env.VITE_AUTHORIZE_URL}/api/transaction/${transactionId.value}/update_auto_id/${data.auto_ticket_id}`, {}, { withCredentials: true, headers: authHeader() });
        } else {
          console.error('auto_ticket_id is undefined in ticket response');
        }
      }

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

      const chargePayload = {
        card_id: selectedCard.value!.id,
        charge_amount: chargeAmount.value.toFixed(2),
        delivery_id: deliveryId.value,
      };

      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 auto_delivery status to 3
      await axios.put(`${import.meta.env.VITE_AUTO_URL}/delivery/update_status/${deliveryId.value}`, {}, { withCredentials: true, headers: authHeader() });

      // Status codes: 0 = APPROVED, 1 = DECLINED (based on backend TransactionStatus enum)
      if (response.data && response.data.status === 0) { // 0 = APPROVED
        if (!response.data.auth_net_transaction_id || response.data.auth_net_transaction_id.trim() === '') {
          throw new Error("Failed transaction: No Authorize.net transaction ID received");
        }
        transactionId.value = response.data.id;
        success.value = `Charge successful! Transaction ID: ${response.data.auth_net_transaction_id}`;

        // Create Tickets_Auto_Delivery after successful charge
        const ticketPayload = {
          gallons_delivered: 0,
          payment_type: 11, // 11 for Authorize charge
          payment_card_id: selectedCard.value!.id,
          payment_status: response.data.status // 0 = APPROVED
        };
        const ticketUrl = `${import.meta.env.VITE_AUTO_URL}/confirm/auto/create/${deliveryId.value}`;
        console.log("POOOPP!")
        await axios.post(ticketUrl, ticketPayload, { withCredentials: true, headers: authHeader() });

        setTimeout(() => {
          router.push({ name: "auto" });
        }, 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>
