'use client';

import { useState } from 'react';
import { useSelectedStoreId } from '@/lib/stores/store-context';
import { ReturnStateBadge } from '@/components/returns/return-state-badge';
import { ReturnTimeline } from '@/components/returns/return-timeline';
import {
  useApproveReturn,
  useMarkReturnReceived,
  useRejectReturn,
  useRetryReturnLabel,
  useReturn,
  useSellerCloseWithoutRefund,
} from '@/lib/queries/use-returns';
import type { OrderReturn } from '@alqove/api-client';

interface Props {
  openReturnId: string | null | undefined;
}

const SELLER_FAULT_REASONS = ['damaged', 'wrong_item', 'not_as_described'] as const;

export function SellerReturnsPanel({ openReturnId }: Props) {
  const storeId = useSelectedStoreId();
  const { data: resp, isLoading } = useReturn(openReturnId ?? null, storeId);

  if (!openReturnId) return null;
  if (isLoading || !resp) {
    return <div className="text-sm text-ink/60">Loading return…</div>;
  }

  const r = resp.data;
  const sellerFault = SELLER_FAULT_REASONS.includes(r.reason as (typeof SELLER_FAULT_REASONS)[number]);

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2">
          <span className="text-sm font-semibold text-ink/60">Status:</span>
          <ReturnStateBadge state={r.state} />
        </div>
      </div>

      <ReturnTimeline return={r} viewer="seller" />

      {r.state === 'requested' && (
        <ReturnActionBar returnId={r.id} sellerFault={sellerFault} />
      )}

      {r.state === 'approved' && r.easypost_label_error && (
        <RetryLabelBar returnId={r.id} error={r.easypost_label_error} />
      )}

      {r.state === 'approved' && !r.easypost_label_error && (
        <p
          aria-live="polite"
          className="flex items-center gap-2 text-xs text-ink/60"
        >
          <span
            aria-hidden
            className="inline-block h-3 w-3 animate-spin rounded-full border-2 border-forest/30 border-t-forest"
          />
          Issuing label…
        </p>
      )}

      {(r.state === 'awaiting_shipment' || r.state === 'in_transit') && (
        <ShippedActionBar returnId={r.id} returnData={r} />
      )}

      {(r.state === 'awaiting_shipment' || r.state === 'in_transit') && (
        <CloseWithoutRefundBar returnId={r.id} />
      )}

      {(r.state === 'closed' || r.state === 'cancelled' || r.state === 'refunded' || r.state === 'received') &&
        r.refund_amount_cents !== null && (
          <p className="text-xs text-ink/60">
            Refunded ${(r.refund_amount_cents / 100).toFixed(2)}
            {r.stripe_refund_id ? ` · ${r.stripe_refund_id.slice(-8)}` : ''}
          </p>
        )}

      {r.state === 'rejected' && r.reason_text && (
        <p className="rounded bg-bone/60 p-3 text-xs text-ink/70">
          Decline note: {r.reason_text}
        </p>
      )}
    </div>
  );
}

function ReturnActionBar({
  returnId,
  sellerFault,
}: {
  returnId: string;
  sellerFault: boolean;
}) {
  const [mode, setMode] = useState<null | 'approve' | 'reject'>(null);
  const [restockingFee, setRestockingFee] = useState('0');
  const [reasonText, setReasonText] = useState('');
  const [error, setError] = useState<string | null>(null);

  const approve = useApproveReturn();
  const reject = useRejectReturn();

  const submitApprove = async () => {
    setError(null);
    try {
      await approve.mutateAsync({
        returnId,
        restockingFeeCents: Number(restockingFee) || 0,
      });
      setMode(null);
    } catch (e) {
      setError((e as Error).message ?? 'Failed to approve.');
    }
  };

  const submitReject = async () => {
    setError(null);
    if (reasonText.trim().length < 10) {
      setError('Reason must be at least 10 characters.');
      return;
    }
    try {
      await reject.mutateAsync({ returnId, reasonText });
      setMode(null);
    } catch (e) {
      setError((e as Error).message ?? 'Failed to decline.');
    }
  };

  if (mode === 'approve') {
    return (
      <div className="space-y-2 rounded-md border border-forest/20 bg-bone/40 p-3 text-sm">
        <p className="text-ink">
          Return approved. A label is being issued — the buyer can print it from their order page.
        </p>
        {!sellerFault && (
          <label className="block">
            <span className="text-xs text-ink/60">Restocking fee (cents, optional)</span>
            <input
              type="number"
              min={0}
              value={restockingFee}
              onChange={(e) => setRestockingFee(e.target.value)}
              className="mt-1 block w-32 rounded border border-forest/20 px-2 py-1"
              data-testid="approve-restocking-fee"
            />
          </label>
        )}
        {error && <p className="text-xs text-terracotta">{error}</p>}
        <div className="flex gap-2">
          <button
            type="button"
            onClick={() => setMode(null)}
            className="rounded-md border border-forest/20 px-3 py-1 text-ink"
          >
            Cancel
          </button>
          <button
            type="button"
            onClick={submitApprove}
            disabled={approve.isPending}
            className="rounded-md bg-forest px-3 py-1 text-white disabled:opacity-60"
          >
            {approve.isPending ? 'Approving…' : 'Confirm approve'}
          </button>
        </div>
      </div>
    );
  }

  if (mode === 'reject') {
    return (
      <div className="space-y-2 rounded-md border border-forest/20 bg-bone/40 p-3 text-sm">
        <label className="block">
          <span className="text-xs text-ink/60">Reason for declining (≥10 chars)</span>
          <textarea
            value={reasonText}
            onChange={(e) => setReasonText(e.target.value)}
            rows={3}
            maxLength={2000}
            className="mt-1 block w-full rounded border border-forest/20 p-2"
          />
        </label>
        {error && <p className="text-xs text-terracotta">{error}</p>}
        <div className="flex gap-2">
          <button
            type="button"
            onClick={() => setMode(null)}
            className="rounded-md border border-forest/20 px-3 py-1 text-ink"
          >
            Cancel
          </button>
          <button
            type="button"
            onClick={submitReject}
            disabled={reject.isPending}
            className="rounded-md bg-terracotta px-3 py-1 text-white disabled:opacity-60"
          >
            {reject.isPending ? 'Declining…' : 'Confirm decline'}
          </button>
        </div>
      </div>
    );
  }

  return (
    <div className="flex gap-2">
      <button
        type="button"
        onClick={() => setMode('approve')}
        className="rounded-md bg-forest px-3 py-1.5 text-sm text-white hover:bg-forest/90"
      >
        Approve
      </button>
      <button
        type="button"
        onClick={() => setMode('reject')}
        className="rounded-md border border-forest/20 px-3 py-1.5 text-sm text-ink hover:bg-bone/40"
      >
        Decline
      </button>
    </div>
  );
}

function RetryLabelBar({ returnId, error }: { returnId: string; error: string }) {
  const [submitError, setSubmitError] = useState<string | null>(null);
  const retry = useRetryReturnLabel();

  const submit = async () => {
    setSubmitError(null);
    try {
      await retry.mutateAsync(returnId);
    } catch (e) {
      setSubmitError((e as Error).message ?? 'Failed to retry label.');
    }
  };

  return (
    <div className="space-y-2 rounded-md border border-red-200 bg-red-50 p-3 text-sm">
      <p className="font-medium text-red-800">Label issuance failed</p>
      <p className="text-xs text-red-700">{error}</p>
      {submitError && <p className="text-xs text-terracotta">{submitError}</p>}
      <button
        type="button"
        onClick={submit}
        disabled={retry.isPending}
        className="rounded-md bg-forest px-3 py-1.5 text-sm text-white hover:bg-forest/90 disabled:opacity-60"
      >
        {retry.isPending ? 'Retrying…' : 'Retry label'}
      </button>
    </div>
  );
}

function CloseWithoutRefundBar({ returnId }: { returnId: string }) {
  const [open, setOpen] = useState(false);
  const [reason, setReason] = useState('');
  const [error, setError] = useState<string | null>(null);
  const close = useSellerCloseWithoutRefund();

  const submit = async () => {
    setError(null);
    if (reason.trim().length < 10) {
      setError('Reason must be at least 10 characters.');
      return;
    }
    try {
      await close.mutateAsync({ returnId, reason: reason.trim() });
      setOpen(false);
    } catch (e) {
      setError((e as Error).message ?? 'Failed to close return.');
    }
  };

  if (!open) {
    return (
      <div>
        <button
          type="button"
          onClick={() => setOpen(true)}
          className="rounded-md border border-terracotta/40 px-3 py-1.5 text-xs text-terracotta hover:bg-terracotta/5"
        >
          Close without refund
        </button>
      </div>
    );
  }

  return (
    <div className="space-y-2 rounded-md border border-terracotta/30 bg-terracotta/5 p-3 text-sm">
      <p className="text-xs text-ink/70">
        This will not refund the buyer. If the buyer escalates, an admin can
        override.
      </p>
      <label className="block">
        <span className="text-xs text-ink/60">Reason (≥10 chars)</span>
        <textarea
          value={reason}
          onChange={(e) => setReason(e.target.value)}
          rows={3}
          maxLength={2000}
          className="mt-1 block w-full rounded border border-forest/20 p-2"
        />
      </label>
      {error && <p className="text-xs text-terracotta">{error}</p>}
      <div className="flex gap-2">
        <button
          type="button"
          onClick={() => setOpen(false)}
          className="rounded-md border border-forest/20 px-3 py-1 text-ink"
        >
          Cancel
        </button>
        <button
          type="button"
          onClick={submit}
          disabled={close.isPending}
          className="rounded-md bg-terracotta px-3 py-1 text-white disabled:opacity-60"
        >
          {close.isPending ? 'Closing…' : 'Confirm close'}
        </button>
      </div>
    </div>
  );
}

function ShippedActionBar({
  returnId,
  returnData,
}: {
  returnId: string;
  returnData: OrderReturn;
}) {
  const [submitError, setSubmitError] = useState<string | null>(null);
  const markReceived = useMarkReturnReceived();

  const submit = async () => {
    setSubmitError(null);
    try {
      await markReceived.mutateAsync(returnId);
    } catch (e) {
      setSubmitError((e as Error).message ?? 'Failed to mark received.');
    }
  };

  return (
    <div className="space-y-2 rounded-md border border-forest/20 bg-bone/40 p-3 text-sm">
      <div className="flex flex-wrap items-center gap-3">
        <button
          type="button"
          onClick={submit}
          disabled={markReceived.isPending}
          className="rounded-md bg-forest px-3 py-1.5 text-sm text-white hover:bg-forest/90 disabled:opacity-60"
        >
          {markReceived.isPending ? 'Marking…' : 'Mark received'}
        </button>
        {returnData.shipping_label_url && (
          <a
            href={returnData.shipping_label_url}
            target="_blank"
            rel="noopener noreferrer"
            className="text-sm text-forest underline hover:text-forest/80"
          >
            Print return label
          </a>
        )}
      </div>
      {submitError && <p className="text-xs text-terracotta">{submitError}</p>}
    </div>
  );
}
