'use client';

import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useTranslations } from 'next-intl';
import { Bookmark, Share2, MoreHorizontal, MessageCircle, Star } from 'lucide-react';
import { vendorWishlistApi, vendorReportApi, reviewApi } from '@/lib/api';
import { useAuthStore } from '@/lib/store/auth';
import { useToast } from '@/components/ui/Toaster';
import { ConfirmationModal } from '@/components/ui/confirmation-modal';
import { ReviewCard } from '@/components/ui/review-card';
import type { VendorReview, VendorWishlistEntry } from '@/types/api';
import { cn } from '@/lib/utils';

// ─── Report reason codes ───────────────────────────────────────────────────────

const REPORT_REASON_CODES = [
  'SPAM_OR_MISLEADING',
  'OFFENSIVE_CONTENT',
  'FAKE_PROFILE',
  'INAPPROPRIATE_BEHAVIOR',
  'OTHER',
] as const;

type ReportReasonCode = (typeof REPORT_REASON_CODES)[number];

const REASON_LABELS: Record<ReportReasonCode, string> = {
  SPAM_OR_MISLEADING: 'Spam or misleading',
  OFFENSIVE_CONTENT: 'Offensive content',
  FAKE_PROFILE: 'Fake profile',
  INAPPROPRIATE_BEHAVIOR: 'Inappropriate behavior',
  OTHER: 'Other',
};

// ─── Bookmark Button ──────────────────────────────────────────────────────────

function BookmarkButton({ publicId, locale }: { publicId: string; locale: string }) {
  const t = useTranslations('vendor.actions');
  const toast = useToast();
  const status = useAuthStore((s) => s.status);
  const queryClient = useQueryClient();

  const { data: wishlist } = useQuery<VendorWishlistEntry[]>({
    queryKey: ['vendor-wishlist', locale],
    queryFn: () => vendorWishlistApi.list(locale),
    enabled: status === 'authenticated',
    staleTime: 30_000,
  });

  const isSaved = wishlist?.some((w) => w.vendor_public_id === publicId) ?? false;

  const saveMutation = useMutation({
    mutationFn: () => vendorWishlistApi.save(locale, publicId),
    onMutate: async () => {
      await queryClient.cancelQueries({ queryKey: ['vendor-wishlist', locale] });
      const prev = queryClient.getQueryData<VendorWishlistEntry[]>(['vendor-wishlist', locale]);
      queryClient.setQueryData<VendorWishlistEntry[]>(['vendor-wishlist', locale], (old) =>
        old
          ? [
              ...old,
              {
                public_id: 'optimistic',
                vendor_public_id: publicId,
                vendor_name: '',
                vendor_avatar_url: null,
                vendor_rating_avg: null,
                saved_at: new Date().toISOString(),
              },
            ]
          : [],
      );
      return { prev };
    },
    onError: (_err, _vars, ctx) => {
      queryClient.setQueryData(['vendor-wishlist', locale], ctx?.prev);
    },
    onSuccess: () => {
      toast(t('save'), 'success');
      queryClient.invalidateQueries({ queryKey: ['vendor-wishlist', locale] });
    },
  });

  const removeMutation = useMutation({
    mutationFn: () => vendorWishlistApi.remove(locale, publicId),
    onMutate: async () => {
      await queryClient.cancelQueries({ queryKey: ['vendor-wishlist', locale] });
      const prev = queryClient.getQueryData<VendorWishlistEntry[]>(['vendor-wishlist', locale]);
      queryClient.setQueryData<VendorWishlistEntry[]>(['vendor-wishlist', locale], (old) =>
        old ? old.filter((w) => w.vendor_public_id !== publicId) : [],
      );
      return { prev };
    },
    onError: (_err, _vars, ctx) => {
      queryClient.setQueryData(['vendor-wishlist', locale], ctx?.prev);
    },
    onSuccess: () => {
      toast(t('unsave'), 'success');
      queryClient.invalidateQueries({ queryKey: ['vendor-wishlist', locale] });
    },
  });

  const busy = saveMutation.isPending || removeMutation.isPending;

  const toggle = () => {
    if (busy) return;
    if (isSaved) removeMutation.mutate();
    else saveMutation.mutate();
  };

  return (
    <button
      type="button"
      onClick={toggle}
      disabled={busy}
      aria-label={isSaved ? t('unsave') : t('save')}
      aria-pressed={isSaved}
      data-testid="vendor-bookmark"
      className="flex h-9 w-9 items-center justify-center rounded-full border border-neutral-200 bg-white hover:bg-neutral-50 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-600 shadow-sm"
    >
      <Bookmark
        className={cn(
          'h-4 w-4 transition-colors',
          isSaved ? 'fill-primary-600 text-primary-600' : 'text-neutral-500',
        )}
        aria-hidden
      />
    </button>
  );
}

// ─── Share Button ─────────────────────────────────────────────────────────────

function ShareButton({ businessName }: { businessName: string }) {
  const t = useTranslations('vendor.actions');
  const toast = useToast();

  const handleShare = async () => {
    const url = window.location.href;
    if (typeof navigator.share === 'function') {
      try {
        await navigator.share({ url, title: businessName });
        return;
      } catch {
        // cancelled or not supported — fall through to clipboard
      }
    }
    try {
      await navigator.clipboard.writeText(url);
    } catch {
      // best-effort
    }
    toast(t('share_copied'), 'success');
  };

  return (
    <button
      type="button"
      onClick={handleShare}
      aria-label={t('share')}
      data-testid="vendor-share"
      className="flex h-9 w-9 items-center justify-center rounded-full border border-neutral-200 bg-white hover:bg-neutral-50 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-600 shadow-sm"
    >
      <Share2 className="h-4 w-4 text-neutral-500" aria-hidden />
    </button>
  );
}

// ─── Overflow Menu + Report Modal ─────────────────────────────────────────────

function OverflowMenu({ publicId, locale }: { publicId: string; locale: string }) {
  const t = useTranslations('vendor.actions');
  const toast = useToast();
  const [menuOpen, setMenuOpen] = useState(false);
  const [reportOpen, setReportOpen] = useState(false);
  const [reasonCode, setReasonCode] = useState<ReportReasonCode>('SPAM_OR_MISLEADING');
  const [details, setDetails] = useState('');
  const [submitting, setSubmitting] = useState(false);

  const handleReport = async () => {
    if (submitting) return;
    setSubmitting(true);
    try {
      await vendorReportApi.submit(locale, publicId, {
        reason_code: reasonCode,
        details: details.trim() || undefined,
      });
      toast(t('report_submitted'), 'success');
      setReportOpen(false);
      setDetails('');
      setReasonCode('SPAM_OR_MISLEADING');
    } catch {
      toast(t('report_submitted'), 'error');
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <>
      <div className="relative">
        <button
          type="button"
          onClick={() => setMenuOpen((v) => !v)}
          aria-label="More options"
          aria-expanded={menuOpen}
          data-testid="vendor-overflow-menu"
          className="flex h-9 w-9 items-center justify-center rounded-full border border-neutral-200 bg-white hover:bg-neutral-50 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-600 shadow-sm"
        >
          <MoreHorizontal className="h-4 w-4 text-neutral-500" aria-hidden />
        </button>

        {menuOpen && (
          <>
            <div
              className="fixed inset-0 z-10"
              aria-hidden
              onClick={() => setMenuOpen(false)}
            />
            <div className="absolute end-0 top-10 z-50 min-w-[160px] rounded-xl border border-neutral-200 bg-white py-1 shadow-lg">
              <button
                type="button"
                data-testid="vendor-report-option"
                onClick={() => {
                  setMenuOpen(false);
                  setReportOpen(true);
                }}
                className="flex w-full items-center gap-2 px-4 py-2 text-start text-sm text-red-600 hover:bg-red-50 transition-colors"
              >
                {t('report')}
              </button>
            </div>
          </>
        )}
      </div>

      <ConfirmationModal
        open={reportOpen}
        onOpenChange={setReportOpen}
        title={t('report_title')}
        description=""
        confirmLabel={submitting ? '…' : t('report')}
        onConfirm={handleReport}
        confirmVariant="danger"
      >
        <div className="space-y-3">
          <div>
            <label
              htmlFor="report-reason"
              className="mb-1 block text-xs font-medium text-neutral-700"
            >
              {t('report_reason')}
            </label>
            <select
              id="report-reason"
              value={reasonCode}
              onChange={(e) => setReasonCode(e.target.value as ReportReasonCode)}
              className="w-full rounded-lg border border-neutral-200 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary-600"
            >
              {REPORT_REASON_CODES.map((code) => (
                <option key={code} value={code}>
                  {REASON_LABELS[code]}
                </option>
              ))}
            </select>
          </div>

          <div>
            <label
              htmlFor="report-details"
              className="mb-1 block text-xs font-medium text-neutral-700"
            >
              {t('report_details')}
            </label>
            <textarea
              id="report-details"
              value={details}
              onChange={(e) => setDetails(e.target.value)}
              rows={3}
              className="w-full resize-none rounded-lg border border-neutral-200 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary-600"
            />
          </div>
        </div>
      </ConfirmationModal>
    </>
  );
}

// ─── Contact CTA ──────────────────────────────────────────────────────────────

export function VendorContactCta({
  locale,
  businessName,
  whatsappNumber,
}: {
  locale: string;
  businessName: string;
  whatsappNumber?: string | null;
}) {
  const t = useTranslations('vendor');

  if (whatsappNumber) {
    const cleaned = whatsappNumber.replace(/\D/g, '');
    return (
      <a
        href={`https://wa.me/${cleaned}`}
        target="_blank"
        rel="noopener noreferrer"
        aria-label={`${t('actions.contact')} ${businessName} on WhatsApp`}
        data-testid="vendor-contact-cta"
        className="flex items-center justify-center gap-2 rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-2.5 text-sm font-medium text-emerald-700 hover:bg-emerald-100 transition-colors"
      >
        <MessageCircle className="h-4 w-4" aria-hidden />
        {t('contact_whatsapp')}
      </a>
    );
  }

  return (
    <a
      href={`/${locale}/chat`}
      data-testid="vendor-contact-cta"
      className="flex items-center justify-center gap-2 rounded-xl border border-neutral-200 bg-white px-4 py-2.5 text-sm font-medium text-neutral-700 hover:bg-neutral-50 transition-colors"
    >
      <MessageCircle className="h-4 w-4" aria-hidden />
      {t('actions.contact')}
    </a>
  );
}

// ─── Reviews Section ──────────────────────────────────────────────────────────

export function VendorReviewsSection({
  publicId,
  locale,
  ratingAvg,
  ratingCount,
}: {
  publicId: string;
  locale: string;
  ratingAvg: number | null;
  ratingCount: number;
}) {
  const t = useTranslations('vendor');
  const [extraReviews, setExtraReviews] = useState<VendorReview[]>([]);
  const [nextCursor, setNextCursor] = useState<string | null>(null);
  const [loadingMore, setLoadingMore] = useState(false);

  const { data, isFetching } = useQuery({
    queryKey: ['vendor-reviews', publicId, locale],
    queryFn: async () => {
      const envelope = await reviewApi.vendorList(locale, publicId);
      const nc = (envelope.meta as Record<string, unknown>)?.next_cursor as string | null;
      setNextCursor(nc ?? null);
      return envelope.data;
    },
    staleTime: 60_000,
  });

  const displayedReviews = [...(data ?? []), ...extraReviews];

  const loadMore = async () => {
    if (!nextCursor || loadingMore) return;
    setLoadingMore(true);
    try {
      const envelope = await reviewApi.vendorList(locale, publicId, nextCursor);
      setExtraReviews((prev) => [...prev, ...envelope.data]);
      const nc = (envelope.meta as Record<string, unknown>)?.next_cursor as string | null;
      setNextCursor(nc ?? null);
    } finally {
      setLoadingMore(false);
    }
  };

  return (
    <section aria-labelledby="reviews-heading" className="mt-8">
      <div className="flex items-center gap-3 mb-4">
        <h2
          id="reviews-heading"
          className="font-heading text-lg font-semibold text-neutral-900 text-start"
        >
          {t('reviews.title')}
        </h2>

        {ratingAvg !== null && ratingCount > 0 && (
          <div className="flex items-center gap-1.5 text-sm text-neutral-500">
            <Star className="h-4 w-4 fill-amber-400 text-amber-400" aria-hidden />
            <span>
              {ratingAvg.toFixed(1)} {t('reviews.rating_out_of')}
            </span>
            <span>·</span>
            <span>{t('reviews_count', { count: ratingCount })}</span>
          </div>
        )}
      </div>

      {isFetching && displayedReviews.length === 0 ? (
        <div className="space-y-3">
          {[1, 2].map((i) => (
            <div key={i} className="h-24 rounded-xl bg-neutral-100 animate-pulse" />
          ))}
        </div>
      ) : displayedReviews.length === 0 ? (
        <p className="text-sm text-neutral-400 italic text-start">{t('reviews.empty')}</p>
      ) : (
        <div className="space-y-3">
          {displayedReviews.slice(0, 5 + extraReviews.length).map((review) => (
            <ReviewCard key={review.public_id} review={review} />
          ))}

          {nextCursor && (
            <button
              type="button"
              onClick={loadMore}
              disabled={loadingMore}
              className="w-full rounded-lg border border-neutral-200 bg-white py-2 text-sm font-medium text-neutral-700 hover:bg-neutral-50 transition-colors disabled:opacity-60"
            >
              {loadingMore ? '…' : t('reviews.load_more')}
            </button>
          )}
        </div>
      )}
    </section>
  );
}

// ─── Action Bar (bookmark + share + overflow …) ───────────────────────────────

export function VendorActionBar({
  publicId,
  locale,
  businessName,
}: {
  publicId: string;
  locale: string;
  businessName: string;
}) {
  return (
    <div className="flex items-center gap-1.5" data-testid="vendor-action-bar">
      <BookmarkButton publicId={publicId} locale={locale} />
      <ShareButton businessName={businessName} />
      <OverflowMenu publicId={publicId} locale={locale} />
    </div>
  );
}
