'use client';

import { useState, useEffect, useCallback, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { BrowserRuntime } from '@cockpit/effect-runtime';
import { Effect } from 'effect';
import {
  loadReviews,
  updateReview,
  deleteReview,
  reorderReviews,
} from './effect/reviewClient';

interface ReviewSummary {
  id: string;
  title: string;
  active: boolean;
  createdAt: number;
  commentCount: number;
  sourceFile?: string;
}

interface ReviewListPanelProps {
  currentReviewId: string;
  onSelect: (reviewId: string) => void;
  readOnly?: boolean;
  /** Trigger list refresh on change (e.g. comment count changes) */
  refreshTrigger?: number;
  /** View comments */
  onViewComments?: (reviewId: string) => void;
}

export function ReviewListPanel({ currentReviewId, onSelect, readOnly, refreshTrigger, onViewComments }: ReviewListPanelProps) {
  const { t } = useTranslation();
  const [reviews, setReviews] = useState<ReviewSummary[]>([]);
  const [deleting, setDeleting] = useState<string | null>(null);
  const [toggling, setToggling] = useState<string | null>(null);
  const [collapsed, setCollapsed] = useState(false);

  // Tooltip state
  const [tooltip, setTooltip] = useState<{ id: string; text: string; top: number; left: number } | null>(null);

  // Drag state
  const dragId = useRef<string | null>(null);
  const [dropTarget, setDropTarget] = useState<string | null>(null);

  const fetchList = useCallback(async () => {
    const exit = await BrowserRuntime.runPromiseExit(loadReviews());
    if (exit._tag === 'Success') {
      setReviews(((exit.value.reviews ?? []) as unknown) as ReviewSummary[]);
    }
    // silent — v1 try/catch ignored errors
  }, []);

  useEffect(() => {
    queueMicrotask(() => fetchList());
  }, [fetchList]);

  // Refresh list when switching review or comment count changes
  useEffect(() => {
    queueMicrotask(() => fetchList());
  }, [currentReviewId, refreshTrigger, fetchList]);

  const handleToggleActive = useCallback(async (e: React.MouseEvent, id: string, currentActive: boolean) => {
    e.stopPropagation();
    if (toggling) return;
    setToggling(id);
    const exit = await BrowserRuntime.runPromiseExit(
      updateReview(id, { active: !currentActive })
    );
    if (exit._tag === 'Success') {
      setReviews(prev => prev.map(r => r.id === id ? { ...r, active: !currentActive } : r));
    }
    setToggling(null);
  }, [toggling]);

  const handleDelete = useCallback(async (e: React.MouseEvent, id: string) => {
    e.stopPropagation();
    if (deleting) return;
    setDeleting(id);
    const exit = await BrowserRuntime.runPromiseExit(deleteReview(id));
    if (exit._tag === 'Success') {
      setReviews(prev => prev.filter(r => r.id !== id));
      // If the current one was deleted, switch to the first in the list
      if (id === currentReviewId) {
        const remaining = reviews.filter(r => r.id !== id);
        if (remaining.length > 0) {
          onSelect(remaining[0].id);
        }
      }
    }
    setDeleting(null);
  }, [deleting, currentReviewId, reviews, onSelect]);

  // Drag & drop handlers (admin only)
  const handleDragStart = useCallback((e: React.DragEvent, id: string) => {
    dragId.current = id;
    e.dataTransfer.effectAllowed = 'move';
    const el = e.currentTarget as HTMLElement;
    requestAnimationFrame(() => el.classList.add('opacity-30'));
  }, []);

  const handleDragEnd = useCallback((e: React.DragEvent) => {
    dragId.current = null;
    setDropTarget(null);
    if (e.currentTarget instanceof HTMLElement) {
      e.currentTarget.classList.remove('opacity-30');
    }
  }, []);

  const handleDragOver = useCallback((e: React.DragEvent, id: string) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';
    if (dragId.current && dragId.current !== id) {
      setDropTarget(id);
    }
  }, []);

  const handleDrop = useCallback(async (e: React.DragEvent, targetId: string) => {
    e.preventDefault();
    setDropTarget(null);
    const sourceId = dragId.current;
    dragId.current = null;
    if (!sourceId || sourceId === targetId) return;

    // Reorder locally
    setReviews(prev => {
      const list = [...prev];
      const fromIdx = list.findIndex(r => r.id === sourceId);
      const toIdx = list.findIndex(r => r.id === targetId);
      if (fromIdx === -1 || toIdx === -1) return prev;
      const [item] = list.splice(fromIdx, 1);
      list.splice(toIdx, 0, item);

      // Persist asynchronously (fire-and-forget)
      const order = list.map(r => r.id);
      BrowserRuntime.runFork(
        reorderReviews(order).pipe(Effect.orElse(() => Effect.void))
      );

      return list;
    });
  }, []);

  const displayReviews = readOnly ? reviews.filter(r => r.active) : reviews;
  const canDrag = !readOnly;

  // Collapsed state
  if (collapsed) {
    return (
      <div className="h-full flex flex-col items-center bg-secondary/50 w-9 flex-shrink-0 border-r border-border">
        <button
          onClick={() => setCollapsed(false)}
          className="p-1.5 mt-2 text-muted-foreground hover:text-foreground hover:bg-accent rounded transition-colors"
          title={t('review.expandList')}
        >
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <polyline points="9 18 15 12 9 6" />
          </svg>
        </button>
        <span className="text-[10px] text-muted-foreground/50 mt-2" style={{ writingMode: 'vertical-rl' }}>
          {readOnly ? t('review.nDocs', { count: displayReviews.length }) : t('review.nReviews', { count: displayReviews.length })}
        </span>
      </div>
    );
  }

  return (
    <div className="h-full flex flex-col bg-secondary/50 w-[200px] flex-shrink-0 border-r border-border">
      <div className="px-3 py-2 border-b border-border flex-shrink-0 flex items-center justify-between">
        <div>
          <span className="text-xs font-medium text-muted-foreground">{readOnly ? t('review.docList') : t('review.allReviewsList')}</span>
          <span className="text-xs text-muted-foreground/60 ml-1.5">{displayReviews.length}</span>
        </div>
        <button
          onClick={() => setCollapsed(true)}
          className="p-0.5 text-muted-foreground hover:text-foreground hover:bg-accent rounded transition-colors"
          title={t('review.collapseList')}
        >
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <polyline points="15 18 9 12 15 6" />
          </svg>
        </button>
      </div>
      <div className="flex-1 overflow-y-auto">
        {displayReviews.map((r) => (
          <div
            key={r.id}
            draggable={canDrag}
            onDragStart={canDrag ? (e) => handleDragStart(e, r.id) : undefined}
            onDragEnd={canDrag ? handleDragEnd : undefined}
            onDragOver={canDrag ? (e) => handleDragOver(e, r.id) : undefined}
            onDrop={canDrag ? (e) => handleDrop(e, r.id) : undefined}
            onMouseEnter={(e) => {
              const rect = e.currentTarget.getBoundingClientRect();
              setTooltip({ id: r.id, text: r.title, top: rect.top + rect.height / 2, left: rect.right });
            }}
            onMouseLeave={() => setTooltip(prev => prev?.id === r.id ? null : prev)}
            onClick={() => onSelect(r.id)}
            className={`group px-3 py-2 cursor-pointer border-b transition-colors ${
              dropTarget === r.id
                ? 'border-b-brand border-t border-t-transparent'
                : 'border-b-border/50'
            } ${
              r.id === currentReviewId
                ? 'bg-accent/60'
                : 'hover:bg-accent/30'
            }`}
          >
            <div className="flex items-center gap-1.5 min-w-0">
              {/* Status dot */}
              {!readOnly && (
                <span className={`w-1.5 h-1.5 rounded-full flex-shrink-0 ${
                  r.active ? 'bg-green-500' : 'bg-muted-foreground/40'
                }`} />
              )}
              {/* Title */}
              <span className="text-xs truncate flex-1">{r.title}</span>
              {/* View comments button */}
              {r.commentCount > 0 && onViewComments && (
                <button
                  onClick={(e) => {
                    e.stopPropagation();
                    onViewComments(r.id);
                  }}
                  className="flex-shrink-0 p-0.5 rounded text-muted-foreground/0 group-hover:text-muted-foreground/60 hover:!text-brand hover:!bg-brand/10 transition-colors"
                  title={t('review.viewComments')}
                >
                  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                    <path d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z" />
                  </svg>
                </button>
              )}
              {/* Admin-only management buttons */}
              {!readOnly && (
                <>
                  {/* Toggle button */}
                  <button
                    onClick={(e) => handleToggleActive(e, r.id, r.active)}
                    className={`flex-shrink-0 p-0.5 rounded text-muted-foreground/0 group-hover:text-muted-foreground/60 hover:!text-foreground hover:!bg-accent transition-colors ${
                      toggling === r.id ? 'opacity-50 pointer-events-none' : ''
                    }`}
                    title={r.active ? t('review.closeReview') : t('review.reopenReview')}
                  >
                    {r.active ? (
                      <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18.36 6.64a9 9 0 1 1-12.73 0"/><line x1="12" y1="2" x2="12" y2="12"/></svg>
                    ) : (
                      <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18.36 6.64A9 9 0 0 1 12 21 9 9 0 0 1 5.64 6.64"/><line x1="12" y1="2" x2="12" y2="12"/></svg>
                    )}
                  </button>
                  {/* Delete button */}
                  <button
                    onClick={(e) => handleDelete(e, r.id)}
                    className={`flex-shrink-0 p-0.5 rounded text-muted-foreground/0 group-hover:text-muted-foreground/60 hover:!text-red-500 hover:!bg-red-500/10 transition-colors ${
                      deleting === r.id ? 'opacity-50 pointer-events-none' : ''
                    }`}
                    title={t('review.deleteReview')}
                  >
                    <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                      <polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
                    </svg>
                  </button>
                </>
              )}
            </div>
            {/* Comment count */}
            {r.commentCount > 0 && (
              <div className={`text-[10px] text-muted-foreground/50 mt-0.5 ${readOnly ? '' : 'pl-3'}`}>
                {t('review.nComments', { count: r.commentCount })}
              </div>
            )}
          </div>
        ))}
        {displayReviews.length === 0 && (
          <div className="px-3 py-4 text-xs text-muted-foreground/50 text-center">
            {readOnly ? t('review.noOpenDocs') : t('review.noReviews')}
          </div>
        )}
      </div>
      {/* Fixed tooltip */}
      {tooltip && (
        <div
          className="fixed z-50 px-2 py-1 text-xs bg-popover text-popover-foreground border border-border rounded shadow-md whitespace-nowrap pointer-events-none"
          style={{ top: tooltip.top, left: tooltip.left + 8, transform: 'translateY(-50%)' }}
        >
          {tooltip.text}
        </div>
      )}
    </div>
  );
}
