'use client';

import { useEffect, useState } from 'react';
import { useParams, useRouter } from 'next/navigation';
import { PageHeader, LoadingSpinner } from '@bytelyst/dashboard-components';
import {
  ActionMenu,
  Timeline,
  Button,
  Input,
  Textarea,
  Select,
  toast,
} from '@/components/ui/Primitives';
import { useAuth } from '@/lib/auth-context';
import {
  getItem,
  updateItem,
  updateItemStatus,
  deleteItem,
  listComments,
  addComment,
  toggleVote,
  type TrackerItem,
  type Comment,
} from '@/lib/tracker-client';

const STATUSES = ['open', 'in_progress', 'done', 'closed', 'wont_fix'] as const;
const PRIORITIES = ['critical', 'high', 'medium', 'low'] as const;
const VISIBILITIES = ['internal', 'public'] as const;

export default function ItemDetailPage() {
  const { id } = useParams<{ id: string }>();
  const router = useRouter();
  const { token } = useAuth();

  const [item, setItem] = useState<TrackerItem | null>(null);
  const [comments, setComments] = useState<Comment[]>([]);
  const [newComment, setNewComment] = useState('');
  const [error, setError] = useState('');
  const [editing, setEditing] = useState(false);
  const [editTitle, setEditTitle] = useState('');
  const [editDescription, setEditDescription] = useState('');

  useEffect(() => {
    if (!token || !id) return;
    getItem(id)
      .then(setItem)
      .catch(err => setError(err.message));
    listComments(id)
      .then(res => setComments(res.comments))
      .catch(() => {});
  }, [token, id]);

  const handleStatusChange = async (status: string) => {
    if (!id) return;
    try {
      const updated = await updateItemStatus(id, status);
      setItem(updated);
    } catch (err: unknown) {
      toast({
        type: 'error',
        title: 'Failed to update status',
        description: err instanceof Error ? err.message : undefined,
      });
    }
  };

  const handlePriorityChange = async (priority: string) => {
    if (!id) return;
    try {
      const updated = await updateItem(id, { priority } as Partial<TrackerItem>);
      setItem(updated);
    } catch (err: unknown) {
      toast({
        type: 'error',
        title: 'Failed to update priority',
        description: err instanceof Error ? err.message : undefined,
      });
    }
  };

  const handleVisibilityChange = async (visibility: string) => {
    if (!id) return;
    try {
      const updated = await updateItem(id, { visibility } as Partial<TrackerItem>);
      setItem(updated);
    } catch (err: unknown) {
      toast({
        type: 'error',
        title: 'Failed to update visibility',
        description: err instanceof Error ? err.message : undefined,
      });
    }
  };

  const handleSaveEdit = async () => {
    if (!id) return;
    try {
      const updated = await updateItem(id, {
        title: editTitle,
        description: editDescription,
      } as Partial<TrackerItem>);
      setItem(updated);
      setEditing(false);
      toast({ type: 'success', title: 'Item updated' });
    } catch (err: unknown) {
      toast({
        type: 'error',
        title: 'Failed to update',
        description: err instanceof Error ? err.message : undefined,
      });
    }
  };

  const handleAddComment = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!id || !newComment.trim()) return;
    try {
      const comment = await addComment(id, newComment);
      setComments(prev => [...prev, comment]);
      setNewComment('');
    } catch (err: unknown) {
      toast({
        type: 'error',
        title: 'Failed to add comment',
        description: err instanceof Error ? err.message : undefined,
      });
    }
  };

  const handleVote = async () => {
    if (!id) return;
    try {
      const res = await toggleVote(id);
      setItem(prev => (prev ? { ...prev, voteCount: res.voteCount } : prev));
    } catch (err: unknown) {
      toast({
        type: 'error',
        title: 'Failed to vote',
        description: err instanceof Error ? err.message : undefined,
      });
    }
  };

  const handleDelete = async () => {
    if (!id) return;
    if (!confirm('Delete this item? This cannot be undone.')) return;
    try {
      await deleteItem(id);
      toast({ type: 'success', title: 'Item deleted' });
      router.push('/dashboard/items');
    } catch (err: unknown) {
      toast({
        type: 'error',
        title: 'Failed to delete',
        description: err instanceof Error ? err.message : undefined,
      });
    }
  };

  const startEdit = () => {
    if (!item) return;
    setEditTitle(item.title);
    setEditDescription(item.description);
    setEditing(true);
  };

  if (!item) {
    return (
      <div className="mx-auto flex min-h-[400px] max-w-3xl items-center justify-center">
        {error ? <p className="text-sm text-destructive">{error}</p> : <LoadingSpinner />}
      </div>
    );
  }

  return (
    <div className="mx-auto max-w-3xl space-y-6">
      <PageHeader
        title={item.title}
        breadcrumbs={[
          { label: 'Dashboard', href: '/dashboard' },
          { label: 'Items', href: '/dashboard/items' },
        ]}
        actions={
          editing ? undefined : (
            <ActionMenu
              label="Item actions"
              items={[
                { id: 'edit', label: 'Edit', onSelect: startEdit },
                { id: 'delete', label: 'Delete', destructive: true, onSelect: handleDelete },
              ]}
            />
          )
        }
      />

      {/* Title/description editor */}
      <div className="space-y-2">
        {editing ? (
          <div className="space-y-3">
            <Input
              type="text"
              aria-label="Title"
              value={editTitle}
              onChange={e => setEditTitle(e.target.value)}
              className="text-lg font-bold"
            />
            <Textarea
              aria-label="Description"
              value={editDescription}
              onChange={e => setEditDescription(e.target.value)}
              rows={6}
            />
            <div className="flex gap-2">
              <Button size="sm" onClick={handleSaveEdit}>
                Save
              </Button>
              <Button size="sm" variant="ghost" onClick={() => setEditing(false)}>
                Cancel
              </Button>
            </div>
          </div>
        ) : (
          item.description && (
            <p className="whitespace-pre-wrap text-sm text-muted-foreground">{item.description}</p>
          )
        )}
      </div>

      {/* Meta */}
      <div className="grid grid-cols-2 gap-4 rounded-xl border border-border bg-card p-4 md:grid-cols-5">
        <div>
          <div className="text-xs font-medium text-muted-foreground">Type</div>
          <div className="mt-1 text-sm font-medium capitalize">{item.type}</div>
        </div>
        <div>
          <div className="text-xs font-medium text-muted-foreground">Status</div>
          <Select
            aria-label="Status"
            controlSize="sm"
            className="mt-1"
            value={item.status}
            onChange={e => handleStatusChange(e.target.value)}
            options={STATUSES.map(s => ({ value: s, label: s.replace(/_/g, ' ') }))}
          />
        </div>
        <div>
          <div className="text-xs font-medium text-muted-foreground">Priority</div>
          <Select
            aria-label="Priority"
            controlSize="sm"
            className="mt-1"
            value={item.priority}
            onChange={e => handlePriorityChange(e.target.value)}
            options={PRIORITIES.map(p => ({ value: p, label: p }))}
          />
        </div>
        <div>
          <div className="text-xs font-medium text-muted-foreground">Visibility</div>
          <Select
            aria-label="Visibility"
            controlSize="sm"
            className="mt-1"
            value={item.visibility || 'internal'}
            onChange={e => handleVisibilityChange(e.target.value)}
            options={VISIBILITIES.map(v => ({
              value: v,
              label: v === 'public' ? '🌐 Public' : '🔒 Internal',
            }))}
          />
        </div>
        <div>
          <div className="text-xs font-medium text-muted-foreground">Votes</div>
          <Button variant="outline" size="sm" className="mt-1" onClick={handleVote}>
            ▲ {item.voteCount}
          </Button>
        </div>
      </div>

      {/* Labels & meta */}
      <div className="flex flex-wrap gap-4 text-xs text-muted-foreground">
        {item.labels.length > 0 && (
          <div className="flex gap-1">
            {item.labels.map(l => (
              <span key={l} className="rounded-full bg-muted px-2 py-0.5">
                {l}
              </span>
            ))}
          </div>
        )}
        <span>Created: {new Date(item.createdAt).toLocaleDateString()}</span>
        {item.assignee && <span>Assigned: {item.assignee}</span>}
        {item.targetRelease && <span>Release: {item.targetRelease}</span>}
      </div>

      {/* Comments */}
      <div className="space-y-4">
        <h2 className="text-lg font-semibold">Comments ({comments.length})</h2>

        <Timeline
          emptyLabel="No comments yet."
          items={comments.map(c => ({
            id: c.id,
            title: c.authorEmail || c.authorId,
            meta: new Date(c.createdAt).toLocaleString(),
            description: <span className="whitespace-pre-wrap">{c.body}</span>,
          }))}
        />

        <form onSubmit={handleAddComment} className="space-y-2">
          <Textarea
            aria-label="Add a comment"
            value={newComment}
            onChange={e => setNewComment(e.target.value)}
            placeholder="Add a comment..."
            rows={3}
          />
          <Button type="submit" disabled={!newComment.trim()}>
            Comment
          </Button>
        </form>
      </div>
    </div>
  );
}
