"use client";

import { fetchData } from '@/lib/data-service';
import { useEffect, useState } from "react";
import { useParams } from "next/navigation";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Clipboard, Truck, Package, ArrowRight, ChevronDown } from "lucide-react";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import Layout from "@/components/layout/layout";
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from "@/components/ui/collapsible";

interface Order {
  orderId: string;
  status: string;
  pgpAddress: string;
  shippingMethod: { type: string; price: number };
  txid: Array<string>;
  products: Array<{
    _id: string;
    productId: string;
    quantity: number;
    pricePerUnit: number;
    totalItemPrice: number;
  }>;
  totalPrice: number;
  trackingNumber?: string;
}

interface OrderInList extends Order {
  _id: string;
}

interface OrdersResponse {
  orders: OrderInList[];
  page: number;
  totalPages: number;
  totalOrders: number;
}

const getStatusVariant = (status: string) => {
  switch (status) {
    case 'acknowledged':
      return 'secondary';
    case 'paid':
      return 'default';
    case 'shipped':
      return 'default';
    case 'completed':
      return 'default';
    case 'cancelled':
      return 'destructive';
    case 'unpaid':
      return 'secondary';
    default:
      return 'secondary';
  }
};

export default function OrderDetailsPage() {
  const [order, setOrder] = useState<Order | null>(null);
  const [trackingNumber, setTrackingNumber] = useState("");
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");
  const [productNames, setProductNames] = useState<Record<string, string>>({});
  const [isPaid, setIsPaid] = useState(false);
  const [isSending, setIsSending] = useState(false);
  const [isMarkingShipped, setIsMarkingShipped] = useState(false);
  const [isDiscarding, setIsDiscarding] = useState(false);
  const [nextOrderId, setNextOrderId] = useState<string | null>(null);
  const [prevOrderId, setPrevOrderId] = useState<string | null>(null);
  const [totalOrders, setTotalOrders] = useState(0);
  const [currentOrderNumber, setCurrentOrderNumber] = useState(0);
  const [totalPages, setTotalPages] = useState(1);
  const [currentPage, setCurrentPage] = useState(1);
  const [isAcknowledging, setIsAcknowledging] = useState(false);
  const [isCancelling, setIsCancelling] = useState(false);

  const router = useRouter();
  const params = useParams();
  const orderId = params?.id;

  const fetchProductNames = async (
    productIds: string[],
    authToken: string
  ): Promise<Record<string, string>> => {
    const productNamesMap: Record<string, string> = {};
    try {
      const promises = productIds.map((id) =>
        fetchData(`${process.env.NEXT_PUBLIC_API_URL}/products/${id}`, {
          method: "GET",
          headers: { Authorization: `Bearer ${authToken}` },
        })
      );
      const responses = await Promise.all(promises);
      const results = await Promise.all(responses.map((res) => res));
  
      results.forEach((product, index) => {
        productNamesMap[productIds[index]] = product.name || "Unknown Product";
      });

    } catch (err) {
      console.error("Failed to fetch product names:", err);
    }
    return productNamesMap;
  };

  const handleMarkAsPaid = async () => {
    try {
      // Add a loading state to give feedback
      const loadingToast = toast.loading("Marking order as paid...");
      
      const authToken = document.cookie
        .split("; ")
        .find((row) => row.startsWith("Authorization="))
        ?.split("=")[1];
      
      if (!authToken) {
        toast.dismiss(loadingToast);
        toast.error("Authentication error - please log in again");
        return;
      }
      
      // Log the request for debugging
      console.log(`Sending request to ${process.env.NEXT_PUBLIC_API_URL}/orders/${orderId}/status`);
      console.log("Request payload:", { status: "paid" });
      
      const response = await fetchData(
        `${process.env.NEXT_PUBLIC_API_URL}/orders/${orderId}/status`,
        {
          method: "PUT",
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${authToken}`,
          },
          body: JSON.stringify({ status: "paid" }),
        }
      );
      
      // Log the response
      console.log("API response:", response);

      toast.dismiss(loadingToast);
      
      if (response && response.message === "Order status updated successfully") {
        // Update both states
        setIsPaid(true);
        setOrder((prevOrder) => (prevOrder ? { ...prevOrder, status: "paid" } : null));
        toast.success("Order marked as paid successfully");
      } else {
        // Handle unexpected response format
        console.error("Unexpected response format:", response);
        throw new Error(
          response.error || response.message || "Failed to mark order as paid"
        );
      }
    } catch (error: any) {
      console.error("Failed to mark order as paid:", error);
      
      // More detailed error handling
      let errorMessage = "Failed to mark order as paid";
      
      if (error.message) {
        errorMessage += `: ${error.message}`;
      }
      
      if (error.response) {
        try {
          const errorData = await error.response.json();
          console.error("Error response data:", errorData);
          if (errorData.message) {
            errorMessage = errorData.message;
          }
        } catch (e) {
          console.error("Could not parse error response:", e);
        }
      }
      
      toast.error(errorMessage);
    }
  };

  const handleMarkAsShipped = async () => {
    try {
      setIsMarkingShipped(true);
      const authToken = document.cookie.split("Authorization=")[1];
      const response = await fetchData(
        `${process.env.NEXT_PUBLIC_API_URL}/orders/${orderId}/status`,
        {
          method: "PUT",
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${authToken}`,
          },
          body: JSON.stringify({ status: "shipped" }),
        }
      );

      if (response && response.message === "Order status updated successfully") {
        setOrder((prevOrder) => prevOrder ? { ...prevOrder, status: "shipped" } : null);
        toast.success("Order marked as shipped successfully!");
      } else {
        throw new Error(response.error || "Failed to mark order as shipped");
      }
    } catch (error: any) {
      console.error("Failed to mark order as shipped:", error);
      toast.error(error.message || "Failed to mark order as shipped");
    } finally {
      setIsMarkingShipped(false);
    }
  };

  const handleMarkAsAcknowledged = async () => {
    try {
      setIsAcknowledging(true);
      const authToken = document.cookie.split("Authorization=")[1];
      const response = await fetchData(
        `${process.env.NEXT_PUBLIC_API_URL}/orders/${orderId}/status`,
        {
          method: "PUT",
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${authToken}`,
          },
          body: JSON.stringify({ status: "acknowledged" }),
        }
      );

      if (response && response.message === "Order status updated successfully") {
        setOrder((prevOrder) => prevOrder ? { ...prevOrder, status: "acknowledged" } : null);
        toast.success("Order marked as acknowledged!");
      } else {
        throw new Error(response.error || "Failed to mark order as acknowledged");
      }
    } catch (error: any) {
      console.error("Failed to mark order as acknowledged:", error);
      toast.error(error.message || "Failed to mark order as acknowledged");
    } finally {
      setIsAcknowledging(false);
    }
  };

  const handleDiscardOrder = async () => {
    try {
      setIsDiscarding(true);
      const authToken = document.cookie.split("Authorization=")[1];
      const response = await fetchData(
        `${process.env.NEXT_PUBLIC_API_URL}/orders/${orderId}`,
        {
          method: "DELETE",
          headers: {
            Authorization: `Bearer ${authToken}`,
          },
        }
      );

      if (response && response.message === "Order deleted successfully") {
        toast.success("Order deleted successfully!");
        router.push('/dashboard/orders');
      } else {
        throw new Error(response.error || "Failed to delete order");
      }
    } catch (error: any) {
      console.error("Failed to delete order:", error);
      toast.error(error.message || "Failed to delete order");
    } finally {
      setIsDiscarding(false);
    }
  };

  const handleCancelOrder = async () => {
    try {
      setIsCancelling(true);
      const authToken = document.cookie.split("Authorization=")[1];
      
      // Update to match the correct API endpoint structure
      const response = await fetchData(
        `${process.env.NEXT_PUBLIC_API_URL}/orders/${orderId}/status`,
        {
          method: "PUT",
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${authToken}`,
          },
          body: JSON.stringify({ status: "cancelled" }),
        }
      );

      if (response && response.message === "Order status updated successfully") {
        setOrder((prevOrder) => prevOrder ? { ...prevOrder, status: "cancelled" } : null);
        toast.success("Order cancelled successfully");
      } else {
        throw new Error(response.error || "Failed to cancel order");
      }
    } catch (error: any) {
      console.error("Failed to cancel order:", error);
      toast.error(error.message || "Failed to cancel order");
    } finally {
      setIsCancelling(false);
    }
  };

  useEffect(() => {
    const fetchOrderDetails = async () => {
      try {
        if (!orderId) return;

        const authToken = document.cookie.split("Authorization=")[1];

        const res = await fetchData(
          `${process.env.NEXT_PUBLIC_API_URL}/orders/${orderId}`,
          {
            method: "GET",
            headers: { Authorization: `Bearer ${authToken}` },
          }
        );

        if (!res) throw new Error("Failed to fetch order details");

        const data: Order = await res;
        setOrder(data);
        console.log(data);

        const productIds = data.products.map((product) => product.productId);
        const productNamesMap = await fetchProductNames(productIds, authToken);
        setProductNames(productNamesMap);

        if (data.status === "paid") {
          setIsPaid(true);
        }
      } catch (err: any) {
        router.push("/dashboard/orders");
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchOrderDetails();
  }, [orderId]);

  useEffect(() => {
    const fetchAdjacentOrders = async () => {
      try {
        const authToken = document.cookie.split("Authorization=")[1];
        
        if (!order?.orderId) return;

        // Get the current numerical orderId
        const currentOrderId = parseInt(order.orderId);
        console.log('Current orderId (numerical):', currentOrderId);

        // Use the new optimized backend endpoint to get adjacent orders
        const adjacentOrdersUrl = `${process.env.NEXT_PUBLIC_API_URL}/orders/adjacent/${currentOrderId}`;
        console.log('Fetching adjacent orders:', adjacentOrdersUrl);
        
        const adjacentOrdersRes = await fetchData(
          adjacentOrdersUrl,
          {
            method: "GET",
            headers: { Authorization: `Bearer ${authToken}` },
          }
        );

        console.log('Adjacent orders response:', adjacentOrdersRes);

        if (!adjacentOrdersRes) {
          console.error("Invalid response from adjacent orders endpoint");
          return;
        }

        // Set the next and previous order IDs
        const { newer, older } = adjacentOrdersRes;
        
        // Set IDs for navigation
        setPrevOrderId(newer?._id || null);
        setNextOrderId(older?._id || null);
        
        if (newer) {
          console.log(`Newer order: ${newer.orderId} (ID: ${newer._id})`);
        } else {
          console.log('No newer order found');
        }
        
        if (older) {
          console.log(`Older order: ${older.orderId} (ID: ${older._id})`);
        } else {
          console.log('No older order found');
        }

      } catch (error) {
        console.error("Failed to fetch adjacent orders:", error);
      }
    };

    if (order) {
      fetchAdjacentOrders();
    }
  }, [order]);

  const handleAddTracking = async () => {
    if (!trackingNumber) {
      toast.error("Please enter a tracking number");
      return;
    }

    try {
      setIsSending(true);
      const authToken = document.cookie.split("Authorization=")[1];

      const response = await fetchData(
        `${process.env.NEXT_PUBLIC_API_URL}/orders/${orderId}/tracking`,
        {
          method: "PUT",
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${authToken}`,
          },
          body: JSON.stringify({ trackingNumber }),
        }
      );

      if (response.error) throw new Error(response.error);

      // Update the local state
      setOrder(prevOrder => prevOrder ? {
        ...prevOrder,
        trackingNumber: trackingNumber
      } : null);
      
      toast.success("Tracking number updated successfully!");
      setTrackingNumber(""); // Clear the input
    } catch (err: any) {
      console.error("Failed to update tracking:", err);
      toast.error(err.message || "Failed to update tracking number");
    } finally {
      setIsSending(false);
    }
  };

  const copyToClipboard = (text: string) => {
    navigator.clipboard.writeText(text);
  };

  if (loading)
    return (
      <Layout>
        <div className="text-center py-10">Loading order details...</div>
      </Layout>
    );
  if (error)
    return (
      <Layout>
        <div className="text-center text-red-500 py-10">Error: {error}</div>
      </Layout>
    );

  return (
    <Layout>
      <div className="container mx-auto px-4 py-8">
        <div className="space-y-6">
          <div className="flex justify-between items-center">
            <div className="flex items-center gap-4">
              <h1 className="text-3xl font-bold">Order Details: {order?.orderId}</h1>
            </div>
            <div className="flex items-center gap-2">
              <Badge 
                variant={getStatusVariant(order?.status || '')}
                className={`${
                  order?.status === 'acknowledged' 
                    ? '!bg-purple-600 hover:!bg-purple-700 text-white' 
                    : order?.status === 'paid'
                    ? 'bg-emerald-600 hover:bg-emerald-700 text-white'
                    : order?.status === 'shipped'
                    ? 'bg-blue-600 hover:bg-blue-700 text-white'
                    : order?.status === 'completed'
                    ? 'bg-green-600 hover:bg-green-700 text-white'
                    : ''
                }`}
              >
                {order?.status}
              </Badge>
            </div>
          </div>

          {/* Order Navigation - Moved to top */}
          <div className="flex justify-between items-center border-b pb-4">
            <div className="w-[140px]">
              {nextOrderId && (
                <Button
                  variant="outline"
                  size="lg"
                  onClick={() => {
                    setLoading(true);
                    router.push(`/dashboard/orders/${nextOrderId}`);
                  }}
                  className="flex items-center"
                >
                  <span className="mr-2">←</span>
                  Older
                </Button>
              )}
            </div>
            <div className="text-center text-sm text-muted-foreground">
              Navigate Orders
            </div>
            <div className="w-[140px] flex justify-end">
              {prevOrderId && (
                <Button
                  variant="outline"
                  size="lg"
                  onClick={() => {
                    setLoading(true);
                    router.push(`/dashboard/orders/${prevOrderId}`);
                  }}
                  className="flex items-center"
                >
                  Newer
                  <span className="ml-2">→</span>
                </Button>
              )}
            </div>
          </div>

          <div className="grid gap-6 md:grid-cols-2">
            <Card>
              <CardHeader>
                <CardTitle>PGP Encrypted Address</CardTitle>
                <CardDescription>
                  Securely encrypted delivery address
                </CardDescription>
              </CardHeader>
              <CardContent>
                <Textarea
                  value={order?.pgpAddress || ""}
                  readOnly
                  className="font-mono text-xs"
                  rows={10}
                />
              </CardContent>
              <CardFooter>
                <Button
                  variant="outline"
                  onClick={() => copyToClipboard(order?.pgpAddress || "")}
                >
                  <Clipboard className="w-4 h-4 mr-2" />
                  Copy to Clipboard
                </Button>
              </CardFooter>
            </Card>

            <Card>
              <CardHeader>
                <CardTitle>Shipping Information</CardTitle>
                <CardDescription>
                  Shipping method and tracking details
                </CardDescription>
              </CardHeader>
              <CardContent className="space-y-4">
                <div className="space-y-2">
                  <Label>Shipping Method</Label>
                  <div className="text-sm text-gray-700 dark:text-gray-300 font-medium">
                    {order?.shippingMethod.type} - £
                    {order?.shippingMethod.price.toFixed(2)}
                  </div>
                </div>
                <div className="space-y-2">
                  <Label htmlFor="tracking">Tracking Number</Label>
                  <Input
                    id="tracking"
                    value={trackingNumber}
                    onChange={(e) => setTrackingNumber(e.target.value)}
                    placeholder="Enter tracking number"
                  />
                </div>
              </CardContent>
              <CardFooter>
                <Button 
                  onClick={handleAddTracking} 
                  disabled={isSending || !trackingNumber.trim()}
                >
                  <Package className="w-4 h-4 mr-2" />
                  {isSending ? "Updating..." : "Update Tracking"}
                </Button>
              </CardFooter>
            </Card>
          </div>

          <Card>
            <CardHeader>
              <CardTitle>Order Items</CardTitle>
            </CardHeader>
            <CardContent>
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Item</TableHead>
                    <TableHead>Quantity</TableHead>
                    <TableHead>Price</TableHead>
                    <TableHead>Total</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {order?.products.map((product) => (
                    <TableRow key={product._id}>
                      <TableCell>
                        {productNames[product.productId] || "Loading..."}
                      </TableCell>
                      <TableCell>{product.quantity}</TableCell>
                      <TableCell>£{product.pricePerUnit.toFixed(2)}</TableCell>
                      <TableCell>£{product.totalItemPrice.toFixed(2)}</TableCell>
                    </TableRow>
                  ))}
                  <TableRow>
                    <TableCell colSpan={3} className="font-bold text-right">
                      Total:
                    </TableCell>
                    <TableCell className="font-bold">
                      £{order?.totalPrice.toFixed(2)}
                    </TableCell>
                  </TableRow>
                </TableBody>
              </Table>
            </CardContent>
          </Card>

          {/* Add Crypto Transaction Details */}
          <Collapsible>
            <div className="rounded-lg border bg-card text-card-foreground shadow-sm">
              <CollapsibleTrigger className="w-full">
                <div className="p-6 flex items-center justify-between">
                  <h3 className="text-lg font-semibold">Crypto Transactions</h3>
                  <ChevronDown className="h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200 [&[data-state=open]]:rotate-180" />
                </div>
              </CollapsibleTrigger>
              <CollapsibleContent>
                <div className="px-6 pb-6">
                  {order?.txid && order.txid.length > 0 ? (
                    <div className="space-y-3">
                      {order.txid.slice(order.txid.length > 2 ? 1 : 0).map((txid: string, index: number) => (
                        <div 
                          key={index}
                          className="p-3 bg-muted rounded-md"
                        >
                          <code className="text-sm break-all">{txid}</code>
                        </div>
                      ))}
                    </div>
                  ) : (
                    <p className="text-muted-foreground">No crypto transactions associated with this order</p>
                  )}
                </div>
              </CollapsibleContent>
            </div>
          </Collapsible>

          <div className="flex justify-between gap-4">
            <div>
              {order?.status !== "cancelled" && (
                <AlertDialog>
                  <AlertDialogTrigger asChild>
                    <Button variant="destructive" size="lg" disabled={isDiscarding}>
                      {isDiscarding ? "Deleting..." : "Delete Order"}
                    </Button>
                  </AlertDialogTrigger>
                  <AlertDialogContent>
                    <AlertDialogHeader>
                      <AlertDialogTitle>Are you sure?</AlertDialogTitle>
                      <AlertDialogDescription>
                        This action will permanently delete the order and cannot be undone.
                      </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                      <AlertDialogCancel>Cancel</AlertDialogCancel>
                      <AlertDialogAction onClick={handleDiscardOrder}>
                        Delete Order
                      </AlertDialogAction>
                    </AlertDialogFooter>
                  </AlertDialogContent>
                </AlertDialog>
              )}
            </div>
            <div className="flex gap-4">
              {(order?.status === "unpaid") && (
                <AlertDialog>
                  <AlertDialogTrigger asChild>
                    <Button
                      variant="destructive"
                      size="lg"
                      disabled={isCancelling}
                    >
                      {isCancelling ? "Cancelling..." : "Cancel Order"}
                    </Button>
                  </AlertDialogTrigger>
                  <AlertDialogContent>
                    <AlertDialogHeader>
                      <AlertDialogTitle>Cancel this order?</AlertDialogTitle>
                      <AlertDialogDescription>
                        This will mark the order as cancelled. This action cannot be undone.
                      </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                      <AlertDialogCancel>No, keep it</AlertDialogCancel>
                      <AlertDialogAction onClick={handleCancelOrder}>
                        Yes, cancel order
                      </AlertDialogAction>
                    </AlertDialogFooter>
                  </AlertDialogContent>
                </AlertDialog>
              )}
              
              {(order?.status === "unpaid" || order?.status === "paid") && (
                <Button 
                  size="lg" 
                  onClick={handleMarkAsAcknowledged}
                  disabled={isAcknowledging}
                  className="bg-purple-600 hover:bg-purple-700"
                >
                  {isAcknowledging ? "Updating..." : "Mark as Acknowledged"}
                </Button>
              )}

              {order?.status === "unpaid" && (
                <Button 
                  size="lg" 
                  onClick={handleMarkAsPaid}
                  disabled={isPaid}
                  className="bg-emerald-600 hover:bg-emerald-700"
                >
                  {isPaid ? "Order Marked as Paid" : "Mark Order as Paid"}
                </Button>
              )}
              
              {(order?.status === "paid" || order?.status === "acknowledged") && (
                <Button 
                  size="lg" 
                  onClick={handleMarkAsShipped}
                  disabled={isMarkingShipped}
                  className="bg-blue-600 hover:bg-blue-700"
                >
                  <Truck className="w-5 h-5 mr-2" />
                  {isMarkingShipped ? "Updating..." : "Mark as Shipped"}
                </Button>
              )}
            </div>
          </div>
        </div>
      </div>
    </Layout>
  );
}