import { useState, useCallback, useEffect, useMemo } from 'react';
import { Link, Navigate, useParams } from 'react-router-dom';
import { bugsApi, ApiError } from '../../utils/api';
import { useAuth } from '../../contexts/AuthContext';
import { formatDate, formatDateTime } from '../../utils/format';
import type { BugComment, BugReport, BugSeverity, BugStatus } from '../../types';

// ── Helpers ────────────────────────────────────────────────────────────────────

function StatusBadge({ status }: { status: BugStatus }) {
  const map: Record<BugStatus, string> = {
    open: 'badge-open', in_progress: 'badge-progress', resolved: 'badge-resolved', closed: 'badge-closed',
  };
  const labels: Record<BugStatus, string> = {
    open: 'Open', in_progress: 'In Progress', resolved: 'Resolved', closed: 'Closed',
  };
  return <span className={`badge ${map[status]}`}>{labels[status]}</span>;
}

function SeverityBadge({ severity }: { severity: BugSeverity }) {
  const map: Record<BugSeverity, string> = {
    low: 'badge-low', medium: 'badge-medium', high: 'badge-high', critical: 'badge-critical',
  };
  return <span className={`badge ${map[severity]}`}>{severity}</span>;
}

// ── Comment component ──────────────────────────────────────────────────────────

function CommentItem({ comment }: { comment: BugComment }) {
  return (
    <div
      style={{
        background: 'var(--color-surface)',
        border: '1px solid var(--color-border)',
        padding: '0.9rem 1.1rem',
        marginBottom: '0.5rem',
      }}
    >
      <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem', gap: '1rem', flexWrap: 'wrap' }}>
        <span style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-cyan)', fontSize: '0.78rem' }}>
          {comment.authorName}
        </span>
        <span style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.7rem', flexShrink: 0 }}>
          {formatDateTime(comment.createdAt)}
        </span>
      </div>
      <div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-dim)', fontSize: '0.83rem', lineHeight: 1.75 }}>
        {comment.content}
      </div>
    </div>
  );
}

// ── Bug Detail Page ────────────────────────────────────────────────────────────

export default function BugDetailPage() {
  const { id } = useParams<{ id: string }>();
  const { user, isAuthenticated } = useAuth();

  const [bug, setBug] = useState<BugReport | null>(null);
  const [comments, setComments] = useState<BugComment[]>([]);
  const [loading, setLoading] = useState(true);
  const [notFound, setNotFound] = useState(false);

  const [newComment, setNewComment] = useState('');
  const [commentError, setCommentError] = useState('');
  const [submitting, setSubmitting] = useState(false);

  useEffect(() => {
    if (!id) return;
    let cancelled = false;
    setLoading(true);

    bugsApi.getBug(id)
      .then((data) => {
        if (cancelled) return;
        const { comments: bugComments, ...bugData } = data;
        setBug(bugData);
        setComments(bugComments.sort((a, b) => a.createdAt.localeCompare(b.createdAt)));
      })
      .catch((err) => {
        if (cancelled) return;
        if (err instanceof ApiError && err.status === 404) setNotFound(true);
      })
      .finally(() => { if (!cancelled) setLoading(false); });

    return () => { cancelled = true; };
  }, [id]);

  const alreadyVoted = useMemo(
    () => !!user && !!bug && (bug.meTooBugs ?? []).includes(user.id),
    [user, bug]
  );
  const isOwnReport = useMemo(
    () => !!user && !!bug && bug.submittedById === user.id,
    [user, bug]
  );

  const handleMeToo = useCallback(async () => {
    if (!user || !bug || alreadyVoted || isOwnReport) return;
    try {
      await bugsApi.toggleMeToo(bug.id);
      setBug((prev) => prev ? { ...prev, meTooBugs: [...(prev.meTooBugs ?? []), user.id] } : prev);
    } catch {
      // silently ignore
    }
  }, [user, bug, alreadyVoted, isOwnReport]);

  const handleComment = useCallback(async () => {
    if (!user || !bug) return;
    if (!newComment.trim()) { setCommentError('Comment cannot be empty.'); return; }
    if (newComment.trim().length < 5) { setCommentError('Comment must be at least 5 characters.'); return; }

    setCommentError('');
    setSubmitting(true);

    try {
      const comment = await bugsApi.addComment(bug.id, newComment.trim());
      setComments((prev) => [...prev, comment]);
      setNewComment('');
    } catch (err) {
      setCommentError(err instanceof Error ? err.message : 'Failed to post comment.');
    } finally {
      setSubmitting(false);
    }
  }, [user, bug, newComment]);

  if (loading) {
    return (
      <div style={{ maxWidth: '860px', margin: '0 auto', padding: '3rem 1.5rem', textAlign: 'center', color: 'var(--color-text-muted)', fontFamily: 'var(--font-mono)' }}>
        Loading...
      </div>
    );
  }

  if (notFound || !bug) {
    return <Navigate to="/bugs" replace />;
  }

  const metooCount = (bug.meTooBugs ?? []).length;

  return (
    <div style={{ maxWidth: '860px', margin: '0 auto', padding: '3rem 1.5rem' }}>
      {/* Breadcrumb */}
      <div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.72rem', color: 'var(--color-text-muted)', marginBottom: '1.5rem' }}>
        <Link to="/bugs" style={{ color: 'var(--color-cyan)' }}>Bug Reports</Link>
        {' '}&gt;{' '}
        <span style={{ color: 'var(--color-text-dim)' }}>{bug.uniqueCode}</span>
      </div>

      {/* Header */}
      <div className="crt-box" style={{ padding: '1.75rem', marginBottom: '1rem' }}>
        <div style={{ display: 'flex', gap: '0.4rem', flexWrap: 'wrap', alignItems: 'center', marginBottom: '0.75rem' }}>
          <span style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.72rem' }}>
            {bug.uniqueCode}
          </span>
          <StatusBadge status={bug.status} />
          <SeverityBadge severity={bug.severity} />
        </div>

        <h1
          style={{
            fontFamily: 'var(--font-heading)',
            color: 'var(--color-text)',
            fontSize: 'clamp(1.4rem, 4vw, 2rem)',
            marginBottom: '1.25rem',
          }}
        >
          {bug.title}
        </h1>

        {/* Meta grid */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr))', gap: '0.6rem', marginBottom: '1.5rem' }}>
          {[
            { label: 'Submitted by', value: bug.submittedByName },
            { label: 'Date', value: formatDate(bug.createdAt) },
            { label: 'Game Version', value: `v${bug.gameVersion}` },
            { label: 'Assigned to', value: bug.assignedToName ?? 'Unassigned' },
          ].map(({ label, value }) => (
            <div
              key={label}
              style={{
                background: 'var(--color-surface-alt)',
                border: '1px solid var(--color-border)',
                padding: '0.55rem 0.7rem',
              }}
            >
              <div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.62rem', letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: '0.2rem' }}>
                {label}
              </div>
              <div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-dim)', fontSize: '0.8rem' }}>{value}</div>
            </div>
          ))}
        </div>

        {/* Description */}
        <div style={{ marginBottom: '1.25rem' }}>
          <div className="section-label" style={{ marginBottom: '0.4rem' }}>Description</div>
          <div
            style={{
              background: 'var(--color-surface-alt)',
              border: '1px solid var(--color-border)',
              padding: '0.9rem 1rem',
              fontFamily: 'var(--font-mono)',
              color: 'var(--color-text-dim)',
              fontSize: '0.83rem',
              lineHeight: 1.8,
              whiteSpace: 'pre-wrap',
              borderRadius: '6px',
            }}
          >
            {bug.description}
          </div>
        </div>

        {/* Steps to reproduce */}
        <div style={{ marginBottom: '1.5rem' }}>
          <div className="section-label" style={{ marginBottom: '0.4rem' }}>Steps to Reproduce</div>
          <div
            style={{
              background: 'var(--color-surface-alt)',
              border: '1px solid var(--color-border)',
              padding: '0.9rem 1rem',
              fontFamily: 'var(--font-mono)',
              color: 'var(--color-text-dim)',
              fontSize: '0.83rem',
              lineHeight: 1.8,
              whiteSpace: 'pre-wrap',
              borderRadius: '6px',
            }}
          >
            {bug.stepsToReproduce}
          </div>
        </div>

        {/* "I have this too" section */}
        <div
          style={{
            display: 'flex',
            alignItems: 'center',
            gap: '1rem',
            flexWrap: 'wrap',
            padding: '0.9rem 1rem',
            background: 'rgba(5,150,105,0.05)',
            border: '1px solid rgba(5,150,105,0.2)',
            borderRadius: '6px',
          }}
        >
          <div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-green)', fontSize: '0.82rem' }}>
            <span style={{ fontSize: '1.1rem' }}>{metooCount}</span>{' '}
            {metooCount === 1 ? 'user has' : 'users have'} this issue
          </div>

          {!isAuthenticated ? (
            <div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.78rem' }}>
              <Link to="/login">Login</Link> to confirm you have this issue
            </div>
          ) : isOwnReport ? (
            <span style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.78rem' }}>
              (this is your report)
            </span>
          ) : alreadyVoted ? (
            <div
              style={{
                fontFamily: 'var(--font-mono)',
                fontSize: '0.78rem',
                color: 'var(--color-green)',
                border: '1px solid var(--color-green)',
                padding: '0.25rem 0.75rem',
                background: 'rgba(5,150,105,0.08)',
                cursor: 'default',
                borderRadius: '4px',
              }}
            >
              &#10003; You reported this too
            </div>
          ) : (
            <button
              className="btn-terminal"
              onClick={handleMeToo}
              style={{ fontSize: '0.78rem', padding: '0.3rem 0.9rem' }}
            >
              &#9654; I have this too
            </button>
          )}
        </div>
      </div>

      {/* Comments section */}
      <div style={{ marginTop: '2rem' }}>
        <div
          style={{
            display: 'flex',
            alignItems: 'center',
            gap: '0.75rem',
            borderBottom: '2px solid var(--color-border)',
            paddingBottom: '0.5rem',
            marginBottom: '1rem',
          }}
        >
          <span style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-cyan)', fontSize: '0.72rem', letterSpacing: '0.15em', textTransform: 'uppercase' }}>
            Discussion
          </span>
          <span style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.65rem', border: '1px solid var(--color-border)', padding: '0.05rem 0.4rem' }}>
            {comments.length}
          </span>
        </div>

        {comments.length === 0 ? (
          <div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.8rem', padding: '1rem 0' }}>
            No comments yet. Be the first to comment.
          </div>
        ) : (
          comments.map((comment) => (
            <CommentItem key={comment.id} comment={comment} />
          ))
        )}

        <div style={{ marginTop: '1.25rem' }}>
          {isAuthenticated ? (
            <div className="crt-box" style={{ padding: '1.25rem' }}>
              <div className="section-label" style={{ marginBottom: '0.6rem' }}>Add a Comment</div>
              <textarea
                className={`input-terminal${commentError ? ' error' : ''}`}
                rows={4}
                placeholder="Write your comment..."
                value={newComment}
                onChange={(e) => { setNewComment(e.target.value); setCommentError(''); }}
                style={{ resize: 'vertical', marginBottom: '0.6rem' }}
                disabled={submitting}
                aria-label="Comment text"
              />
              {commentError && (
                <div style={{ color: 'var(--color-red)', fontFamily: 'var(--font-mono)', fontSize: '0.72rem', marginBottom: '0.6rem' }}>
                  {commentError}
                </div>
              )}
              <button
                className="btn-terminal"
                onClick={handleComment}
                disabled={submitting}
                style={{ opacity: submitting ? 0.6 : 1 }}
              >
                {submitting ? 'Posting...' : '&#9654; Post Comment'}
              </button>
            </div>
          ) : (
            <div className="crt-box" style={{ padding: '1.25rem', textAlign: 'center' }}>
              <p style={{ color: 'var(--color-text-muted)', fontFamily: 'var(--font-mono)', fontSize: '0.82rem', marginBottom: '0.75rem' }}>
                You must be logged in to comment.
              </p>
              <div style={{ display: 'flex', gap: '0.6rem', justifyContent: 'center' }}>
                <Link to="/login" className="btn-terminal">Login</Link>
                <Link to="/register" className="btn-terminal btn-amber">Register</Link>
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
