'use client';

import { useEffect, useRef } from 'react';
import type { ReactNode } from 'react';
import { cn } from '@/lib/cn';
import type { Task } from '@/lib/types';

interface TaskDetailModalProps {
  task: Task;
  onClose: () => void;
}

const priorityColors: Record<string, string> = {
  critical: 'text-error',
  high: 'text-warning',
  medium: 'text-blue-400',
  low: 'text-text-muted',
};

const statusBadgeColors: Record<string, string> = {
  'not-started': 'bg-gray-600/20 text-gray-300',
  'in-progress': 'bg-blue-600/20 text-blue-400',
  blocked: 'bg-error/20 text-error',
  done: 'bg-success/20 text-success',
  cancelled: 'bg-gray-600/20 text-gray-500',
};

function DetailRow({
  label,
  children,
}: {
  label: string;
  children: ReactNode;
}): React.ReactElement {
  return (
    <div className="flex gap-2 py-2 text-sm">
      <span className="w-24 shrink-0 text-text-muted">{label}</span>
      <span className="text-text-primary">{children}</span>
    </div>
  );
}

export function TaskDetailModal({ task, onClose }: TaskDetailModalProps): React.ReactElement {
  const dialogRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    function handleKeyDown(e: KeyboardEvent): void {
      if (e.key === 'Escape') onClose();
    }
    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  }, [onClose]);

  // Trap focus on mount
  useEffect(() => {
    dialogRef.current?.focus();
  }, []);

  const prLinks = extractPrLinks(task.metadata);

  return (
    /* backdrop */
    <div
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4"
      onClick={(e) => {
        if (e.target === e.currentTarget) onClose();
      }}
      role="presentation"
    >
      <div
        ref={dialogRef}
        role="dialog"
        aria-modal="true"
        aria-labelledby="task-detail-title"
        tabIndex={-1}
        className="flex max-h-[90vh] w-full max-w-lg flex-col overflow-hidden rounded-xl border border-surface-border bg-surface-card outline-none"
      >
        {/* Header */}
        <div className="flex items-start justify-between gap-3 border-b border-surface-border p-4">
          <h2 id="task-detail-title" className="text-base font-semibold text-text-primary">
            {task.title}
          </h2>
          <button
            type="button"
            onClick={onClose}
            aria-label="Close task details"
            className="shrink-0 rounded p-1 text-text-muted hover:text-text-primary"
          >
            ✕
          </button>
        </div>

        {/* Body */}
        <div className="flex-1 overflow-y-auto p-4">
          {/* Badges */}
          <div className="mb-4 flex flex-wrap gap-2">
            <span
              className={cn(
                'rounded-full px-2 py-0.5 text-xs',
                statusBadgeColors[task.status] ?? 'bg-gray-600/20 text-gray-400',
              )}
            >
              {task.status}
            </span>
            <span className={cn('text-xs', priorityColors[task.priority])}>
              {task.priority} priority
            </span>
          </div>

          {/* Description */}
          {task.description && (
            <div className="mb-4 rounded-lg bg-surface-elevated p-3">
              <p className="text-sm text-text-secondary">{task.description}</p>
            </div>
          )}

          {/* Details */}
          <div className="divide-y divide-surface-border rounded-lg border border-surface-border px-3">
            {task.assignee ? <DetailRow label="Assignee">{task.assignee}</DetailRow> : null}
            {task.dueDate ? (
              <DetailRow label="Due date">
                {new Date(task.dueDate).toLocaleDateString(undefined, {
                  year: 'numeric',
                  month: 'long',
                  day: 'numeric',
                })}
              </DetailRow>
            ) : null}
            <DetailRow label="Created">
              {new Date(task.createdAt).toLocaleDateString(undefined, {
                year: 'numeric',
                month: 'long',
                day: 'numeric',
              })}
            </DetailRow>
            <DetailRow label="Updated">
              {new Date(task.updatedAt).toLocaleDateString(undefined, {
                year: 'numeric',
                month: 'long',
                day: 'numeric',
              })}
            </DetailRow>
          </div>

          {/* Tags */}
          {task.tags != null && task.tags.length > 0 ? (
            <div className="mt-4">
              <p className="mb-2 text-xs text-text-muted">Tags</p>
              <div className="flex flex-wrap gap-1">
                {task.tags.map((tag) => (
                  <span
                    key={tag}
                    className="rounded-full bg-surface-elevated px-2 py-0.5 text-xs text-text-secondary"
                  >
                    {tag}
                  </span>
                ))}
              </div>
            </div>
          ) : null}

          {/* PR Links */}
          {prLinks.length > 0 ? (
            <div className="mt-4">
              <p className="mb-2 text-xs text-text-muted">Pull Requests</p>
              <ul className="space-y-1">
                {prLinks.map((link) => (
                  <li key={link.url}>
                    <a
                      href={link.url}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-xs text-blue-400 underline hover:text-blue-300"
                    >
                      {link.label ?? link.url}
                    </a>
                  </li>
                ))}
              </ul>
            </div>
          ) : null}

          {/* Notes from metadata */}
          <NotesSection notes={getNotesString(task.metadata)} />
        </div>
      </div>
    </div>
  );
}

interface PrLink {
  url: string;
  label?: string;
}

function extractPrLinks(metadata: Record<string, unknown> | null): PrLink[] {
  if (!metadata) return [];

  const raw = metadata['pr_links'] ?? metadata['prLinks'];
  if (!Array.isArray(raw)) return [];

  return raw
    .filter((item): item is PrLink => {
      if (typeof item === 'string') return true;
      if (typeof item === 'object' && item !== null && 'url' in item) return true;
      return false;
    })
    .map((item): PrLink => {
      if (typeof item === 'string') return { url: item };
      return item as PrLink;
    });
}

function getNotesString(metadata: Record<string, unknown> | null): string | null {
  if (!metadata) return null;
  const notes = metadata['notes'];
  if (typeof notes === 'string' && notes.trim().length > 0) return notes;
  return null;
}

function NotesSection({ notes }: { notes: string | null }): React.ReactElement | null {
  if (!notes) return null;
  return (
    <div className="mt-4">
      <p className="mb-2 text-xs text-text-muted">Notes</p>
      <div className="rounded-lg bg-surface-elevated p-3">
        <p className="whitespace-pre-wrap text-xs text-text-secondary">{notes}</p>
      </div>
    </div>
  );
}
