'use client';

import { useEffect, useState, use } from 'react';
import { useRouter } from 'next/navigation';
import {
  ArrowLeft, RefreshCw, Clock, FileText, Timer, CheckCircle2,
  ChevronDown, ChevronRight, User, Briefcase, AlertCircle, EyeOff, Eye, ExternalLink, Mail, AlignLeft, Code2,
} from 'lucide-react';
import { useUserTimezone } from '@/lib/hooks/use-user-timezone';

const PRIORITY_LABEL: Record<number, string> = {
  1: 'Standard', 2: 'Medium', 3: 'Standard', 4: 'Critical',
  6: 'High', 7: 'Security', 8: 'Minor Svc', 9: 'Major Svc', 10: 'Install', 11: 'Fast Track',
};
const PRIORITY_COLOR: Record<number, string> = {
  1: 'text-slate-600 bg-slate-100 border-slate-300',
  2: 'text-slate-600 bg-slate-100 border-slate-300',
  3: 'text-slate-600 bg-slate-100 border-slate-300',
  4: 'text-red-600 bg-red-100 border-red-300',
  6: 'text-orange-600 bg-orange-100 border-orange-300',
  7: 'text-purple-600 bg-purple-100 border-purple-300',
  8: 'text-yellow-700 bg-yellow-100 border-yellow-300',
  9: 'text-orange-700 bg-orange-100 border-orange-300',
  10: 'text-blue-600 bg-blue-100 border-blue-300',
  11: 'text-pink-600 bg-pink-100 border-pink-300',
};
const STATUS_LABEL: Record<number, string> = {
  1: 'New', 5: 'Complete', 7: 'Waiting Customer', 8: 'In Progress', 9: 'Waiting Materials',
  10: 'Dispatched', 11: 'Escalate', 12: 'Waiting Vendor', 13: 'Waiting Approval',
  14: 'Resource Assigned', 16: 'Reopened', 19: 'End User Note Added', 25: 'On Hold',
  27: 'Resolution Plan', 37: 'Client Non-Responsive', 45: 'Pending Next Site Visit',
  47: 'Resource Requested', 48: 'Escalate to MC', 57: 'Escalate to Wulf', 61: 'Escalate to CSM',
  66: 'Internal Note Added', 70: 'Waiting Quote Acceptance', 71: 'Waiting Project/Ticket',
};

interface Ticket {
  id: number; ticket_number: string; title: string; description: string;
  status: number; priority: number; create_date: string; last_activity_date: string;
  due_date_time: string | null; resolved_date_time: string | null;
  queue_label: string; estimated_hours: string | null; resolution: string | null;
  company_name: string; assigned_to: string;
}
type TimelineItem =
  | { kind: 'created'; ts: string; ticket: Ticket }
  | { kind: 'note'; ts: string; is_system: boolean; data: { id: number; title: string; description: string; note_type: number; publish: number; author: string } }
  | { kind: 'time'; ts: string; data: { id: number; hours_worked: string; notes: string; billable: boolean; resource_name: string } }
  | { kind: 'resolved'; ts: string };

function fmtDate(ts: string, tz: string) {
  return new Date(ts).toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit', timeZone: tz });
}
function fmtHours(h: string | number) {
  const n = parseFloat(String(h));
  if (n < 1) return `${Math.round(n * 60)}m`;
  return `${n.toFixed(1)}h`;
}
function renderContent(s: string): React.ReactNode[] {
  if (!s) return [];

  // Step 1: convert <a href="...">...</a> → placeholder §URL§
  // Collect links in order
  const links: string[] = [];
  const withPlaceholders = s.replace(/<a\b[^>]*\bhref=["']([^"']+)["'][^>]*>.*?<\/a>/gi, (_, href) => {
    links.push(href);
    return `\x00LINK${links.length - 1}\x00`;
  });

  // Step 2: strip remaining HTML tags
  const plain = withPlaceholders.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();

  // Step 3: split on LINK placeholders and bare URLs
  const URL_RE = /\x00LINK(\d+)\x00|(https?:\/\/[^\s<>"']+)/g;
  const nodes: React.ReactNode[] = [];
  let last = 0;
  let match: RegExpExecArray | null;
  let key = 0;

  while ((match = URL_RE.exec(plain)) !== null) {
    if (match.index > last) {
      nodes.push(plain.slice(last, match.index));
    }
    const href = match[1] !== undefined ? links[parseInt(match[1])] : match[2];
    nodes.push(
      <a key={key++} href={href} target="_blank" rel="noopener noreferrer"
        className="text-primary underline" onClick={e => e.stopPropagation()}>
        [link]
      </a>
    );
    last = match.index + match[0].length;
  }
  if (last < plain.length) nodes.push(plain.slice(last));
  return nodes;
}

function TimelineCard({ item, tz, defaultOpen = false }: { item: TimelineItem; tz: string; defaultOpen?: boolean }) {
  const [open, setOpen] = useState(defaultOpen);

  if (item.kind === 'created') {
    return (
      <div className="flex gap-3">
        <div className="flex flex-col items-center">
          <div className="w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center shrink-0">
            <FileText className="w-4 h-4 text-primary" />
          </div>
          <div className="w-px flex-1 bg-border mt-1" />
        </div>
        <div className="pb-4 flex-1 min-w-0">
          <p className="text-xs text-muted-foreground mb-0.5">{fmtDate(item.ts, tz)}</p>
          <p className="text-sm font-medium">Ticket created</p>
        </div>
      </div>
    );
  }

  if (item.kind === 'resolved') {
    return (
      <div className="flex gap-3">
        <div className="flex flex-col items-center">
          <div className="w-8 h-8 rounded-full bg-green-100 flex items-center justify-center shrink-0">
            <CheckCircle2 className="w-4 h-4 text-green-600" />
          </div>
        </div>
        <div className="pb-4 flex-1">
          <p className="text-xs text-muted-foreground mb-0.5">{fmtDate(item.ts, tz)}</p>
          <p className="text-sm font-medium text-green-600">Ticket resolved</p>
        </div>
      </div>
    );
  }

  if (item.kind === 'time') {
    const te = item.data;
    return (
      <div className="flex gap-3">
        <div className="flex flex-col items-center">
          <div className="w-8 h-8 rounded-full bg-blue-500/20 flex items-center justify-center shrink-0">
            <Timer className="w-4 h-4 text-blue-400" />
          </div>
          <div className="w-px flex-1 bg-border mt-1" />
        </div>
        <div className="pb-4 flex-1 min-w-0">
          <p className="text-xs text-muted-foreground mb-0.5">{fmtDate(item.ts, tz)}</p>
          <button onClick={() => setOpen(o => !o)}
            className="w-full text-left flex items-center gap-2">
            <p className="text-sm font-medium flex-1">
              Time entry — {fmtHours(te.hours_worked)}
              {!te.billable && <span className="ml-1 text-xs text-muted-foreground">(non-bill)</span>}
            </p>
            {open ? <ChevronDown className="w-4 h-4 text-muted-foreground shrink-0" /> : <ChevronRight className="w-4 h-4 text-muted-foreground shrink-0" />}
          </button>
          {open && (
            <div className="mt-2 rounded-lg bg-muted border border-border p-3 space-y-1.5">
              <p className="text-xs font-medium text-foreground flex items-center gap-1.5">
                <User className="w-3 h-3 text-muted-foreground" />{te.resource_name}
              </p>
              {te.notes && <p className="text-sm text-foreground leading-relaxed">{renderContent(te.notes)}</p>}
            </div>
          )}
        </div>
      </div>
    );
  }

  // note
  const note = item.data;
  const isInternal = note.publish === 2;
  const isSystem = item.is_system;
  const bodyNodes = renderContent(note.description ?? '');
  const bodyPlain = (note.description ?? '').replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
  const isEmail = note.note_type === 2;
  const iconColor = isSystem ? 'text-muted-foreground' : isInternal ? 'text-slate-400' : isEmail ? 'text-violet-500' : 'text-amber-500';
  const iconBg   = isSystem ? 'bg-muted' : isInternal ? 'bg-muted' : isEmail ? 'bg-violet-500/10' : 'bg-amber-500/10';
  const NoteIcon = isEmail ? Mail : FileText;
  return (
    <div className="flex gap-3">
      <div className="flex flex-col items-center">
        <div className={`w-8 h-8 rounded-full flex items-center justify-center shrink-0 ${iconBg}`}>
          <NoteIcon className={`w-4 h-4 ${iconColor}`} />
        </div>
        <div className="w-px flex-1 bg-border mt-1" />
      </div>
      <div className="pb-4 flex-1 min-w-0">
        <p className="text-xs text-muted-foreground mb-0.5">{fmtDate(item.ts, tz)}</p>
        <button onClick={() => setOpen(o => !o)} className="w-full text-left">
          <div className="flex items-start gap-1">
            <div className="flex-1 min-w-0">
              <p className={`text-sm font-medium line-clamp-1 ${isSystem ? 'text-muted-foreground' : ''}`}>
                {note.title || (isInternal ? 'Internal Note' : 'Customer Note')}
              </p>
              {!open && bodyPlain && <p className="text-xs text-muted-foreground line-clamp-2 mt-0.5">{bodyPlain}</p>}
            </div>
            {open ? <ChevronDown className="w-4 h-4 text-muted-foreground shrink-0 mt-0.5" /> : <ChevronRight className="w-4 h-4 text-muted-foreground shrink-0 mt-0.5" />}
          </div>
        </button>
        {open && (
          <div className="mt-2 rounded-lg border border-border bg-muted p-3">
            <p className="text-xs text-muted-foreground flex items-center gap-1 mb-1.5">
              <User className="w-3 h-3" />{note.author || 'System'} · {isSystem ? 'System' : isInternal ? 'Internal' : 'Client-visible'}
            </p>
            <p className="text-sm text-foreground whitespace-pre-wrap leading-relaxed">{bodyNodes}</p>
          </div>
        )}
      </div>
    </div>
  );
}

export default function TicketTimeline({ params }: { params: Promise<{ id: string }> }) {
  const { id } = use(params);
  const router = useRouter();
  const tz = useUserTimezone();
  const [data, setData] = useState<{ ticket: Ticket; timeline: TimelineItem[]; total_hours: number } | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [showSystem, setShowSystem] = useState(false);
  const [showInternal, setShowInternal] = useState(false);
  const [descOpen, setDescOpen] = useState(true);
  const [descRaw, setDescRaw] = useState(false);

  useEffect(() => {
    setLoading(true);
    fetch(`/api/mobile/tickets/${id}/timeline`)
      .then(r => r.json())
      .then(d => { setData(d); setLoading(false); })
      .catch(e => { setError(String(e)); setLoading(false); });
  }, [id]);

  if (loading) return (
    <div className="flex items-center justify-center h-64">
      <RefreshCw className="w-6 h-6 animate-spin text-muted-foreground" />
    </div>
  );
  if (error || !data) return <div className="p-4 text-sm text-destructive">{error ?? 'Not found'}</div>;

  const { ticket, timeline, total_hours } = data;
  const priClass = PRIORITY_COLOR[ticket.priority] ?? 'text-slate-600 bg-slate-50 border-slate-200';

  return (
    <div>
      {/* Ticket header */}
      <div className="px-4 pt-4 pb-3 border-b">
        <div className="flex items-center justify-between -mx-4 px-4 py-3 border-b mb-3">
          <button
            type="button"
            onClick={() => router.back()}
            aria-label="Back to Tickets"
            className="flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground transition-colors"
          >
            <ArrowLeft className="w-4 h-4" aria-hidden="true" />
            <span>Tickets</span>
          </button>

          <p className="text-sm font-semibold truncate mx-2 flex-1 text-center">
            Tickets / #{ticket.ticket_number}
          </p>

          <a
            href={`/analyzer/ticket/${ticket.id}`}
            target="_blank"
            rel="noopener noreferrer"
            aria-label="Open ticket on desktop"
            className="text-muted-foreground hover:text-foreground transition-colors shrink-0"
          >
            <ExternalLink className="w-4 h-4" aria-hidden="true" />
          </a>
        </div>
        <div className="flex items-start gap-2 mb-2">
          <span className={`shrink-0 text-xs font-medium px-2 py-0.5 rounded-full border ${priClass}`}>
            {PRIORITY_LABEL[ticket.priority] ?? `P${ticket.priority}`}
          </span>
          <span className="text-xs text-muted-foreground bg-muted px-2 py-0.5 rounded-full font-mono">
            {ticket.ticket_number}
          </span>
          <span className="text-xs text-muted-foreground bg-muted px-2 py-0.5 rounded-full">
            {STATUS_LABEL[ticket.status] ?? `Status ${ticket.status}`}
          </span>
        </div>
        <h1 className="text-base font-bold leading-snug">{ticket.title}</h1>
        <div className="mt-2 space-y-1">
          <p className="text-xs text-muted-foreground flex items-center gap-1.5">
            <Briefcase className="w-3.5 h-3.5" />{ticket.company_name}
          </p>
          {ticket.assigned_to && (
            <p className="text-xs text-muted-foreground flex items-center gap-1.5">
              <User className="w-3.5 h-3.5" />{ticket.assigned_to} · {ticket.queue_label ?? '—'}
            </p>
          )}
          <p className="text-xs text-muted-foreground flex items-center gap-1.5">
            <Clock className="w-3.5 h-3.5" />Created {fmtDate(ticket.create_date, tz)}
          </p>
        </div>

        {/* Stats row */}
        <div className="grid grid-cols-3 gap-2 mt-3">
          <div className="rounded-lg bg-muted/50 p-2 text-center">
            <p className="text-base font-bold">{timeline.filter(i => i.kind === 'note').length}</p>
            <p className="text-[10px] text-muted-foreground">Notes</p>
          </div>
          <div className="rounded-lg bg-muted/50 p-2 text-center">
            <p className="text-base font-bold">{timeline.filter(i => i.kind === 'time').length}</p>
            <p className="text-[10px] text-muted-foreground">Time entries</p>
          </div>
          <div className="rounded-lg bg-muted/50 p-2 text-center">
            <p className="text-base font-bold">{total_hours}h</p>
            <p className="text-[10px] text-muted-foreground">Hours logged</p>
          </div>
        </div>

        {/* Description */}
        {ticket.description && (
          <div className="mt-3">
            <button
              onClick={() => setDescOpen(o => !o)}
              className="w-full flex items-center justify-between py-1.5 text-left"
            >
              <span className="flex items-center gap-1.5 text-xs font-semibold text-muted-foreground uppercase tracking-wider">
                <AlignLeft className="w-3.5 h-3.5" />Description
              </span>
              {descOpen
                ? <ChevronDown className="w-3.5 h-3.5 text-muted-foreground" />
                : <ChevronRight className="w-3.5 h-3.5 text-muted-foreground" />}
            </button>
            {descOpen && (
              <div className="mt-1.5 rounded-xl border bg-muted/40 p-3">
                {descRaw ? (
                  <pre className="text-xs text-muted-foreground whitespace-pre-wrap break-words font-mono leading-relaxed">
                    {ticket.description.replace(/<[^>]+>/g, '').replace(/&nbsp;/g, ' ').replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').trim()}
                  </pre>
                ) : (
                  <p className="text-sm text-foreground leading-relaxed">{renderContent(ticket.description)}</p>
                )}
                <button
                  onClick={() => setDescRaw(r => !r)}
                  className="mt-2 flex items-center gap-1 text-[11px] text-muted-foreground hover:text-foreground transition-colors"
                >
                  <Code2 className="w-3 h-3" />
                  {descRaw ? 'Show formatted' : 'View original'}
                </button>
              </div>
            )}
          </div>
        )}
      </div>

      {/* Timeline */}
      <div className="px-4 pt-5">
        <div className="flex items-center justify-between mb-4 gap-3">
          <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">Timeline</p>
          <div className="flex items-center gap-3">
            <button
              onClick={() => setShowInternal(s => !s)}
              className="flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors">
              {showInternal ? <EyeOff className="w-3.5 h-3.5" /> : <Eye className="w-3.5 h-3.5" />}
              {showInternal ? 'Hide internal' : 'Show internal'}
            </button>
            <button
              onClick={() => setShowSystem(s => !s)}
              className="flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors">
              {showSystem ? <EyeOff className="w-3.5 h-3.5" /> : <Eye className="w-3.5 h-3.5" />}
              {showSystem ? 'Hide system' : 'Show system'}
            </button>
          </div>
        </div>
        {timeline.length === 0 ? (
          <p className="text-sm text-muted-foreground text-center py-8">No activity recorded</p>
        ) : (
          timeline
            .filter(item => {
              if (item.kind !== 'note') return true;
              if (!showSystem && item.is_system) return false;
              if (!showInternal && (item.data as any).publish === 2) return false;
              return true;
            })
            .map((item, i) => (
              <TimelineCard key={i} item={item} tz={tz} defaultOpen={item.kind === 'note' && i === timeline.length - 1} />
            ))
        )}
      </div>
    </div>
  );
}
