import { useMemo, useState } from "react";

import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";

import { FeedbackDetailSheet } from "./components/feedback-detail-sheet";
import { FeedbackEmptyState } from "./components/feedback-empty-state";
import { FeedbackRequestRow } from "./components/feedback-request-row";
import { FeedbackTopBar } from "./components/feedback-top-bar";
import { IdeationAToolbar } from "./components/ideation-a-toolbar";
import { MOCK_CURRENT_USERS, MOCK_FEEDBACK } from "./mock-data";
import type { FeedbackCurrentUser, FeedbackItem, FeedbackRole } from "./types";

export interface FeedbackIdeationAProps {
  items?: FeedbackItem[];
  title?: string;
  /** Fires when the toolbar's "New request" button is pressed (open to every role). */
  onNewRequest?: () => void;
  /** Viewer role — drives the toolbar (filters + New request) and detail actions. */
  role?: FeedbackRole;
  /** Signed-in user — scopes the "My requests" filter. Defaults to the role's mock user. */
  currentUser?: FeedbackCurrentUser;
  /**
   * Render the built-in page top bar. Default `true` (standalone use). Pass
   * `false` when a host app supplies its own top bar — the board then fills its
   * parent (`h-full`) instead of the viewport (`h-screen`).
   */
  showTopBar?: boolean;
  /** Fires when the "Load more" button is pressed (host fetches the next page). */
  onLoadMore?: () => void;
  /** Whether more items can be loaded — shows the "Load more" button. */
  hasMore?: boolean;
  /** Whether a load-more fetch is in flight — disables the button. */
  isLoadingMore?: boolean;
  /**
   * Controlled status filter. When provided together with `onStatusChange`,
   * the component skips client-side filtering — the host is responsible for
   * passing pre-displayed `items` (e.g. from a server call).
   */
  status?: string;
  onStatusChange?: (value: string) => void;
  /** Controlled type filter (same controlled semantics as `status`). */
  type?: string;
  onTypeChange?: (value: string) => void;
  /** Controlled search query (same controlled semantics as `status`). */
  query?: string;
  onQueryChange?: (value: string) => void;
  /**
   * Fired when admin confirms approval (priority chosen). May return a promise —
   * the detail drawer stays open until it resolves and closes on success only.
   */
  onApprove?: (item: FeedbackItem, priority: string) => void | Promise<void>;
  /**
   * Fired when admin clicks Decline. May return a promise — the detail drawer
   * stays open until it resolves and closes on success only.
   */
  onDecline?: (item: FeedbackItem) => void | Promise<void>;
  /**
   * Fired when `onApprove` or `onDecline` rejects. The detail drawer stays open;
   * the host decides how to surface the failure.
   */
  onError?: (error: unknown) => void;
  /** Fired when the upvote button is toggled on a row. */
  onUpvote?: (item: FeedbackItem) => void;
}

/**
 * Ideation A — an upvote board. The toolbar (tabs + search + New request) sits on
 * one line above a list of full-width rows: upvote control on the left,
 * title/tags/details in the middle, a preview of the related screen on the right.
 */
export function FeedbackIdeationA({
  items = MOCK_FEEDBACK,
  title = "Product Ideas & Feature Requests",
  onNewRequest,
  role = "staff",
  currentUser = MOCK_CURRENT_USERS[role],
  showTopBar = true,
  onLoadMore,
  hasMore = false,
  isLoadingMore = false,
  status: statusProp,
  onStatusChange: onStatusChangeProp,
  type: typeProp,
  onTypeChange: onTypeChangeProp,
  query: queryProp,
  onQueryChange: onQueryChangeProp,
  onApprove,
  onDecline,
  onError,
  onUpvote,
}: FeedbackIdeationAProps) {
  const isControlled = onStatusChangeProp !== undefined;

  const [localStatus, setLocalStatus] = useState("all");
  const [localType, setLocalType] = useState("all");
  const [localQuery, setLocalQuery] = useState("");

  const status = isControlled ? (statusProp ?? "all") : localStatus;
  const setStatus = isControlled ? onStatusChangeProp : setLocalStatus;
  const typeFilter = isControlled ? (typeProp ?? "all") : localType;
  const setTypeFilter = isControlled ? onTypeChangeProp! : setLocalType;
  const query = isControlled ? (queryProp ?? "") : localQuery;
  const setQuery = isControlled ? onQueryChangeProp! : setLocalQuery;

  const [selected, setSelected] = useState<FeedbackItem | null>(null);
  const [sheetOpen, setSheetOpen] = useState(false);

  function openDetail(item: FeedbackItem) {
    setSelected(item);
    setSheetOpen(true);
  }

  const displayed = useMemo(() => {
    if (isControlled) {
      return [...items].sort(
        (a, b) => Number(b.type === "bug") - Number(a.type === "bug"),
      );
    }
    const q = query.trim().toLowerCase();
    return items
      .filter((item) => {
        const matchesFilter =
          status === "all"
            ? true
            : status === "my-requests"
              ? item.reporter.name === currentUser.name
              : item.status === status;
        const matchesType = typeFilter === "all" || item.type === typeFilter;
        const matchesQuery =
          q === "" ||
          item.title.toLowerCase().includes(q) ||
          item.problemStatement.toLowerCase().includes(q) ||
          item.area.toLowerCase().includes(q);
        return matchesFilter && matchesType && matchesQuery;
      })
      .sort((a, b) => Number(b.type === "bug") - Number(a.type === "bug"));
  }, [items, status, typeFilter, query, currentUser.name, isControlled]);

  return (
    <div
      className={cn(
        "flex flex-col bg-background font-sans",
        // Standalone fills the viewport; embedded fills the host's content area.
        showTopBar ? "h-screen" : "h-full",
      )}
    >
      {showTopBar && <FeedbackTopBar title={title} showAction={false} />}

      <div className="flex-1 overflow-auto">
        <div className="space-y-6 px-6 py-8">
          <IdeationAToolbar
            status={status}
            onStatusChange={setStatus}
            type={typeFilter}
            onTypeChange={setTypeFilter}
            query={query}
            onQueryChange={setQuery}
            onNewRequest={onNewRequest}
            role={role}
          />

          {displayed.length === 0 ? (
            <FeedbackEmptyState description="No ideas match your search or filter. Try a different keyword or stage." />
          ) : (
            <div className="flex flex-col gap-3">
              {displayed.map((item) => (
                <FeedbackRequestRow
                  key={item.id}
                  item={item}
                  onSelect={openDetail}
                  onUpvote={onUpvote}
                />
              ))}
            </div>
          )}

          {/* Host-driven pagination — only shown when more pages remain. */}
          {hasMore && (
            <div className="flex justify-center pt-2">
              <Button
                variant="outline"
                onClick={onLoadMore}
                disabled={isLoadingMore}
              >
                {isLoadingMore ? "Loading…" : "Load more"}
              </Button>
            </div>
          )}
        </div>
      </div>

      <FeedbackDetailSheet
        item={selected}
        open={sheetOpen}
        onOpenChange={setSheetOpen}
        role={role}
        onApprove={onApprove}
        onDecline={onDecline}
        onError={onError}
      />
    </div>
  );
}
