'use client';

import { use, useMemo, useState } from 'react';
import Link from 'next/link';
import { usePurchase } from '@/lib/queries/use-purchases';
import { useOrderCancel } from '@/lib/queries/use-order-cancel';
import { MessageThread } from '@/components/messaging/message-thread';
import { useMyThreads } from '@/lib/queries/use-my-threads';
import { ReturnRequestModal } from '@/components/returns/return-request-modal';
import { ReturnStateBadge } from '@/components/returns/return-state-badge';
import { ReturnTimeline } from '@/components/returns/return-timeline';
import { EscalateReturnButton } from '@/components/returns/escalate-return-button';
import { useReturn } from '@/lib/queries/use-returns';
import { useMyReviews } from '@/lib/queries/use-reviews';
import { ReviewModal } from '@/components/reviews/review-modal';
import type { OrderDetail, OrderItemData, Review } from '@alqove/api-client';

const REVIEW_EDIT_WINDOW_MS = 30 * 24 * 60 * 60 * 1000;

function withinReviewEditWindow(createdAt: string): boolean {
  const t = new Date(createdAt).getTime();
  if (Number.isNaN(t)) return false;
  return Date.now() - t < REVIEW_EDIT_WINDOW_MS;
}

function formatPrice(cents: number): string {
  return `$${(cents / 100).toFixed(2)}`;
}

const CANCELLATION_COPY: Record<string, string> = {
  buyer_requested: 'You cancelled this order. Refund processed.',
  sold_locally: 'The store marked this item as unavailable. Full refund processed.',
  item_damaged: 'The store could not fulfill this order. Full refund processed.',
  ship_deadline_exceeded: "This order was automatically cancelled because it wasn't shipped in time. Full refund processed.",
  other: 'This order was cancelled by the store. Full refund processed.',
};

export function PurchaseDetailClient({ params }: { params: Promise<{ id: string }> }) {
  const { id } = use(params);
  const { data: response, isLoading } = usePurchase(id);
  const purchase = response?.data;
  const { data: reviewsResp } = useMyReviews();
  const reviewsByOrderItem = useMemo(() => {
    const map = new Map<string, Review>();
    for (const r of reviewsResp?.data ?? []) {
      map.set(r.order_item_id, r);
    }
    return map;
  }, [reviewsResp]);

  if (isLoading) {
    return (
      <div className="mx-auto max-w-3xl px-4 py-8">
        <div className="animate-pulse space-y-4">
          <div className="h-8 w-48 rounded bg-slate-200" />
          <div className="h-64 rounded bg-slate-200" />
        </div>
      </div>
    );
  }

  if (!purchase) {
    return (
      <div className="mx-auto max-w-3xl px-4 py-16 text-center">
        <h1 className="text-2xl font-bold text-slate-900">Purchase not found</h1>
        <Link href="/purchases" className="mt-4 inline-block text-sm font-medium text-forest-600">
          &larr; Back to purchases
        </Link>
      </div>
    );
  }

  return (
    <div className="mx-auto max-w-3xl px-4 py-8">
      <Link href="/purchases" className="text-sm text-forest-600 hover:text-forest-700 mb-4 inline-block">
        &larr; Back to purchases
      </Link>

      <h1 className="text-2xl font-bold text-slate-900 mb-6">Purchase Details</h1>

      {purchase.is_delayed && (
        <div className="mb-4 rounded-md bg-amber-50 border border-amber-200 p-3 text-sm">
          <p className="font-medium text-amber-900">One or more orders in this purchase are delayed.</p>
          <p className="text-amber-800 mt-1">The store hasn&apos;t shipped yet. You can cancel for a full refund.</p>
        </div>
      )}

      <div className="bg-white rounded-lg border border-slate-200 p-5 mb-6">
        <div className="grid grid-cols-2 gap-4 text-sm">
          <div><span className="text-slate-500">Subtotal</span><div className="font-semibold">{formatPrice(purchase.subtotal)}</div></div>
          <div><span className="text-slate-500">Shipping</span><div className="font-semibold">{formatPrice(purchase.shipping_total)}</div></div>
          <div><span className="text-slate-500">Discount</span><div className="font-semibold">{formatPrice(purchase.discount_total)}</div></div>
          <div><span className="text-slate-500">Total</span><div className="font-bold text-lg">{formatPrice(purchase.total)}</div></div>
        </div>
      </div>

      {purchase.shipping_address && (
        <div className="bg-white rounded-lg border border-slate-200 p-5 mb-6">
          <h2 className="font-semibold text-sm mb-2">Shipping Address</h2>
          <div className="text-sm text-slate-600">
            <div>{purchase.shipping_address.first_name} {purchase.shipping_address.last_name}</div>
            <div>{purchase.shipping_address.street}</div>
            <div>{purchase.shipping_address.city}, {purchase.shipping_address.state} {purchase.shipping_address.zip}</div>
          </div>
        </div>
      )}

      <h2 className="font-bold text-lg mb-3">Orders</h2>
      <div className="space-y-4">
        {purchase.orders.map((order: OrderDetail) => (
          <OrderCard
            key={order.id}
            order={order}
            purchaseId={purchase.id}
            buyerUserId={purchase.buyer_id}
            reviewsByOrderItem={reviewsByOrderItem}
          />
        ))}
      </div>
    </div>
  );
}

function OrderCard({
  order,
  purchaseId,
  buyerUserId,
  reviewsByOrderItem,
}: {
  order: OrderDetail;
  purchaseId: string;
  buyerUserId: string;
  reviewsByOrderItem: Map<string, Review>;
}) {
  const [showMessages, setShowMessages] = useState(false);
  const { data: threadsResp } = useMyThreads();
  const unread =
    threadsResp?.data.find((t) => t.order_id === order.id)?.unread_count ?? 0;
  return (
    <div className="bg-white rounded-lg border border-slate-200 p-5">
      <div className="flex items-center justify-between mb-3">
        <div className="flex items-center gap-2">
          <div className="h-6 w-6 rounded-full bg-forest-600 flex items-center justify-center text-[10px] font-semibold text-white">
            {order.store.name.charAt(0)}
          </div>
          <span className="font-semibold text-sm">{order.store.name}</span>
        </div>
        <span className="text-xs text-slate-400">{order.status}</span>
      </div>

      <OrderTimeline status={order.status} shippedAt={order.shipped_at} deliveredAt={order.delivered_at} />

      {order.tracking_url && order.carrier && order.tracking_number && (
        <a
          href={order.tracking_url}
          target="_blank"
          rel="noreferrer"
          className="mt-3 inline-block text-sm text-forest-600 hover:text-forest-700 underline"
        >
          Track with {order.carrier}: {order.tracking_number}
        </a>
      )}

      {order.is_delayed && (
        <div className="mt-3 rounded-md bg-amber-50 border border-amber-200 p-3 text-sm">
          <p className="font-medium text-amber-900">Your order is delayed.</p>
          <p className="text-amber-800 mt-1">The store hasn&apos;t shipped yet. Cancel for a full refund.</p>
        </div>
      )}

      {order.status === 'cancelled' && order.cancellation_reason && (
        <>
          {order.refund_status === 'pending_reconciliation' ? (
            // Bug L — don't claim "full refund processed" when Stripe failed.
            <p className="mt-3 rounded bg-amber-50 p-3 text-sm text-amber-800">
              <strong>Order cancelled.</strong> The refund couldn&apos;t be processed
              automatically — our team is reconciling it now. You&apos;ll see the
              refund on your statement within 1–2 business days.
            </p>
          ) : (
            <p className="mt-3 text-sm text-slate-500">
              {CANCELLATION_COPY[order.cancellation_reason] ?? 'Order cancelled. Full refund processed.'}
            </p>
          )}
        </>
      )}

      {(order.status === 'pending' || order.status === 'processing') && (
        <div className="mt-3">
          <CancelOrderButton orderId={order.id} purchaseId={purchaseId} delayed={!!order.is_delayed} />
        </div>
      )}

      <ReturnSection order={order} />

      <details
        className="mt-4 border-t border-slate-100 pt-4"
        open={showMessages}
        onToggle={(e) => setShowMessages((e.target as HTMLDetailsElement).open)}
      >
        <summary className="cursor-pointer select-none text-sm font-medium text-slate-700">
          Messages with {order.store.name}
          {unread > 0 && (
            <span className="ml-2 rounded-full bg-forest-600 px-2 py-0.5 text-xs text-white">
              {unread} new
            </span>
          )}
        </summary>
        {showMessages && (
          <div className="mt-3">
            <MessageThread
              orderId={order.id}
              counterpartyName={order.store.name}
              viewerRole="buyer"
              viewerUserId={buyerUserId}
            />
          </div>
        )}
      </details>

      <div className="space-y-2 mt-4">
        {order.items.map((item: OrderItemData) => {
          const existingReview = reviewsByOrderItem.get(item.id);
          return (
            <div key={item.id} className="flex items-center gap-3">
              {item.image_url_snapshot && (
                <img
                  src={item.image_url_snapshot}
                  alt={item.title_snapshot}
                  className="h-10 w-10 rounded object-cover"
                />
              )}
              <div className="flex-1 text-sm">
                <div className="font-medium">{item.title_snapshot}</div>
                <div className="text-slate-400">{formatPrice(item.price_snapshot)}</div>
              </div>
              {order.status === 'delivered' && (
                <ReviewCta
                  orderItem={item}
                  storeName={order.store.name}
                  existing={existingReview ?? null}
                />
              )}
            </div>
          );
        })}
      </div>

      <div className="border-t border-slate-100 mt-3 pt-3 flex justify-between text-sm">
        <span className="text-slate-500">Shipping: {formatPrice(order.shipping_cost)}</span>
        <span className="font-semibold">Subtotal: {formatPrice(order.subtotal)}</span>
      </div>
    </div>
  );
}

function ReturnSection({ order }: { order: OrderDetail }) {
  const [modalOpen, setModalOpen] = useState(false);
  const [showDetails, setShowDetails] = useState(false);
  const { data: returnResp } = useReturn(order.open_return_id ?? null);

  const inWindow =
    !!order.delivered_at &&
    !!order.returns_open_until &&
    new Date() <= new Date(order.returns_open_until);

  if (order.open_return_id && returnResp?.data) {
    const r = returnResp.data;
    const showShippingControls =
      r.state === 'awaiting_shipment' || r.state === 'in_transit';
    return (
      <div className="mt-3 rounded-md border border-slate-200 bg-slate-50 p-3 text-sm">
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-2">
            <span className="font-medium text-slate-700">Return:</span>
            <ReturnStateBadge state={r.state} />
          </div>
          <button
            type="button"
            onClick={() => setShowDetails((s) => !s)}
            className="text-forest-600 hover:text-forest-700"
          >
            {showDetails ? 'Hide' : 'View details'}
          </button>
        </div>
        {showShippingControls && (
          <div className="mt-3 flex flex-wrap items-center gap-3 text-sm">
            {r.tracking_number && (
              <span>
                {r.tracking_url ? (
                  <a
                    href={r.tracking_url}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="text-forest-700 hover:text-forest-800 underline"
                  >
                    {r.carrier ?? 'Carrier'} {r.tracking_number}
                  </a>
                ) : (
                  <span className="text-slate-700">
                    {r.carrier ?? 'Carrier'} {r.tracking_number}
                  </span>
                )}
              </span>
            )}
            {r.shipping_label_url && (
              <a
                href={r.shipping_label_url}
                target="_blank"
                rel="noopener noreferrer"
                className="font-medium text-forest-700 hover:text-forest-800 underline"
              >
                Download return label
              </a>
            )}
          </div>
        )}
        {showDetails && (
          <div className="mt-3 border-t border-slate-200 pt-3">
            <ReturnTimeline return={r} viewer="buyer" />
            {r.refund_amount_cents !== null && (
              <p className="mt-3 text-xs text-slate-500">
                Refunded ${(r.refund_amount_cents / 100).toFixed(2)}
                {r.stripe_refund_id ? ` · ${r.stripe_refund_id.slice(-8)}` : ''}
              </p>
            )}
          </div>
        )}
        <div className="mt-3">
          <EscalateReturnButton return={r} />
        </div>
      </div>
    );
  }

  if (!inWindow) return null;

  return (
    <>
      <div className="mt-3">
        <button
          type="button"
          onClick={() => setModalOpen(true)}
          className="rounded-md border border-slate-300 px-3 py-1.5 text-sm text-slate-700 hover:bg-slate-50"
        >
          Request return
        </button>
      </div>
      <ReturnRequestModal
        orderId={order.id}
        items={order.items}
        open={modalOpen}
        onClose={() => setModalOpen(false)}
      />
    </>
  );
}

function OrderTimeline({ status, shippedAt, deliveredAt }: { status: string; shippedAt?: string | null; deliveredAt?: string | null }) {
  const steps = [
    { label: 'Placed', done: true, timestamp: null as string | null },
    { label: 'Shipped', done: !!shippedAt || status === 'shipped' || status === 'delivered', timestamp: shippedAt ?? null },
    { label: 'Delivered', done: !!deliveredAt, timestamp: deliveredAt ?? null },
  ];
  return (
    <ol className="flex items-center gap-4">
      {steps.map((s) => (
        <li key={s.label} className="flex items-center gap-2 text-sm">
          <span className={`inline-block h-2 w-2 rounded-full ${s.done ? 'bg-forest-600' : 'bg-slate-300'}`} />
          <span className={s.done ? 'text-slate-900' : 'text-slate-500'}>
            {s.label}
            {s.timestamp ? ` · ${new Date(s.timestamp).toLocaleDateString()}` : ''}
          </span>
        </li>
      ))}
    </ol>
  );
}

function CancelOrderButton({ orderId, purchaseId, delayed }: { orderId: string; purchaseId: string; delayed: boolean }) {
  const [confirming, setConfirming] = useState(false);
  const { mutate, isPending, error } = useOrderCancel(purchaseId);

  // Note: success-with-Stripe-warning is rendered by OrderCard from the
  // persisted `refund_status` field, not from mutation state — this component
  // unmounts the moment the order's status flips to 'cancelled'.
  const errMsg = (error as { message?: string } | null)?.message ?? null;

  if (!confirming) {
    return (
      <button
        type="button"
        onClick={() => setConfirming(true)}
        className={`text-sm rounded-md px-3 py-1.5 ${
          delayed
            ? 'bg-amber-600 text-white hover:bg-amber-700'
            : 'border border-slate-300 text-slate-700 hover:bg-slate-50'
        }`}
      >
        {delayed ? 'Cancel for full refund' : 'Cancel order'}
      </button>
    );
  }

  return (
    <div className="rounded-md border border-slate-200 bg-slate-50 p-3 text-sm">
      <p className="text-slate-700 mb-2">
        Cancel this order? You&apos;ll receive a full refund for this store&apos;s items and shipping.
      </p>
      {errMsg && (
        <p className="mb-2 rounded bg-red-50 p-2 text-xs text-red-700">
          {errMsg}
        </p>
      )}
      <div className="flex gap-2">
        <button
          type="button"
          onClick={() => setConfirming(false)}
          className="rounded-md border border-slate-300 px-3 py-1 text-slate-700 hover:bg-white"
        >
          Keep order
        </button>
        <button
          type="button"
          disabled={isPending}
          onClick={() => mutate(orderId, { onSuccess: () => setConfirming(false) })}
          className="rounded-md bg-amber-600 px-3 py-1 text-white hover:bg-amber-700 disabled:opacity-60"
        >
          {isPending ? 'Cancelling…' : 'Confirm cancel'}
        </button>
      </div>
    </div>
  );
}

function ReviewCta({
  orderItem,
  storeName,
  existing,
}: {
  orderItem: OrderItemData;
  storeName: string;
  existing: Review | null;
}) {
  const [open, setOpen] = useState(false);

  if (!existing) {
    return (
      <>
        <button
          type="button"
          onClick={() => setOpen(true)}
          data-testid={`review-cta-leave-${orderItem.id}`}
          className="rounded-md border border-slate-300 px-3 py-1.5 text-xs font-medium text-slate-700 hover:bg-slate-50"
        >
          Leave a review
        </button>
        {open && (
          <ReviewModal
            orderItem={{
              id: orderItem.id,
              title_snapshot: orderItem.title_snapshot,
              image_url_snapshot: orderItem.image_url_snapshot,
            }}
            storeName={storeName}
            mode="create"
            onClose={() => setOpen(false)}
          />
        )}
      </>
    );
  }

  if (withinReviewEditWindow(existing.created_at)) {
    return (
      <>
        <button
          type="button"
          onClick={() => setOpen(true)}
          data-testid={`review-cta-edit-${orderItem.id}`}
          className="rounded-md border border-slate-300 px-3 py-1.5 text-xs font-medium text-slate-700 hover:bg-slate-50"
        >
          Edit your review
        </button>
        {open && (
          <ReviewModal
            orderItem={{
              id: orderItem.id,
              title_snapshot: orderItem.title_snapshot,
              image_url_snapshot: orderItem.image_url_snapshot,
            }}
            storeName={storeName}
            mode="edit"
            initial={existing}
            onClose={() => setOpen(false)}
          />
        )}
      </>
    );
  }

  return (
    <span
      data-testid={`review-cta-locked-${orderItem.id}`}
      className="text-xs text-slate-400"
    >
      Reviewed
    </span>
  );
}
