"use client";

import ToastMessage from "@/components/common/ToastMessage";
import { Button } from "@/components/ui/button";
import { AddressDialog } from "@/components/user/address/address-dialog";
import { AppDispatch, RootState } from "@/redux/store";
import { Loader2, PlusIcon } from "lucide-react";
import { useEffect, useState, useCallback } from "react";
import { useDispatch, useSelector } from "react-redux";
import axios from "axios"
import { useRouter } from "next/navigation";
import Cookies from "js-cookie";
import { fetchCartFromBackend } from "@/redux/slices/cartSlice";
import { useSession } from "next-auth/react";
import PriceDisplay from "@/components/ui/formattedPrice";

export default function CheckoutPage() {

  const router = useRouter();
  const { data: session } = useSession();


  const dispatch = useDispatch<AppDispatch>();

  const [selectedPayment, setSelectedPayment] = useState("Cash On Delivery");
  const [selectedDelivery, setSelectedDelivery] = useState("FedEx");
  const [addresses, setAddresses] = useState<Address[]>([]);
  const [selectedAddress, setSelectedAddress] = useState<Address | null>(null);

  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [phone, setPhone] = useState("");
  const [rname, setRname] = useState("");
  const [loading, setLoading] = useState(true);

  const cart = useSelector((state: RootState) => state.cart);
  const [isMounted, setIsMounted] = useState(false);

  const [total, setTotal] = useState(cart.totalPrice);
  const [deliveryCost, setDeliveryCost] = useState(0);

  const [couponCode, setCouponCode] = useState("");

  const calculateDeliveryCost = useCallback(async (uuid: string) => {
    try {
      const response = await axios.get(`/api/checkout/deliveryCost/${uuid}`);
      if (response.status === 200) {
        const cost = response.data.mssg;
        setDeliveryCost(cost);
        setTotal(cart.totalPrice + cost);
        setLoading(false)
      } else {
        ToastMessage("Failed to fetch delivery cost", "error");
      }
    } catch {
      ToastMessage("Failed to fetch delivery cost", "error");
    }
  }, [cart.totalPrice]);

  const handleAddressChange = async (address: Address) => {

    await calculateDeliveryCost(address.uuid);


    setSelectedAddress(address)
  }


  const submitForm = async (e: React.FormEvent) => {
    e.preventDefault()

    if (!selectedAddress) {
      ToastMessage("Please select an address", "error");
      return;
    }
    else if (!name || !email || !phone || !rname) {
      ToastMessage("Please fill all the fields", "error");
      return;
    }
    else if (!selectedPayment) {
      ToastMessage("Please select a payment method", "error");
      return;
    }
    else if (!selectedDelivery) {
      ToastMessage("Please select a delivery method", "error");
      return;
    }
    else {
      const formData = new FormData()

      formData.append("name", name);
      formData.append("email", email);
      formData.append("phone", phone);
      formData.append("rname", rname);
      formData.append("address_uuid", selectedAddress.uuid);
      formData.append("payment_method", selectedPayment);
      formData.append("delivery_method", selectedDelivery)
      formData.append('delivery_cost', deliveryCost.toString());

      const response = await axios.post("/api/checkout", formData)

      if (response.status === 200) {
        // ToastMessage("Order placed successfully", "success")
        // Reset form fields
        setName("");
        setEmail("");
        setPhone("");
        setRname("");
        setSelectedAddress(null);
        setSelectedPayment("Credit Card");
        setSelectedDelivery("FedEx");

        Cookies.remove("cart")

        dispatch(fetchCartFromBackend())

        router.push(`/checkout/place-order/${response.data.orderNumber}`)

      } else if (response.status === 201) {
        setName("");
        setEmail("");
        setPhone("");
        setRname("");
        setSelectedAddress(null);
        setSelectedPayment("Credit Card");
        setSelectedDelivery("FedEx");

        Cookies.remove("cart")

        dispatch(fetchCartFromBackend())

        const data = response.data

        const payment_url = response.data.payment_url

        console.log(data)
        console.log(payment_url)

        window.location.href = payment_url

      }

      else {
        ToastMessage("Failed to place order", "error");
      }

    }

  }

  useEffect(() => {
    if (!session?.user) {
      ToastMessage("Please login to continue", "error");
      router.push("/login");
    }
  }, [session?.user, router]);

  useEffect(() => {
    setIsMounted(true);
  }, []);


  const fetchAddress = useCallback(async () => {
    const res = await fetch("/api/user/address");
    const data = await res.json();
    const selA = data.mssg.find((address: Address) => address.is_default === true);
    setSelectedAddress(selA);
    setAddresses(data.mssg);
    setLoading(false)

  }, [])

  useEffect(() => {

    if (session?.user) {
      fetchAddress()
    }
  }, [fetchAddress, session?.user]);


  useEffect(() => {
    if (selectedAddress?.uuid) {
      calculateDeliveryCost(selectedAddress.uuid);
    }
  }, [selectedAddress, calculateDeliveryCost]);


  const applyCoupon = async () => {

    if (couponCode.trim() === "") {
      ToastMessage("Please enter a coupon code", "error");
      return;
    }

    const response = await fetch("/api/checkout/coupons", {
      method: "POST",
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({
        "code": couponCode
      })
    })

    setCouponCode("")

    if (response.status !== 200) {
      const data = await response.json()
      ToastMessage(data.message, "error");
      return;
    }
    else {
      dispatch(fetchCartFromBackend())

    }

    ToastMessage("Coupon applied successfully", "success");
  }

  const removeCoupon = async () => {
    const response = await fetch("/api/checkout/coupons", {
      method: "DELETE",
      headers: {},
    })
    if (response.status !== 200) {
      const data = await response.json()
      ToastMessage(data.message, "error");
      return;
    }
    else{
      dispatch(fetchCartFromBackend())
      ToastMessage("Coupon removed successfully", "success");
    }

  }


  if (loading) {
    return <Loader2 className="animate-spin h-10 w-10 text-blue-600 mx-auto mt-20" />
  }

  else if (cart.totalQuantity == 0) {
    return (
      <div className="flex justify-center items-center min-h-screen">
        <div className="text-center">
          <h1 className="text-2xl font-bold mb-4">Your Cart is Empty</h1>
          <p className="text-gray-600 mb-6">Add some products to your cart to proceed with checkout.</p>
          <Button onClick={() => router.push('/')} className="bg-blue-600 text-white hover:bg-blue-700">
            Go to Home
          </Button>
        </div>
      </div>
    );
  }


  else {
    return (
      <div className="flex justify-center items-start px-4 py-8 min-h-screen bg-white">
        <form className="flex flex-col lg:flex-row w-full max-w-[1300px] gap-6" onSubmit={(e) => submitForm(e)}>
          {/* Left Section */}
          <div className="w-full lg:w-2/3 space-y-10">
            <div>
              <h2 className="text-xl font-semibold text-gray-800 mb-4">Delivery Details</h2>
              <div className="grid grid-cols-2 gap-4">
                <div className="flex flex-col">
                  <label htmlFor="name" className="text-sm mb-1">Your name</label>
                  <input className="input" onChange={(e) => setName(e.target.value)} type="text" name="name" placeholder="John Doe" required />
                </div>
                <div className="flex flex-col">
                  <label htmlFor="email" className="text-sm mb-1">Receiver&apos;s email</label>
                  <input className="input" onChange={(e) => setEmail(e.target.value)} type="email" name="email" placeholder="Johndoe@gmail.com" required />
                </div>
                <div className="flex flex-col">
                  <label htmlFor="phone" className="text-sm mb-1">Receiver&apos;s Phone</label>
                  <input className="input" onChange={(e) => setPhone(e.target.value)} type="number" name="phone" placeholder="01XXXXXXXXX" required />
                </div>
                <div className="flex flex-col">
                  <label htmlFor="rname" className="text-sm mb-1">Receiver&apos;s name</label>
                  <input className="input" onChange={(e) => setRname(e.target.value)} type="text" name="rname" placeholder="John Doe" required />
                </div>
                {addresses && addresses.map((address) => (
                  <div
                    key={address.uuid}
                    onClick={() => handleAddressChange(address)}
                    className={`border flex justify-between rounded-lg p-4 cursor-pointer shadow-sm transition hover:shadow-md ${selectedAddress === address ? 'border-blue-600 bg-blue-50' : 'border-gray-200'}`}
                  >
                    <div>
                      <h3 className="font-semibold text-sm">{address.name}</h3>
                      <p className="text-sm text-muted-foreground">
                        {address.address_line}<br />
                        {address.city}, {address.district} {address.post_code}<br />
                        {address.division}
                      </p>
                    </div>
                    {address.is_default && (
                      <div className="bg-black rounded-2xl px-2 py-1 self-start">
                        <p className="font-bold text-white text-xs">Default</p>
                      </div>
                    )}
                  </div>
                ))}
                <AddressDialog>
                  <Button className="text-white col-span-2">
                    <PlusIcon className="mr-2 h-4 w-4 text-white" />
                    Add New Address
                  </Button>
                </AddressDialog>
              </div>
            </div>
            
            
            <div>
              <h2 className="text-xl font-semibold text-gray-800 mb-4">Payment</h2>
              <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                {["BKASH", "Cash On Delivery"].map(option => (
                  <div
                    key={option}
                    onClick={() => setSelectedPayment(option)}
                    className={`border rounded-lg p-4 cursor-pointer shadow-sm transition hover:shadow-md ${selectedPayment === option ? 'border-blue-600 bg-blue-50' : 'border-gray-200'}`}
                  >
                    <p className="font-medium text-gray-800">{option}</p>
                    <div className="mt-2 text-sm text-gray-500 flex justify-between">
                      <span>{option === 'Cash On Delivery' ? '+ fee applicable' : option === 'BKASH' ? 'Pay with Bkash' : "Error"}</span>
                      {/* <span className="text-blue-500 text-xs">Edit</span> */}
                    </div>
                  </div>
                ))}
              </div>
            </div>


          </div>

          {/* Order Summary */}
          <div className="w-full lg:w-1/3 border border-gray-200 px-8 py-10 rounded-3xl shadow-xl bg-gradient-to-b from-white to-gray-50 self-start backdrop-blur-sm transition-all duration-300 hover:shadow-2xl hover:-translate-y-1">
            <h2 className="text-2xl font-bold text-gray-800 mb-8 text-center tracking-wide border-b pb-3">
              Order Summary
            </h2>

            <div className="space-y-4 text-gray-700 text-sm">
              <div className="flex justify-between py-2 border-b border-gray-100">
                <span className="font-medium">Subtotal</span>
                {isMounted && (
                  <span className="font-semibold text-gray-900">
                    <PriceDisplay price={cart.totalPrice} />
                  </span>
                )}
              </div>

              <div className="flex justify-between py-2 border-b border-gray-100">
                <span className="font-medium">Savings</span>
                {isMounted && (
                  <span className="font-semibold text-green-600">
                    -<PriceDisplay price={cart.discountAmount} />
                  </span>
                )}
              </div>

              <div className="flex justify-between py-2 border-b border-gray-100">
                <span className="font-medium">Store Pickup</span>
                <span className="font-semibold text-gray-900">
                  <PriceDisplay price={0} />
                </span>
              </div>

              <div className="flex justify-between py-2 border-b border-gray-100">
                <span className="font-medium">Delivery Cost</span>
                {isMounted && (
                  <span className="font-semibold text-gray-900">
                    <PriceDisplay price={deliveryCost} />
                  </span>
                )}
              </div>

              <div className="flex justify-between pt-5 text-lg font-extrabold border-t border-gray-200">
                <span>Total</span>
                {isMounted && (
                  <span className="font-extrabold text-lime-600">
                    <PriceDisplay price={total - cart.discountAmount} />
                  </span>
                )}
              </div>
            </div>

            {/* Coupon Section */}
            <div className="flex items-center gap-2 mt-6">
              <input
                type="text"
                value={couponCode}
                onChange={(e) => setCouponCode(e.target.value)}
                name="coupon"
                placeholder="Enter coupon code"
                className="flex-1 border border-gray-300 focus:border-lime-400 focus:ring-2 focus:ring-lime-200 transition-all duration-200 rounded-lg px-3 py-2 text-sm outline-none"
              />
              <button
                onClick={() => applyCoupon()}
                type="button"
                className="border-none bg-gradient-to-r from-lime-400 to-lime-500 text-white font-semibold px-4 py-2 rounded-lg shadow-md hover:shadow-lg hover:from-lime-500 hover:to-lime-600 transition-all duration-200"
              >
                Apply
              </button>
            </div>

            <div>
              {cart.discountAmount > 0 && (
                <div className="flex items-center gap-3 bg-green-50 border border-green-200 px-4 py-2 rounded-xl mt-2 shadow-sm">
                  <div className="flex items-center gap-2">
                    <span className="text-green-700 font-medium text-sm">
                      Coupon applied successfully!
                    </span>

                    <span className="px-2 py-0.5 text-xs font-semibold bg-green-100 text-green-700 rounded-full border border-green-300">
                      {cart.discountCode}
                    </span>
                  </div>

                  <button
                    type="button"
                    onClick={removeCoupon}
                    className="ml-auto text-green-700 hover:text-red-600 transition text-lg leading-none font-bold px-2"
                  >
                    ×
                  </button>
                </div>
              )}
            </div>


            {/* Place Order Button */}
            <button className="w-full mt-6 text-white bg-gradient-to-r from-lime-400 via-lime-500 to-lime-600 hover:from-lime-500 hover:to-lime-700 transition-all duration-300 focus:ring-4 focus:outline-none focus:ring-lime-200 font-semibold rounded-xl px-5 py-3 text-center uppercase tracking-wide shadow-lg hover:shadow-xl">
              Place Order
            </button>
          </div>

        </form>
      </div>
    )
  }

}
