"use client";

import { fetchData } from '@/lib/data-service';
import { useEffect, useState } from "react";
import { useParams } from "next/navigation";
import Layout from "@/components/layout/layout";
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 } from "lucide-react";
import { useRouter } from "next/navigation";
import { toast } from "sonner";

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

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

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 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 {
      const authToken = document.cookie.split("Authorization=")[1];
      const response = await fetchData(
        `${process.env.NEXT_PUBLIC_API_URL}/orders/${orderId}`,
        {
          method: "PUT",
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${authToken}`,
          },
          body: JSON.stringify({ status: "paid" }),
        }
      );

      if (response && response.message === "Order status updated successfully") {
        setIsPaid(true); // Update isPaid state
        setOrder((prevOrder) => (prevOrder ? { ...prevOrder, status: "paid" } : null)); // Update order status
        console.log("Order marked as paid successfully.");
      } else {
        const errorData = await response.json();
        console.error("Failed to mark order as paid:", errorData.message);
        alert(`Error: ${errorData.message}`);
      }
    } catch (error: any) {
      console.error("An error occurred while marking the order as paid:", error.message);
      alert("An unexpected error occurred. Please try again.");
    }
  };

  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}`,
        {
          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);
    }
  };

  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]);

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

  return (
    <Layout>
      <div className="space-y-6">
        <div className="flex justify-between items-center">
          <h1 className="text-3xl font-bold">Order Details: {order?.orderId}</h1>
          <div className="flex items-center gap-2">
            <Badge variant={getStatusVariant(order?.status || '')}>
              {order?.status}
            </Badge>
          </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 */}
        <div className="rounded-lg border bg-card text-card-foreground shadow-sm">
          <div className="p-6">
            <h3 className="text-lg font-semibold mb-4">Crypto Transactions</h3>
            {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">{txid}</code>
                  </div>
                ))}
              </div>
            ) : (
              <p className="text-muted-foreground">No crypto transactions associated with this order</p>
            )}
          </div>
        </div>

        <div className="flex justify-end space-x-4">
          {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" && (
            <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>
    </Layout>
  );
}