'use client';

import { useEffect, useState, useCallback, useMemo } from 'react';
import {
  SegmentedControl,
  Button,
  Input,
  Select,
  Textarea,
  Modal,
  Badge,
  StatusDot,
  MetricCard,
  toast,
  type BadgeProps,
  type StatusTone,
} from '@/components/ui/Primitives';
import {
  getRoadmapItems,
  getRoadmapStats,
  submitPublicItem,
  publicVote,
  type TrackerItem,
  type PublicRoadmapStats,
} from '@/lib/tracker-client';
import { buildExecutionPipeline, buildIssueDraft, type IssueDraft } from '@/lib/execution-pipeline';

type BadgeVariant = NonNullable<BadgeProps['variant']>;

// ── Status column config ────────────────────────────────────────────
const STATUS_COLUMNS = [
  { key: 'open', label: 'Planned', tone: 'info' as StatusTone },
  { key: 'in_progress', label: 'In Progress', tone: 'warning' as StatusTone },
  { key: 'done', label: 'Complete', tone: 'success' as StatusTone },
] as const;

const TYPE_BADGES: Record<string, { label: string; variant: BadgeVariant }> = {
  feature: { label: 'Feature', variant: 'info' },
  bug: { label: 'Bug', variant: 'danger' },
  task: { label: 'Task', variant: 'neutral' },
};

const PRIORITY_BADGES: Record<string, { label: string; variant: BadgeVariant }> = {
  critical: { label: 'Critical', variant: 'danger' },
  high: { label: 'High', variant: 'warning' },
  medium: { label: 'Medium', variant: 'neutral' },
  low: { label: 'Low', variant: 'success' },
};

export default function RoadmapPage() {
  const [items, setItems] = useState<TrackerItem[]>([]);
  const [stats, setStats] = useState<PublicRoadmapStats | null>(null);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState('');
  const [typeFilter, setTypeFilter] = useState('');
  const [view, setView] = useState<'board' | 'list'>('board');
  const [issueDraft, setIssueDraft] = useState<IssueDraft | null>(null);

  // Submit form state
  const [showSubmit, setShowSubmit] = useState(false);
  const [submitForm, setSubmitForm] = useState({
    title: '',
    description: '',
    type: 'feature',
    email: '',
    name: '',
  });
  const [submitting, setSubmitting] = useState(false);

  // Vote email (persisted in localStorage)
  const [voteEmail, setVoteEmail] = useState('');
  const [showEmailPrompt, setShowEmailPrompt] = useState(false);
  const [pendingVoteId, setPendingVoteId] = useState<string | null>(null);
  const [votedItems, setVotedItems] = useState<Set<string>>(new Set());

  useEffect(() => {
    if (typeof window !== 'undefined') {
      const saved = localStorage.getItem('roadmap_email');
      if (saved) setVoteEmail(saved);
      const voted = localStorage.getItem('roadmap_voted');
      if (voted) setVotedItems(new Set(JSON.parse(voted)));
    }
  }, []);

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const params: Record<string, string> = {
        sortBy: 'voteCount',
        sortOrder: 'desc',
        limit: '100',
      };
      if (search) params.q = search;
      if (typeFilter) params.type = typeFilter;
      const [itemsRes, statsRes] = await Promise.all([getRoadmapItems(params), getRoadmapStats()]);
      setItems(itemsRes.items);
      setStats(statsRes);
    } catch (err) {
      toast({
        type: 'error',
        title: "Couldn't load the roadmap",
        description: err instanceof Error ? err.message : undefined,
      });
    } finally {
      setLoading(false);
    }
  }, [search, typeFilter]);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

  const handleVoteClick = (itemId: string) => {
    if (!voteEmail) {
      setPendingVoteId(itemId);
      setShowEmailPrompt(true);
      return;
    }
    doVote(itemId, voteEmail);
  };

  const doVote = async (itemId: string, email: string) => {
    try {
      const res = await publicVote(itemId, email);
      setItems(prev => prev.map(i => (i.id === itemId ? { ...i, voteCount: res.voteCount } : i)));
      const newVoted = new Set(votedItems);
      if (res.voted) {
        newVoted.add(itemId);
      } else {
        newVoted.delete(itemId);
      }
      setVotedItems(newVoted);
      localStorage.setItem('roadmap_voted', JSON.stringify([...newVoted]));
    } catch (err) {
      toast({
        type: 'error',
        title: 'Vote failed',
        description: err instanceof Error ? err.message : undefined,
      });
    }
  };

  const handleEmailSubmit = () => {
    if (!voteEmail) return;
    localStorage.setItem('roadmap_email', voteEmail);
    setShowEmailPrompt(false);
    if (pendingVoteId) {
      doVote(pendingVoteId, voteEmail);
      setPendingVoteId(null);
    }
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setSubmitting(true);
    try {
      const res = await submitPublicItem(submitForm);
      toast({
        type: 'success',
        title: 'Idea submitted',
        description: `Your ${submitForm.type} request "${res.title}" has been submitted for review.`,
      });
      setShowSubmit(false);
      setSubmitForm({
        title: '',
        description: '',
        type: 'feature',
        email: submitForm.email,
        name: submitForm.name,
      });
      // Save email for voting
      if (submitForm.email) {
        setVoteEmail(submitForm.email);
        localStorage.setItem('roadmap_email', submitForm.email);
      }
      // Refresh data to show new item
      fetchData();
    } catch (err) {
      toast({
        type: 'error',
        title: 'Submission failed',
        description: err instanceof Error ? err.message : undefined,
      });
    } finally {
      setSubmitting(false);
    }
  };

  const itemsByStatus = (status: string) => items.filter(i => i.status === status);
  const executionPipeline = useMemo(() => buildExecutionPipeline(items), [items]);

  const openIssueDraft = (item: TrackerItem) => {
    setIssueDraft(buildIssueDraft(item));
  };

  return (
    <div className="min-h-screen bg-background">
      {/* Header */}
      <header className="border-b border-border bg-card/80 backdrop-blur-sm sticky top-0 z-20">
        <div className="max-w-7xl mx-auto px-4 sm:px-6 py-4 flex items-center justify-between">
          <div>
            <h1 className="text-2xl font-bold text-foreground">Product Roadmap</h1>
            <p className="text-sm text-muted-foreground mt-0.5">
              Vote on features, report bugs, and shape what we build next
            </p>
          </div>
          <div className="flex items-center gap-3">
            <Button onClick={() => setShowSubmit(true)}>+ Submit Idea</Button>
            <a
              href="/login"
              className="text-sm text-muted-foreground hover:text-foreground transition-colors"
            >
              Admin →
            </a>
          </div>
        </div>
      </header>

      <main className="max-w-7xl mx-auto px-4 sm:px-6 py-6">
        {/* Stats bar */}
        {stats && (
          <div className="grid grid-cols-2 sm:grid-cols-4 gap-4 mb-6">
            <MetricCard label="Total Items" value={stats.total} />
            <MetricCard label="Total Votes" value={stats.totalVotes} />
            <MetricCard label="In Progress" value={stats.byStatus?.in_progress || 0} />
            <MetricCard label="Completed" value={stats.byStatus?.done || 0} />
          </div>
        )}

        {!loading && items.length > 0 && (
          <section className="mb-6 rounded-2xl border border-border bg-card p-5 shadow-sm">
            <div className="flex flex-col gap-1 sm:flex-row sm:items-end sm:justify-between">
              <div>
                <h2 className="text-lg font-semibold text-foreground">Execution pipeline</h2>
                <p className="text-sm text-muted-foreground">
                  Promote the strongest roadmap signal into implementation work.
                </p>
              </div>
              <div className="text-xs text-muted-foreground">
                {executionPipeline.summary.ready} ready · {executionPipeline.summary.inFlight} in
                flight
              </div>
            </div>
            <div className="mt-4 grid gap-4 lg:grid-cols-2">
              <ExecutionLane
                title="Next to build"
                empty="No open public requests yet."
                items={executionPipeline.nextUp}
                onDraft={openIssueDraft}
              />
              <ExecutionLane
                title="Already moving"
                empty="No in-progress roadmap items."
                items={executionPipeline.inFlight}
                onDraft={openIssueDraft}
              />
            </div>
          </section>
        )}

        {/* Filters */}
        <div className="flex flex-col sm:flex-row gap-3 mb-6">
          <Input
            type="text"
            placeholder="Search items..."
            aria-label="Search items"
            className="flex-1"
            value={search}
            onChange={e => setSearch(e.target.value)}
          />
          <Select
            value={typeFilter}
            onChange={e => setTypeFilter(e.target.value)}
            aria-label="Filter by type"
            options={[
              { value: '', label: 'All Types' },
              { value: 'feature', label: 'Features' },
              { value: 'bug', label: 'Bugs' },
              { value: 'task', label: 'Tasks' },
            ]}
          />
          <SegmentedControl
            aria-label="Roadmap view"
            value={view}
            onValueChange={v => setView(v as 'board' | 'list')}
            options={[
              { value: 'board', label: 'Board' },
              { value: 'list', label: 'List' },
            ]}
          />
        </div>

        {loading ? (
          view === 'board' ? (
            <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
              {STATUS_COLUMNS.map(col => (
                <div key={col.key} className="space-y-3">
                  <div className="flex items-center gap-2 mb-2">
                    <StatusDot tone={col.tone} className="animate-pulse" />
                    <h2 className="h-5 w-24 bg-muted rounded animate-pulse" />
                  </div>
                  {[1, 2, 3].map(i => (
                    <div key={i} className="bg-card rounded-xl border border-border p-4">
                      <div className="flex items-start gap-3">
                        <div className="flex flex-col items-center min-w-[44px] py-1.5 px-2">
                          <div className="h-4 w-4 bg-muted rounded animate-pulse" />
                          <div className="h-4 w-6 bg-muted rounded mt-1 animate-pulse" />
                        </div>
                        <div className="flex-1 min-w-0 space-y-2">
                          <div className="h-4 w-full bg-muted rounded animate-pulse" />
                          <div className="h-3 w-3/4 bg-muted rounded animate-pulse" />
                          <div className="flex gap-2 pt-2">
                            <div className="h-5 w-12 bg-muted rounded-full animate-pulse" />
                            <div className="h-5 w-12 bg-muted rounded-full animate-pulse" />
                          </div>
                        </div>
                      </div>
                    </div>
                  ))}
                </div>
              ))}
            </div>
          ) : (
            <div className="space-y-3">
              {[1, 2, 3, 4, 5].map(i => (
                <div
                  key={i}
                  className="bg-card rounded-xl border border-border p-4 flex items-center gap-4"
                >
                  <div className="flex flex-col items-center min-w-[44px] py-1.5 px-2">
                    <div className="h-4 w-4 bg-muted rounded animate-pulse" />
                    <div className="h-4 w-6 bg-muted rounded mt-1 animate-pulse" />
                  </div>
                  <div className="flex-1 min-w-0 space-y-2">
                    <div className="h-4 w-full bg-muted rounded animate-pulse" />
                    <div className="h-3 w-1/2 bg-muted rounded animate-pulse" />
                  </div>
                  <div className="flex items-center gap-2 shrink-0">
                    <div className="h-5 w-12 bg-muted rounded-full animate-pulse" />
                    <div className="h-4 w-16 bg-muted rounded animate-pulse" />
                  </div>
                </div>
              ))}
            </div>
          )
        ) : view === 'board' ? (
          /* Board View */
          <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
            {STATUS_COLUMNS.map(col => (
              <div key={col.key} className="space-y-3">
                <div className="flex items-center gap-2 mb-2">
                  <StatusDot tone={col.tone} />
                  <h2 className="font-semibold text-foreground">{col.label}</h2>
                  <span className="text-xs text-muted-foreground ml-auto">
                    {itemsByStatus(col.key).length}
                  </span>
                </div>
                {itemsByStatus(col.key).length === 0 ? (
                  <p className="text-sm text-muted-foreground italic py-4 text-center">No items</p>
                ) : (
                  itemsByStatus(col.key).map(item => (
                    <ItemCard
                      key={item.id}
                      item={item}
                      votedItems={votedItems}
                      onVote={handleVoteClick}
                    />
                  ))
                )}
              </div>
            ))}
          </div>
        ) : (
          /* List View */
          <div className="space-y-3">
            {items.length === 0 ? (
              <p className="text-center py-10 text-muted-foreground">No items found</p>
            ) : (
              items.map(item => (
                <ItemRow
                  key={item.id}
                  item={item}
                  votedItems={votedItems}
                  onVote={handleVoteClick}
                />
              ))
            )}
          </div>
        )}
      </main>

      {/* Email prompt modal */}
      <Modal
        open={showEmailPrompt}
        onOpenChange={open => {
          if (!open) {
            setShowEmailPrompt(false);
            setPendingVoteId(null);
          }
        }}
        title="Enter your email to vote"
        description="We use your email to track your votes. One vote per item."
        size="sm"
      >
        <div className="space-y-4">
          <Input
            type="email"
            aria-label="Email"
            placeholder="you@example.com"
            value={voteEmail}
            onChange={e => setVoteEmail(e.target.value)}
            onKeyDown={e => e.key === 'Enter' && handleEmailSubmit()}
            autoFocus
          />
          <div className="flex justify-end gap-2">
            <Button
              variant="ghost"
              onClick={() => {
                setShowEmailPrompt(false);
                setPendingVoteId(null);
              }}
            >
              Cancel
            </Button>
            <Button onClick={handleEmailSubmit}>Vote</Button>
          </div>
        </div>
      </Modal>

      {/* Submit modal */}
      <Modal
        open={showSubmit}
        onOpenChange={open => {
          if (!open) setShowSubmit(false);
        }}
        title="Submit an Idea"
      >
        <form onSubmit={handleSubmit} className="space-y-3">
          <div className="grid grid-cols-2 gap-3">
            <Input
              type="text"
              aria-label="Your name"
              placeholder="Your name"
              value={submitForm.name}
              onChange={e => setSubmitForm({ ...submitForm, name: e.target.value })}
              required
            />
            <Input
              type="email"
              aria-label="Your email"
              placeholder="Your email"
              value={submitForm.email}
              onChange={e => setSubmitForm({ ...submitForm, email: e.target.value })}
              required
            />
          </div>
          <Select
            value={submitForm.type}
            onChange={e => setSubmitForm({ ...submitForm, type: e.target.value })}
            aria-label="Request type"
            options={[
              { value: 'feature', label: 'Feature Request' },
              { value: 'bug', label: 'Bug Report' },
              { value: 'task', label: 'Task' },
            ]}
          />
          <Input
            type="text"
            aria-label="Title"
            placeholder="Title — what would you like to see?"
            value={submitForm.title}
            onChange={e => setSubmitForm({ ...submitForm, title: e.target.value })}
            required
            maxLength={500}
          />
          <Textarea
            aria-label="Description"
            placeholder="Describe your idea or issue in detail (optional)"
            value={submitForm.description}
            onChange={e => setSubmitForm({ ...submitForm, description: e.target.value })}
            rows={4}
            maxLength={5000}
          />
          <div className="flex justify-end gap-2 pt-2">
            <Button type="button" variant="ghost" onClick={() => setShowSubmit(false)}>
              Cancel
            </Button>
            <Button type="submit" loading={submitting}>
              {submitting ? 'Submitting...' : 'Submit'}
            </Button>
          </div>
        </form>
      </Modal>

      <Modal
        open={!!issueDraft}
        onOpenChange={open => {
          if (!open) setIssueDraft(null);
        }}
        title="Implementation issue draft"
        description="Copy this into Gitea/GitHub to promote roadmap signal into execution."
      >
        {issueDraft && (
          <div className="space-y-3">
            <Input aria-label="Issue title" value={issueDraft.title} readOnly />
            <Textarea aria-label="Issue body" value={issueDraft.body} readOnly rows={12} />
            <div className="flex flex-wrap gap-2">
              {issueDraft.labels.map(label => (
                <Badge key={label} variant="neutral">
                  {label}
                </Badge>
              ))}
            </div>
            <div className="flex justify-end gap-2">
              <Button variant="ghost" onClick={() => setIssueDraft(null)}>
                Close
              </Button>
              <Button
                onClick={() => {
                  void navigator.clipboard?.writeText(
                    `${issueDraft.title}\n\n${issueDraft.body}\n\nLabels: ${issueDraft.labels.join(', ')}`
                  );
                  toast({ type: 'success', title: 'Issue draft copied' });
                }}
              >
                Copy draft
              </Button>
            </div>
          </div>
        )}
      </Modal>
    </div>
  );
}

// ── Sub-components ──────────────────────────────────────────────────

const voteButtonClass = (hasVoted: boolean) =>
  `flex flex-col items-center min-w-[44px] py-1.5 px-2 rounded-lg border text-sm font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${
    hasVoted
      ? 'border-primary bg-primary/10 text-primary'
      : 'border-border bg-muted/50 text-muted-foreground hover:border-primary hover:text-primary'
  }`;

function ExecutionLane({
  title,
  empty,
  items,
  onDraft,
}: {
  title: string;
  empty: string;
  items: Array<TrackerItem & { executionScore: number; executionReason: string }>;
  onDraft: (item: TrackerItem) => void;
}) {
  return (
    <div className="space-y-2">
      <div className="text-sm font-medium text-foreground">{title}</div>
      {items.length === 0 ? (
        <p className="rounded-lg border border-dashed border-border p-4 text-sm text-muted-foreground">
          {empty}
        </p>
      ) : (
        items.map(item => (
          <div key={item.id} className="rounded-lg border border-border bg-background p-4">
            <div className="flex items-start justify-between gap-3">
              <div>
                <div className="font-medium text-foreground">{item.title}</div>
                <div className="mt-1 text-xs text-muted-foreground">{item.executionReason}</div>
              </div>
              <Badge variant={item.priority === 'critical' ? 'danger' : 'warning'}>
                {item.executionScore}
              </Badge>
            </div>
            <div className="mt-3 flex flex-wrap gap-2">
              <a
                href={`/status/${item.id}`}
                className="rounded-md border border-border px-3 py-1.5 text-xs font-medium hover:bg-muted"
              >
                Status page
              </a>
              <Button size="sm" variant="secondary" onClick={() => onDraft(item)}>
                Draft issue
              </Button>
            </div>
          </div>
        ))
      )}
    </div>
  );
}

function ItemCard({
  item,
  votedItems,
  onVote,
}: {
  item: TrackerItem;
  votedItems: Set<string>;
  onVote: (id: string) => void;
}) {
  const typeBadge = TYPE_BADGES[item.type] || TYPE_BADGES.task;
  const priorityBadge = PRIORITY_BADGES[item.priority] || PRIORITY_BADGES.medium;
  const hasVoted = votedItems.has(item.id);

  return (
    <div className="bg-card rounded-xl border border-border p-4 hover:shadow-md transition-shadow">
      <div className="flex items-start gap-3">
        <button
          onClick={() => onVote(item.id)}
          type="button"
          aria-pressed={hasVoted}
          aria-label={hasVoted ? `Remove vote from ${item.title}` : `Upvote ${item.title}`}
          className={voteButtonClass(hasVoted)}
          title={hasVoted ? 'Remove vote' : 'Upvote'}
        >
          <span className="text-xs">▲</span>
          <span>{item.voteCount}</span>
        </button>
        <div className="flex-1 min-w-0">
          <h3 className="font-medium text-foreground text-sm leading-snug">{item.title}</h3>
          {item.description && (
            <p className="text-xs text-muted-foreground mt-1 line-clamp-2">{item.description}</p>
          )}
          <div className="flex flex-wrap items-center gap-1.5 mt-2">
            <Badge variant={typeBadge.variant}>{typeBadge.label}</Badge>
            <Badge variant={priorityBadge.variant}>{priorityBadge.label}</Badge>
            {item.commentCount > 0 && (
              <span className="text-[10px] text-muted-foreground">💬 {item.commentCount}</span>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

function ItemRow({
  item,
  votedItems,
  onVote,
}: {
  item: TrackerItem;
  votedItems: Set<string>;
  onVote: (id: string) => void;
}) {
  const typeBadge = TYPE_BADGES[item.type] || TYPE_BADGES.task;
  const statusCol = STATUS_COLUMNS.find(c => c.key === item.status);
  const hasVoted = votedItems.has(item.id);

  return (
    <div className="bg-card rounded-xl border border-border p-4 flex items-center gap-4 hover:shadow-md transition-shadow">
      <button
        onClick={() => onVote(item.id)}
        type="button"
        aria-pressed={hasVoted}
        aria-label={hasVoted ? `Remove vote from ${item.title}` : `Upvote ${item.title}`}
        title={hasVoted ? 'Remove vote' : 'Upvote'}
        className={voteButtonClass(hasVoted)}
      >
        <span className="text-xs">▲</span>
        <span>{item.voteCount}</span>
      </button>
      <div className="flex-1 min-w-0">
        <h3 className="font-medium text-foreground text-sm">{item.title}</h3>
        {item.description && (
          <p className="text-xs text-muted-foreground mt-0.5 line-clamp-1">{item.description}</p>
        )}
      </div>
      <div className="flex items-center gap-2 shrink-0">
        <Badge variant={typeBadge.variant}>{typeBadge.label}</Badge>
        {statusCol && (
          <span className="flex items-center gap-1 text-xs text-muted-foreground">
            <StatusDot tone={statusCol.tone} />
            {statusCol.label}
          </span>
        )}
        {item.commentCount > 0 && (
          <span className="text-xs text-muted-foreground">💬 {item.commentCount}</span>
        )}
      </div>
    </div>
  );
}
