'use client';

import React, { useState, useEffect, useRef } from 'react';
import Link from 'next/link';
import { useAuth } from '@/contexts/AuthContext';
import { useRouter } from 'next/navigation';
import { BB_PEN_NAMES, AV_PEN_NAMES } from '@/lib/auth/permissions';

// ─── Types ────────────────────────────────────────────────────────────────────
interface Message {
  id: string;
  role: 'user' | 'assistant';
  content: string;
  timestamp: Date;
  provider?: 'ollama' | 'anthropic';
}

interface Session {
  id: string;
  site_id: number;
  pen_name: string | null;
  first_message_preview: string;
  provider_used: string;
  last_message_at: string;
}

interface AIStatus {
  ollama: { online: boolean; latencyMs: number; models: string[] };
  anthropic: { configured: boolean };
  currentProvider: 'ollama' | 'anthropic';
}

// ─── Pen name style guide data ────────────────────────────────────────────────
interface PenNameProfile {
  name: string;
  title: string;
  beat: string;
  site: 'BB' | 'AV';
  styleNotes: string;
  toneKeywords: string[];
  exampleLead: string;
}

const PEN_NAME_PROFILES: PenNameProfile[] = [
  {
    name: 'Michael Strand', title: 'Senior Technology Editor', site: 'BB',
    beat: 'Broadcast technology, industry news, NAB Show primary correspondent',
    styleNotes: 'Authoritative and comprehensive. Leads with the big-picture industry implication before drilling into product specifics. Favors longer paragraphs with technical depth. Uses precise broadcast engineering terminology without over-explaining.',
    toneKeywords: ['authoritative', 'comprehensive', 'technical', 'industry-wide'],
    exampleLead: 'The shift toward IP-based production infrastructure reached a new milestone this week as...',
  },
  {
    name: 'David Harlow', title: 'Broadcast Engineering Correspondent', site: 'BB',
    beat: 'Broadcast engineering, transmission, RF, satellite, signal distribution',
    styleNotes: 'Engineering-first perspective. Leads with the technical specification or engineering challenge being solved. Uses RF and transmission terminology fluently. Concise, factual sentences. Avoids marketing language entirely.',
    toneKeywords: ['engineering-focused', 'technical', 'concise', 'specification-driven'],
    exampleLead: 'A new RF transmission system capable of sustaining 4K HDR delivery across legacy infrastructure...',
  },
  {
    name: 'Karen Fielding', title: 'Post Production Editor', site: 'BB',
    beat: 'Post production, editing, color grading, VFX, media asset management',
    styleNotes: 'Workflow-oriented. Explains how tools fit into real post production pipelines. Speaks to colorists, editors, and MAM administrators. Uses post-specific terminology (LUT, roundtrip, proxy, conform) naturally.',
    toneKeywords: ['workflow-focused', 'practical', 'pipeline-aware', 'post-specific'],
    exampleLead: 'Colorists working in high-volume episodic environments will find the new grading pipeline...',
  },
  {
    name: 'James Mercer', title: 'NAB Show Senior Correspondent', site: 'BB',
    beat: 'NAB Show Las Vegas, NAB Show New York, show floor coverage, exhibitor news',
    styleNotes: 'Show-floor energy. Vivid, present-tense descriptions of booth experiences and product demos. Contextualizes announcements within the broader NAB narrative. Primary byline for all major NAB pillar content.',
    toneKeywords: ['show-floor', 'vivid', 'contextual', 'event-driven'],
    exampleLead: 'Walking the South Hall at NAB Show Las Vegas, the density of IP production announcements...',
  },
  {
    name: 'Peter Calloway', title: 'Radio & Transmission Reporter', site: 'BB',
    beat: 'Radio broadcasting, AM/FM/DAB, transmission infrastructure, tower and antenna technology',
    styleNotes: 'Radio-industry insider voice. Understands the economics of tower infrastructure and the regulatory landscape. Writes for station engineers and broadcast directors. Straightforward, no-nonsense style.',
    toneKeywords: ['radio-focused', 'regulatory-aware', 'infrastructure', 'practical'],
    exampleLead: 'Station engineers managing aging AM transmitter infrastructure now have a cost-effective upgrade path...',
  },
  {
    name: 'Sandra Voss', title: 'Production Technology Editor', site: 'BB',
    beat: 'Studio production, cameras, switchers, graphics systems, live production',
    styleNotes: 'Live production specialist. Focuses on the director and technical director perspective. Evaluates cameras and switchers in terms of production flexibility and reliability under live conditions.',
    toneKeywords: ['live-production', 'reliability-focused', 'director-perspective', 'studio-aware'],
    exampleLead: "Technical directors running multi-camera live productions will appreciate the new switcher's...",
  },
  {
    name: 'Brian Kowalski', title: 'Streaming & OTT Correspondent', site: 'BB',
    beat: 'Streaming technology, OTT platforms, CDN, video delivery, cloud broadcast',
    styleNotes: 'Cloud-native perspective. Comfortable with CDN architecture, encoding ladders, and OTT business models. Writes for streaming engineers and platform operators. Uses streaming-specific metrics (rebuffering rate, ABR, latency).',
    toneKeywords: ['cloud-native', 'platform-aware', 'metrics-driven', 'OTT-focused'],
    exampleLead: 'As sub-second latency becomes table stakes for live streaming, the new delivery architecture...',
  },
  {
    name: 'Laura Pennington', title: 'Industry News Editor', site: 'BB',
    beat: 'Company news, acquisitions, appointments, executive moves, industry business coverage',
    styleNotes: 'Business journalism style. Leads with the news fact, then provides context and industry reaction. Quotes executives accurately. Covers M&A with an understanding of strategic rationale.',
    toneKeywords: ['business-journalism', 'fact-first', 'executive-focused', 'strategic'],
    exampleLead: "The broadcast industry's transition to cloud production is accelerating faster than most analysts predicted...",
  },
  {
    name: 'Thomas Reeves', title: 'Audio Technology Correspondent', site: 'BB',
    beat: 'Broadcast audio, mixing consoles, audio processing, AES Convention coverage',
    styleNotes: "Broadcast audio engineer's perspective. Evaluates consoles and processors from a workflow standpoint. Uses AES and SMPTE audio terminology. Covers both technical specifications and operational workflow.",
    toneKeywords: ['audio-engineering', 'AES-fluent', 'console-focused', 'workflow-aware'],
    exampleLead: 'Broadcast audio engineers demanding more flexible routing in live production environments...',
  },
  {
    name: 'Christine Vale', title: 'Business & Industry Reporter', site: 'BB',
    beat: 'Industry analysis, market trends, opinion, business of broadcast',
    styleNotes: 'Analytical and opinion-forward. Comfortable with market data and industry forecasts. Writes longer-form analysis pieces. Challenges conventional wisdom when data supports it.',
    toneKeywords: ['analytical', 'opinion-forward', 'data-driven', 'market-aware'],
    exampleLead: "The broadcast industry's transition to cloud production is accelerating faster than most analysts predicted...",
  },
  {
    name: 'Marcus Webb', title: 'Live Production Correspondent', site: 'BB',
    beat: 'Live events, sports broadcasting, remote production, REMI and IP production workflows',
    styleNotes: 'Sports and live events specialist. Understands REMI/at-home production economics. Writes for remote production engineers and sports broadcast directors. Covers IP workflows in the context of real production deployments.',
    toneKeywords: ['sports-broadcast', 'REMI-focused', 'IP-production', 'event-driven'],
    exampleLead: 'The remote production workflow deployed for last season\'s playoff coverage has now become...',
  },
  {
    name: 'Ellen Forsythe', title: 'International Markets Editor', site: 'BB',
    beat: 'IBC Show, BroadcastAsia, CABSAT, international broadcast markets',
    styleNotes: 'International perspective. Contextualizes technology announcements within regional market dynamics. Covers IBC and BroadcastAsia with an understanding of European and Asian regulatory environments.',
    toneKeywords: ['international', 'market-contextual', 'regulatory-aware', 'IBC-focused'],
    exampleLead: 'European broadcasters navigating the DVB-I transition are finding new deployment options...',
  },
  {
    name: 'Rex Chandler', title: 'AV Integration Senior Correspondent', site: 'AV',
    beat: 'AV systems integration, integrator news, company announcements, InfoComm coverage',
    styleNotes: 'Integration-industry insider. Writes for AV integrators and systems designers. Understands the full project lifecycle from design through commissioning. Primary InfoComm correspondent.',
    toneKeywords: ['integration-focused', 'project-lifecycle', 'integrator-voice', 'InfoComm-primary'],
    exampleLead: 'AV integrators tackling large-scale corporate campus deployments now have a unified platform...',
  },
  {
    name: 'Dana Flux', title: 'Digital Signage & Display Editor', site: 'AV',
    beat: 'Digital signage, LED walls, display technology, CMS platforms',
    styleNotes: 'Display technology specialist. Evaluates LED walls and CMS platforms from a deployment and content management perspective. Understands pixel pitch, brightness specs, and content scheduling workflows.',
    toneKeywords: ['display-focused', 'CMS-aware', 'deployment-practical', 'spec-driven'],
    exampleLead: "The latest generation of fine-pitch LED displays is pushing the boundaries of what's achievable...",
  },
  {
    name: 'Derek Wainwright', title: 'Unified Communications Correspondent', site: 'AV',
    beat: 'UC&C, video conferencing, hybrid meeting rooms, Microsoft Teams Rooms, Zoom Rooms',
    styleNotes: 'UC&C specialist. Writes for IT managers and AV integrators deploying hybrid meeting solutions. Understands the Microsoft and Zoom certification ecosystems. Focuses on user experience and IT manageability.',
    toneKeywords: ['UC-focused', 'hybrid-work', 'IT-aware', 'certification-fluent'],
    exampleLead: 'As hybrid work becomes permanent, IT managers are demanding meeting room solutions that...',
  },
  {
    name: 'Sloane Rigging', title: 'Installed AV & Audio Editor', site: 'AV',
    beat: 'Installed audio, sound reinforcement, houses of worship AV, DSP, loudspeakers',
    styleNotes: 'Installed audio specialist. Writes for system designers and audio consultants. Understands DSP configuration, loudspeaker coverage patterns, and the unique requirements of houses of worship.',
    toneKeywords: ['installed-audio', 'DSP-fluent', 'worship-AV', 'system-design'],
    exampleLead: 'Houses of worship seeking intelligible speech reinforcement across challenging acoustical spaces...',
  },
  {
    name: 'Chip Crosspoint', title: 'AV Networking & Technology Correspondent', site: 'AV',
    beat: 'AV-over-IP, Dante, IPMX, control systems, IT/AV convergence',
    styleNotes: 'AV networking deep-diver. Comfortable with Dante, IPMX, and AES67 at a technical level. Writes for AV engineers and IT/AV convergence specialists. Explains complex networking concepts clearly.',
    toneKeywords: ['AV-networking', 'Dante-fluent', 'IPMX-aware', 'IT-AV-convergence'],
    exampleLead: 'The adoption of IPMX as a unified AV-over-IP standard is accelerating as major manufacturers...',
  },
  {
    name: 'Blair Presenter', title: 'Education & Corporate AV Editor', site: 'AV',
    beat: 'Education AV, classroom technology, corporate AV, government AV, ISE coverage',
    styleNotes: 'Education and corporate AV specialist. Understands the procurement cycles and budget constraints of K-12, higher education, and government AV. ISE correspondent.',
    toneKeywords: ['education-AV', 'corporate-AV', 'procurement-aware', 'ISE-focused'],
    exampleLead: 'K-12 districts managing post-pandemic classroom technology refreshes are finding that...',
  },
  {
    name: 'Jordan Lumen', title: 'Display & Visualization Correspondent', site: 'AV',
    beat: 'Projectors, large-venue displays, video walls, visualization technology, simulation',
    styleNotes: 'Large-venue display specialist. Evaluates projectors and video walls for large-venue and simulation applications. Understands lumen output, throw ratios, and blending technology.',
    toneKeywords: ['large-venue', 'projection-focused', 'simulation-aware', 'visualization'],
    exampleLead: 'Large-venue integrators specifying projection systems for auditoriums and simulation centers...',
  },
];

const QUICK_ACTIONS = [
  { label: 'New Story from URL', key: 'url_story' },
  { label: 'Write Exhibitor Preview', key: 'exhibitor_preview' },
  { label: 'Rewrite Press Release', key: 'press_release' },
  { label: 'Generate NAB Story', key: 'nab_story' },
  { label: 'Generate InfoComm Story', key: 'infocomm_story' },
  { label: 'Social Media Posts', key: 'social_posts' },
  { label: 'Story Headline Options', key: 'headlines' },
  { label: 'Translate Story', key: 'translate' },
  { label: 'Company Bio', key: 'company_bio' },
  { label: 'Product Description', key: 'product_desc' },
];

const QUICK_ACTION_TEMPLATES: Record<string, string> = {
  url_story: `Write a news story for [AV Beat / AV Beat] based on this URL: [URL]. Use the byline [pen name]. Target length: [400-600] words. Focus angle: [product launch / company news / industry trend].`,
  exhibitor_preview: `Write a pre-show exhibitor preview for [company name] at [NAB Show / InfoComm] [year]. They will be showing [product/technology]. Booth: [number if known]. Use [pen name] byline. 400-500 words.`,
  press_release: `Rewrite the following press release as a real news story for [AV Beat / AV Beat]. Remove marketing language, lead with the news hook, add industry context. Byline: [pen name].

[PASTE PRESS RELEASE HERE]`,
  nab_story: `Write a [story type: preview / announcement / recap] story about [topic/company] for NAB Show [year]. Include relevant SEO keywords. Byline: James Mercer. [400-800] words.`,
  infocomm_story: `Write a [story type: preview / announcement / recap] story about [topic/company] for InfoComm [year]. Include relevant SEO keywords. Byline: Rex Chandler. [400-800] words.`,
  social_posts: `Generate social media posts for the following story. Create versions for: Twitter/X (280 chars max), LinkedIn (professional tone, 150 words max), Facebook (conversational, 100 words max).
Story headline: [HEADLINE]
Story summary: [SUMMARY]`,
  headlines: `Generate 8 headline options for this story. Include 2 SEO-optimized versions targeting [keyword], 2 social media-friendly versions, 2 trade publication style versions, and 2 alternatives. Story summary: [SUMMARY]`,
  translate: `Translate the following story into [language]. Maintain the professional trade publication tone. Keep technical terms in their internationally recognized form. [PASTE STORY HERE]`,
  company_bio: `Write a 150-word company bio for [company name] suitable for use as a boilerplate paragraph at the end of news stories on [AV Beat / AV Beat]. The company makes [products/services]. Website: [URL].`,
  product_desc: `Write a 200-word product description for [product name] by [company]. Key features: [features]. Target audience: [integrators / broadcast engineers / etc]. Suitable for use in a product announcement story.`,
};

function renderMarkdown(text: string): string {
  return text
    .replace(/^### (.+)$/gm, '<h3 class="text-base font-bold text-white mt-4 mb-1">$1</h3>')
    .replace(/^## (.+)$/gm, '<h2 class="text-lg font-bold text-white mt-5 mb-2">$1</h2>')
    .replace(/^# (.+)$/gm, '<h1 class="text-xl font-bold text-white mt-5 mb-2">$1</h1>')
    .replace(/\*\*(.+?)\*\*/g, '<strong class="text-white font-semibold">$1</strong>')
    .replace(/\*(.+?)\*/g, '<em>$1</em>')
    .replace(/`([^`]+)`/g, '<code class="bg-[#FFFFFF] text-[#1D4ED8] px-1 py-0.5 rounded text-sm font-mono">$1</code>')
    .replace(/^- (.+)$/gm, '<li class="ml-4 list-disc text-[#aaa]">$1</li>')
    .replace(/^\d+\. (.+)$/gm, '<li class="ml-4 list-decimal text-[#aaa]">$1</li>')
    .replace(/\n\n/g, '</p><p class="mb-3 text-[#ccc] leading-relaxed">')
    .replace(/\n/g, '<br/>');
}

// ─── Draft Preview Modal ───────────────────────────────────────────────────────
interface DraftPreviewModalProps {
  content: string;
  title: string;
  penName: string;
  siteId: number;
  onClose: () => void;
  onSave: (openEditor: boolean) => void;
}

function DraftPreviewModal({ content, title, penName, siteId, onClose, onSave }: DraftPreviewModalProps) {
  const wordCount = content.replace(/<[^>]+>/g, '').split(/\s+/).filter(Boolean).length;

  return (
    <div className="fixed inset-0 bg-black/70 z-50 flex items-center justify-center p-4" onClick={onClose}>
      <div
        className="bg-[#111827] border border-[#1e2a3a] rounded-xl w-full max-w-3xl max-h-[85vh] flex flex-col shadow-2xl"
        onClick={e => e.stopPropagation()}
      >
        <div className="flex items-center justify-between px-5 py-4 border-b border-[#1e2a3a]">
          <div>
            <h2 className="text-white font-semibold text-sm">Draft Preview</h2>
            <p className="text-[#555] text-xs mt-0.5">Review before saving to {siteId === 1 ? 'AV Beat' : 'AV Beat'}</p>
          </div>
          <button onClick={onClose} className="text-[#555] hover:text-white transition-colors text-lg leading-none">✕</button>
        </div>

        <div className="flex items-center gap-4 px-5 py-3 bg-[#0d1117] border-b border-[#1e2a3a]">
          <div className="flex items-center gap-2">
            <span className="text-[#555] text-xs">Byline:</span>
            <span className="text-white text-xs font-medium">{penName}</span>
          </div>
          <div className="flex items-center gap-2">
            <span className="text-[#555] text-xs">Site:</span>
            <span className={`text-xs font-bold px-1.5 py-0.5 rounded ${siteId === 2 ? 'bg-orange-900/40 text-orange-400' : 'bg-blue-900/40 text-blue-400'}`}>
              {siteId === 2 ? 'AV Beat' : 'AV Beat'}
            </span>
          </div>
          <div className="flex items-center gap-2">
            <span className="text-[#555] text-xs">Words:</span>
            <span className="text-[#aaa] text-xs">{wordCount}</span>
          </div>
          <div className="flex items-center gap-2">
            <span className="text-[#555] text-xs">Status:</span>
            <span className="text-yellow-400 text-xs">Draft</span>
          </div>
        </div>

        <div className="px-5 py-3 border-b border-[#1e2a3a]">
          <p className="text-[#555] text-xs mb-1">Title</p>
          <p className="text-white text-base font-semibold">{title || 'Untitled Draft'}</p>
        </div>

        <div className="flex-1 overflow-y-auto px-5 py-4">
          <div
            className="prose-sm text-[#ccc] text-sm leading-relaxed"
            dangerouslySetInnerHTML={{
              __html: `<p class="mb-3 text-[#ccc] leading-relaxed">${renderMarkdown(content)}</p>`,
            }}
          />
        </div>

        <div className="flex items-center justify-between px-5 py-4 border-t border-[#1e2a3a] bg-[#0d1117] rounded-b-xl">
          <button onClick={onClose} className="text-[#555] hover:text-[#aaa] text-sm transition-colors">Cancel</button>
          <div className="flex gap-3">
            <button
              onClick={() => onSave(false)}
              className="bg-[#1e2a3a] hover:bg-[#253347] text-[#aaa] hover:text-white text-sm px-4 py-2 rounded-lg transition-colors border border-[#2a3a50]"
            >
              Save as Draft
            </button>
            <button
              onClick={() => onSave(true)}
              className="bg-[#1D4ED8] hover:bg-[#1E3A8A] text-white text-sm px-4 py-2 rounded-lg transition-colors font-medium"
            >
              Open in Editor →
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─── Regenerate Modal ──────────────────────────────────────────────────────────
interface RegenerateModalProps {
  onClose: () => void;
  onRegenerate: (prompt: string) => void;
}

function RegenerateModal({ onClose, onRegenerate }: RegenerateModalProps) {
  const [customPrompt, setCustomPrompt] = useState('');
  const [selectedVariant, setSelectedVariant] = useState<string | null>(null);

  const variants = [
    { label: 'Different angle', prompt: 'Regenerate this with a completely different angle and approach.' },
    { label: 'More technical', prompt: 'Regenerate this with more technical depth and engineering detail.' },
    { label: 'More concise', prompt: 'Regenerate this as a shorter, more concise version (under 300 words).' },
    { label: 'More conversational', prompt: 'Regenerate this with a more conversational, accessible tone.' },
    { label: 'Lead with data', prompt: 'Regenerate this leading with industry data, statistics, or market context.' },
    { label: 'Stronger headline', prompt: 'Keep the same content but rewrite with a stronger, more compelling headline and opening paragraph.' },
    { label: 'Add quotes', prompt: 'Regenerate this and add realistic attributed quotes from company executives.' },
    { label: 'SEO optimized', prompt: 'Regenerate this with stronger SEO optimization — include keyword-rich subheadings and a meta description.' },
  ];

  const handleSubmit = () => {
    const prompt = customPrompt.trim() || selectedVariant || 'Please regenerate the previous response with a different approach.';
    onRegenerate(prompt);
    onClose();
  };

  return (
    <div className="fixed inset-0 bg-black/70 z-50 flex items-center justify-center p-4" onClick={onClose}>
      <div
        className="bg-[#111827] border border-[#1e2a3a] rounded-xl w-full max-w-lg shadow-2xl"
        onClick={e => e.stopPropagation()}
      >
        <div className="flex items-center justify-between px-5 py-4 border-b border-[#1e2a3a]">
          <h2 className="text-white font-semibold text-sm">Regenerate with Different Prompt</h2>
          <button onClick={onClose} className="text-[#555] hover:text-white transition-colors text-lg leading-none">✕</button>
        </div>

        <div className="p-5 space-y-4">
          <div>
            <p className="text-[#555] text-xs mb-2 uppercase tracking-wider font-bold">Quick Variants</p>
            <div className="grid grid-cols-2 gap-2">
              {variants.map(v => (
                <button
                  key={v.label}
                  onClick={() => { setSelectedVariant(v.prompt); setCustomPrompt(''); }}
                  className={`text-left text-xs px-3 py-2 rounded border transition-colors ${
                    selectedVariant === v.prompt
                      ? 'border-[#1D4ED8] bg-[#DCE6F2] text-white'
                      : 'border-[#1e2a3a] text-[#aaa] hover:border-[#2a3a50] hover:text-white hover:bg-[#161f2e]'
                  }`}
                >
                  {v.label}
                </button>
              ))}
            </div>
          </div>

          <div>
            <p className="text-[#555] text-xs mb-2 uppercase tracking-wider font-bold">Or Write Custom Instructions</p>
            <textarea
              value={customPrompt}
              onChange={e => { setCustomPrompt(e.target.value); setSelectedVariant(null); }}
              placeholder="e.g. Rewrite this focusing on the European market impact..."
              rows={3}
              className="w-full bg-[#0d1117] border border-[#1e2a3a] text-white text-sm rounded-lg px-3 py-2 focus:outline-none focus:border-[#1D4ED8] placeholder-[#333] resize-none"
            />
          </div>

          {(selectedVariant || customPrompt.trim()) && (
            <div className="bg-[#0d1117] border border-[#1e2a3a] rounded-lg px-3 py-2">
              <p className="text-[#555] text-[10px] mb-1 uppercase tracking-wider">Will send:</p>
              <p className="text-[#aaa] text-xs italic">{customPrompt.trim() || selectedVariant}</p>
            </div>
          )}
        </div>

        <div className="flex items-center justify-between px-5 py-4 border-t border-[#1e2a3a] bg-[#0d1117] rounded-b-xl">
          <button onClick={onClose} className="text-[#555] hover:text-[#aaa] text-sm transition-colors">Cancel</button>
          <button
            onClick={handleSubmit}
            className="bg-[#1D4ED8] hover:bg-[#1E3A8A] text-white text-sm px-4 py-2 rounded-lg transition-colors font-medium"
          >
            Regenerate ↺
          </button>
        </div>
      </div>
    </div>
  );
}

// ─── Style Guides Panel ────────────────────────────────────────────────────────
interface StyleGuidesPanelProps {
  onClose: () => void;
  onSelectPenName: (name: string) => void;
}

function StyleGuidesPanel({ onClose, onSelectPenName }: StyleGuidesPanelProps) {
  const [leftPen, setLeftPen] = useState<PenNameProfile>(PEN_NAME_PROFILES[0]);
  const [rightPen, setRightPen] = useState<PenNameProfile>(PEN_NAME_PROFILES[12]);
  const [filterSite, setFilterSite] = useState<'ALL' | 'BB' | 'AV'>('ALL');

  const filtered = PEN_NAME_PROFILES.filter(p => filterSite === 'ALL' || p.site === filterSite);

  const PenCard = ({ profile, side }: { profile: PenNameProfile; side: 'left' | 'right' }) => (
    <div className="flex-1 min-w-0 flex flex-col">
      <div className="mb-3">
        <select
          value={profile.name}
          onChange={e => {
            const found = PEN_NAME_PROFILES.find(p => p.name === e.target.value);
            if (found) side === 'left' ? setLeftPen(found) : setRightPen(found);
          }}
          className="w-full bg-[#0d1117] border border-[#1e2a3a] text-white text-sm rounded px-2 py-1.5 focus:outline-none focus:border-[#1D4ED8]"
        >
          {PEN_NAME_PROFILES.map(p => (
            <option key={p.name} value={p.name}>{p.name} ({p.site})</option>
          ))}
        </select>
      </div>

      <div className="bg-[#0d1117] border border-[#1e2a3a] rounded-lg p-4 flex-1 space-y-3">
        <div>
          <div className="flex items-center gap-2 mb-1">
            <span className={`text-[10px] font-bold px-1.5 py-0.5 rounded ${profile.site === 'AV' ? 'bg-orange-900/40 text-orange-400' : 'bg-blue-900/40 text-blue-400'}`}>
              {profile.site}
            </span>
            <span className="text-white font-semibold text-sm">{profile.name}</span>
          </div>
          <p className="text-[#1D4ED8] text-xs">{profile.title}</p>
        </div>

        <div>
          <p className="text-[#555] text-[10px] uppercase tracking-wider font-bold mb-1">Beat</p>
          <p className="text-[#aaa] text-xs leading-relaxed">{profile.beat}</p>
        </div>

        <div>
          <p className="text-[#555] text-[10px] uppercase tracking-wider font-bold mb-1">Writing Style</p>
          <p className="text-[#ccc] text-xs leading-relaxed">{profile.styleNotes}</p>
        </div>

        <div>
          <p className="text-[#555] text-[10px] uppercase tracking-wider font-bold mb-1">Tone Keywords</p>
          <div className="flex flex-wrap gap-1">
            {profile.toneKeywords.map(kw => (
              <span key={kw} className="text-[10px] bg-[#1e2a3a] text-[#aaa] px-2 py-0.5 rounded-full border border-[#2a3a50]">{kw}</span>
            ))}
          </div>
        </div>

        <div>
          <p className="text-[#555] text-[10px] uppercase tracking-wider font-bold mb-1">Example Lead</p>
          <p className="text-[#aaa] text-xs italic leading-relaxed border-l-2 border-[#1D4ED8]/40 pl-3">"{profile.exampleLead}"</p>
        </div>

        <button
          onClick={() => onSelectPenName(profile.name)}
          className="w-full text-xs bg-[#1e2a3a] hover:bg-[#253347] text-[#aaa] hover:text-white border border-[#2a3a50] px-3 py-2 rounded-lg transition-colors"
        >
          Use {profile.name} as Byline
        </button>
      </div>
    </div>
  );

  return (
    <div className="fixed inset-0 bg-black/70 z-50 flex items-center justify-center p-4" onClick={onClose}>
      <div
        className="bg-[#111827] border border-[#1e2a3a] rounded-xl w-full max-w-5xl max-h-[90vh] flex flex-col shadow-2xl"
        onClick={e => e.stopPropagation()}
      >
        <div className="flex items-center justify-between px-5 py-4 border-b border-[#1e2a3a]">
          <div className="flex items-center gap-4">
            <h2 className="text-white font-semibold text-sm">Pen Name Style Guides</h2>
            <div className="flex gap-1">
              {(['ALL', 'BB', 'AV'] as const).map(f => (
                <button
                  key={f}
                  onClick={() => setFilterSite(f)}
                  className={`text-xs px-2.5 py-1 rounded transition-colors ${filterSite === f ? 'bg-[#1D4ED8] text-white' : 'bg-[#1e2a3a] text-[#aaa] hover:text-white'}`}
                >
                  {f === 'ALL' ? 'All Writers' : f === 'BB' ? 'AV Beat' : 'AV Beat'}
                </button>
              ))}
            </div>
          </div>
          <button onClick={onClose} className="text-[#555] hover:text-white transition-colors text-lg leading-none">✕</button>
        </div>

        <div className="p-5 flex-1 overflow-y-auto">
          <p className="text-[#555] text-xs mb-4">Compare two pen name styles side by side. Select a writer from each dropdown.</p>
          <div className="flex gap-5">
            <PenCard profile={leftPen} side="left" />
            <div className="w-px bg-[#1e2a3a] flex-shrink-0" />
            <PenCard profile={rightPen} side="right" />
          </div>

          <div className="mt-6 pt-5 border-t border-[#1e2a3a]">
            <p className="text-[#555] text-xs uppercase tracking-wider font-bold mb-3">All Writers Quick Reference</p>
            <div className="grid grid-cols-2 gap-2">
              {filtered.map(p => (
                <button
                  key={p.name}
                  onClick={() => setLeftPen(p)}
                  className="text-left p-2.5 rounded border border-[#1e2a3a] hover:border-[#2a3a50] hover:bg-[#161f2e] transition-colors group"
                >
                  <div className="flex items-center gap-2 mb-0.5">
                    <span className={`text-[9px] font-bold px-1 rounded ${p.site === 'AV' ? 'bg-orange-900/40 text-orange-400' : 'bg-blue-900/40 text-blue-400'}`}>{p.site}</span>
                    <span className="text-white text-xs font-medium group-hover:text-[#1D4ED8] transition-colors">{p.name}</span>
                  </div>
                  <p className="text-[#555] text-[10px]">{p.title}</p>
                </button>
              ))}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─── Response History Sidebar ──────────────────────────────────────────────────
interface ResponseHistorySidebarProps {
  messages: Message[];
  onJumpTo: (msgId: string) => void;
  onClose: () => void;
}

function ResponseHistorySidebar({ messages, onJumpTo, onClose }: ResponseHistorySidebarProps) {
  const assistantMessages = messages.filter(m => m.role === 'assistant' && m.content);

  return (
    <div className="w-72 flex-shrink-0 bg-[#111827] border-l border-[#1e2a3a] flex flex-col overflow-hidden">
      <div className="flex items-center justify-between px-4 py-3 border-b border-[#1e2a3a]">
        <h2 className="text-[#555] text-xs font-bold uppercase tracking-widest">Response History</h2>
        <button onClick={onClose} className="text-[#555] hover:text-[#aaa] text-xs transition-colors">✕</button>
      </div>

      {assistantMessages.length === 0 ? (
        <div className="p-4 text-center">
          <p className="text-[#444] text-xs">No responses yet in this session</p>
        </div>
      ) : (
        <div className="flex-1 overflow-y-auto p-3 space-y-2">
          {assistantMessages.map((msg, idx) => {
            const preview = msg.content.replace(/<[^>]+>/g, '').slice(0, 120);
            const wordCount = msg.content.split(/\s+/).filter(Boolean).length;
            return (
              <button
                key={msg.id}
                onClick={() => onJumpTo(msg.id)}
                className="w-full text-left p-3 rounded border border-[#1e2a3a] hover:border-[#2a3a50] hover:bg-[#161f2e] transition-colors group"
              >
                <div className="flex items-center justify-between mb-1">
                  <span className="text-[10px] text-[#1D4ED8] font-bold">Response #{idx + 1}</span>
                  <span className={`w-1.5 h-1.5 rounded-full flex-shrink-0 ${msg.provider === 'ollama' ? 'bg-green-500' : 'bg-yellow-500'}`} />
                </div>
                <p className="text-[#aaa] text-xs line-clamp-3 leading-relaxed">{preview}…</p>
                <div className="flex items-center gap-3 mt-2">
                  <span className="text-[10px] text-[#444]">{msg.timestamp.toLocaleTimeString()}</span>
                  <span className="text-[10px] text-[#444]">{wordCount} words</span>
                  <span className="text-[10px] text-[#1D4ED8] opacity-0 group-hover:opacity-100 transition-opacity">Jump ↑</span>
                </div>
              </button>
            );
          })}
        </div>
      )}

      {assistantMessages.length > 0 && (
        <div className="p-3 border-t border-[#1e2a3a]">
          <p className="text-[#444] text-[10px] text-center">
            {assistantMessages.length} response{assistantMessages.length !== 1 ? 's' : ''} in this session
          </p>
        </div>
      )}
    </div>
  );
}

// ─── Main Component ────────────────────────────────────────────────────────────
export default function AIConsolePage() {
  const { user, loading } = useAuth();
  const router = useRouter();

  const [messages, setMessages] = useState<Message[]>([]);
  const [input, setInput] = useState('');
  const [isStreaming, setIsStreaming] = useState(false);
  const [sessions, setSessions] = useState<Session[]>([]);
  const [currentSessionId, setCurrentSessionId] = useState<string | null>(null);
  const [aiStatus, setAiStatus] = useState<AIStatus | null>(null);
  const [selectedSite, setSelectedSite] = useState<1 | 2>(1);
  const [selectedPenName, setSelectedPenName] = useState('Michael Strand');
  const [urlInput, setUrlInput] = useState('');
  const [showUrlInput, setShowUrlInput] = useState(false);
  const [fetchingUrl, setFetchingUrl] = useState(false);
  const [urlContext, setUrlContext] = useState<{ content: string; domain: string; wordCount: number } | null>(null);
  const [lastResponseContent, setLastResponseContent] = useState('');
  const [lastResponseTitle, setLastResponseTitle] = useState('');
  const [toast, setToast] = useState<{ message: string; type: 'success' | 'error' } | null>(null);

  // New feature states
  const [showHistorySidebar, setShowHistorySidebar] = useState(false);
  const [showRegenerateModal, setShowRegenerateModal] = useState(false);
  const [showStyleGuides, setShowStyleGuides] = useState(false);
  const [showDraftPreview, setShowDraftPreview] = useState(false);

  const messagesEndRef = useRef<HTMLDivElement>(null);
  const messageRefs = useRef<Record<string, HTMLDivElement | null>>({});
  const inputRef = useRef<HTMLTextAreaElement>(null);
  const abortRef = useRef<AbortController | null>(null);

  const showToast = (message: string, type: 'success' | 'error' = 'success') => {
    setToast({ message, type });
    setTimeout(() => setToast(null), 4000);
  };

  useEffect(() => {
    if (!loading && !user) router.push('/login');
  }, [user, loading, router]);

  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if ((e.metaKey || e.ctrlKey) && e.key === 'Enter' && !isStreaming) {
        e.preventDefault();
        handleSend();
      }
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [input, isStreaming]);

  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages]);

  useEffect(() => {
    if (!user) return;
    fetch('/api/ai/console?action=ping')
      .then(r => r.json())
      .then(data => setAiStatus(data))
      .catch(() => {});

    fetch('/api/ai/console-settings', { method: 'PATCH' })
      .then(r => r.json())
      .then(data => setSessions(data.sessions || []))
      .catch(() => {});

    const interval = setInterval(() => {
      fetch('/api/ai/console?action=ping')
        .then(r => r.json())
        .then(data => setAiStatus(data))
        .catch(() => {});
    }, 5 * 60 * 1000);
    return () => clearInterval(interval);
  }, [user]);

  useEffect(() => {
    setSelectedPenName(selectedSite === 1 ? 'Michael Strand' : 'Rex Chandler');
  }, [selectedSite]);

  const penNames = selectedSite === 1 ? BB_PEN_NAMES : AV_PEN_NAMES;

  const buildSystemPrompt = () => {
    const siteName = selectedSite === 1 ? 'AV Beat' : 'AV Beat';
    const siteDesc = selectedSite === 1
      ? 'a professional B2B trade publication for broadcast engineers, production professionals, and industry executives'
      : 'a professional B2B trade publication for AV integrators, technology managers, and AV industry professionals';
    const audience = selectedSite === 1
      ? 'broadcast engineers, production professionals, and industry executives' :'AV integrators, technology managers, and AV industry professionals';
    const availablePenNames = penNames.join(', ');

    return `You are an AI editorial assistant for ${siteName} (${siteDesc}).
You help administrators generate professional industry news stories, press release rewrites, exhibitor previews, social media content, and other editorial content.

When writing stories:
- Write in the style of ${selectedPenName} if specified
- Maintain a professional B2B trade publication tone
- Target audience: ${audience}
- Always write original content — never copy source text
- Keep technical terminology accurate
- Lead with the news hook, not company boilerplate
- Never mention competitor publications

Available pen names for this session: ${availablePenNames}

Respond conversationally and helpfully. If asked to write a story, write the full story unless told otherwise. If asked for options or headlines, provide a numbered list.`;
  };

  const handleSend = async (overrideInput?: string) => {
    const sendInput = overrideInput !== undefined ? overrideInput : input;
    if (!sendInput.trim() || isStreaming) return;

    const userContent = urlContext
      ? `${sendInput}\n\n---\nContent from ${urlContext.domain} (${urlContext.wordCount} words):\n${urlContext.content}`
      : sendInput;

    const userMsg: Message = {
      id: Date.now().toString(),
      role: 'user',
      content: sendInput,
      timestamp: new Date(),
    };

    setMessages(prev => [...prev, userMsg]);
    if (overrideInput === undefined) setInput('');
    setUrlContext(null);
    setShowUrlInput(false);
    setIsStreaming(true);

    let sessionId = currentSessionId;
    if (!sessionId) {
      try {
        const res = await fetch('/api/ai/console-settings', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            action: 'create_session',
            site_id: selectedSite,
            pen_name: selectedPenName,
            first_message: sendInput,
          }),
        });
        const data = await res.json();
        sessionId = data.session?.id || null;
        setCurrentSessionId(sessionId);
      } catch {}
    }

    if (sessionId) {
      fetch('/api/ai/console-settings', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ action: 'save_message', session_id: sessionId, role: 'user', content: sendInput }),
      }).catch(() => {});
    }

    const apiMessages = [
      { role: 'system', content: buildSystemPrompt() },
      ...messages.map(m => ({ role: m.role, content: m.content })),
      { role: 'user', content: userContent },
    ];

    const assistantMsgId = (Date.now() + 1).toString();
    setMessages(prev => [...prev, {
      id: assistantMsgId,
      role: 'assistant',
      content: '',
      timestamp: new Date(),
    }]);

    let fullContent = '';
    let responseProvider: 'ollama' | 'anthropic' = 'anthropic';

    try {
      abortRef.current = new AbortController();
      const response = await fetch('/api/ai/console', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ messages: apiMessages, stream: true, sessionId }),
        signal: abortRef.current.signal,
      });

      if (!response.ok) throw new Error('AI request failed');

      responseProvider = (response.headers.get('X-AI-Provider') as 'ollama' | 'anthropic') || 'anthropic';

      const reader = response.body?.getReader();
      if (!reader) throw new Error('No stream');

      const decoder = new TextDecoder();
      let buffer = '';

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;

        buffer += decoder.decode(value, { stream: true });
        const lines = buffer.split('\n');
        buffer = lines.pop() || '';

        for (const line of lines) {
          if (line.startsWith('data: ')) {
            try {
              const data = JSON.parse(line.slice(6));
              if (data.type === 'chunk' && data.chunk) {
                fullContent += data.chunk;
                setMessages(prev => prev.map(m =>
                  m.id === assistantMsgId
                    ? { ...m, content: fullContent, provider: responseProvider }
                    : m
                ));
              } else if (data.type === 'start' && data.provider) {
                responseProvider = data.provider;
              }
            } catch {}
          }
        }
      }
    } catch (err: any) {
      if (err.name !== 'AbortError') {
        setMessages(prev => prev.map(m =>
          m.id === assistantMsgId
            ? { ...m, content: 'Error: Could not get AI response. Please try again.' }
            : m
        ));
      }
    } finally {
      setIsStreaming(false);
      setLastResponseContent(fullContent);
      const titleMatch = fullContent.match(/^#+ (.+)$/m) || fullContent.match(/^(.{20,80})\n/);
      setLastResponseTitle(titleMatch?.[1] || 'AI Draft');

      if (sessionId && fullContent) {
        fetch('/api/ai/console-settings', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ action: 'save_message', session_id: sessionId, role: 'assistant', content: fullContent, provider: responseProvider }),
        }).catch(() => {});
      }

      fetch('/api/ai/console-settings', { method: 'PATCH' })
        .then(r => r.json())
        .then(data => setSessions(data.sessions || []))
        .catch(() => {});
    }
  };

  const handleFetchUrl = async () => {
    if (!urlInput.trim()) return;
    setFetchingUrl(true);
    try {
      const res = await fetch('/api/ai/fetch-url', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ url: urlInput }),
      });
      const data = await res.json();
      if (data.error) throw new Error(data.error);
      setUrlContext({ content: data.content, domain: data.domain, wordCount: data.wordCount });
      setUrlInput('');
      setShowUrlInput(false);
      showToast(`Added content from ${data.domain} (${data.wordCount} words) to context`);
    } catch (err: any) {
      showToast(err.message || 'Failed to fetch URL', 'error');
    } finally {
      setFetchingUrl(false);
    }
  };

  const handleSaveDraft = async (openEditor = false) => {
    if (!lastResponseContent) return;
    setShowDraftPreview(false);
    try {
      const res = await fetch('/api/ai/console-settings', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          action: 'save_draft',
          title: lastResponseTitle,
          content: `<p>${lastResponseContent.replace(/\n\n/g, '</p><p>').replace(/\n/g, '<br/>')}</p>`,
          pen_name: selectedPenName,
          site_id: selectedSite,
        }),
      });
      const data = await res.json();
      if (data.draft) {
        showToast('Saved as draft');
        if (openEditor) router.push(`/admin/articles?draft=${data.draft.id}`);
      }
    } catch {
      showToast('Failed to save draft', 'error');
    }
  };

  const handleDeleteSession = async (sessionId: string) => {
    await fetch('/api/ai/console-settings', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ action: 'delete_session', session_id: sessionId }),
    });
    setSessions(prev => prev.filter(s => s.id !== sessionId));
    if (currentSessionId === sessionId) {
      setCurrentSessionId(null);
      setMessages([]);
    }
  };

  const handleNewSession = () => {
    setCurrentSessionId(null);
    setMessages([]);
    setLastResponseContent('');
    setLastResponseTitle('');
    setUrlContext(null);
    setShowHistorySidebar(false);
    inputRef.current?.focus();
  };

  const handleJumpToMessage = (msgId: string) => {
    const el = messageRefs.current[msgId];
    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });
  };

  const getStatusDot = () => {
    if (!aiStatus) return { color: 'bg-gray-500', label: 'Checking...' };
    if (aiStatus.ollama.online) return { color: 'bg-green-500', label: `Local Ollama (${aiStatus.ollama.latencyMs}ms)` };
    if (aiStatus.anthropic.configured) return { color: 'bg-yellow-500', label: 'Cloud AI (Anthropic)' };
    return { color: 'bg-red-500', label: 'No AI available' };
  };

  const statusDot = getStatusDot();
  const isFailover = aiStatus && !aiStatus.ollama.online && aiStatus.anthropic.configured;
  const assistantMessageCount = messages.filter(m => m.role === 'assistant' && m.content).length;

  if (loading) return null;

  return (
    <div className="min-h-screen bg-[#0d1117] flex flex-col">
      {/* Header */}
      <div className="bg-[#111827] border-b border-[#1e2a3a] px-4 py-3 flex items-center justify-between">
        <div className="flex items-center gap-3">
          <Link href="/admin" className="text-[#555] hover:text-[#1D4ED8] text-sm transition-colors">← Dashboard</Link>
          <span className="text-[#333]">/</span>
          <h1 className="text-white font-bold text-sm tracking-wide">AI Console</h1>
        </div>
        <div className="flex items-center gap-3">
          <button
            onClick={() => setShowStyleGuides(true)}
            className="text-xs text-[#555] hover:text-[#aaa] bg-[#1e2a3a] hover:bg-[#253347] border border-[#2a3a50] px-2.5 py-1.5 rounded transition-colors"
            title="View pen name style guides side by side"
          >
            Style Guides
          </button>
          <button
            onClick={() => setShowHistorySidebar(v => !v)}
            className={`text-xs px-2.5 py-1.5 rounded border transition-colors ${
              showHistorySidebar
                ? 'bg-[#DCE6F2] border-[#1D4ED8]/40 text-[#1D4ED8]'
                : 'bg-[#1e2a3a] border-[#2a3a50] text-[#555] hover:text-[#aaa]'
            }`}
            title="Toggle response history sidebar"
          >
            History
            {assistantMessageCount > 0 && (
              <span className="ml-1.5 bg-[#1D4ED8] text-white text-[9px] font-bold px-1 py-0.5 rounded-full">{assistantMessageCount}</span>
            )}
          </button>
          <Link href="/dashboard/ai-console/health" className="text-[#555] hover:text-[#1D4ED8] text-xs transition-colors">Health</Link>
          <Link href="/dashboard/ai-console/settings" className="text-[#555] hover:text-[#1D4ED8] text-xs transition-colors">Settings</Link>
          <button onClick={handleNewSession} className="text-xs bg-[#1e2a3a] hover:bg-[#253347] text-[#aaa] px-3 py-1.5 rounded transition-colors">
            + New Session
          </button>
        </div>
      </div>

      {/* Failover banner */}
      {isFailover && (
        <div className="bg-yellow-900/30 border-b border-yellow-700/40 px-4 py-2 text-center">
          <span className="text-yellow-400 text-xs">⚠ Using cloud AI — local server unavailable</span>
        </div>
      )}

      <div className="flex flex-1 overflow-hidden">
        {/* LEFT PANEL */}
        <div className="w-72 flex-shrink-0 bg-[#111827] border-r border-[#1e2a3a] flex flex-col overflow-y-auto">
          {/* Quick Actions */}
          <div className="p-4 border-b border-[#1e2a3a]">
            <h2 className="text-[#555] text-xs font-bold uppercase tracking-widest mb-3">Quick Actions</h2>
            <div className="space-y-1">
              {QUICK_ACTIONS.map(action => (
                <button
                  key={action.key}
                  onClick={() => {
                    setInput(QUICK_ACTION_TEMPLATES[action.key] || '');
                    inputRef.current?.focus();
                  }}
                  className="w-full text-left text-xs text-[#aaa] hover:text-white hover:bg-[#1e2a3a] px-3 py-2 rounded transition-colors"
                >
                  {action.label}
                </button>
              ))}
            </div>
          </div>

          {/* Recent Sessions */}
          <div className="p-4 border-b border-[#1e2a3a] flex-1">
            <h2 className="text-[#555] text-xs font-bold uppercase tracking-widest mb-3">Recent Sessions</h2>
            {sessions.length === 0 ? (
              <p className="text-[#444] text-xs">No sessions yet</p>
            ) : (
              <div className="space-y-2">
                {sessions.map(session => (
                  <div
                    key={session.id}
                    className={`group p-2.5 rounded border cursor-pointer transition-colors ${
                      currentSessionId === session.id
                        ? 'border-[#1D4ED8]/40 bg-[#1e2a3a]'
                        : 'border-[#1e2a3a] hover:border-[#2a3a50] hover:bg-[#161f2e]'
                    }`}
                  >
                    <div className="flex items-start justify-between gap-1">
                      <p className="text-xs text-[#aaa] line-clamp-2 flex-1">{session.first_message_preview || 'Session'}</p>
                      <button
                        onClick={(e) => { e.stopPropagation(); handleDeleteSession(session.id); }}
                        className="text-[#333] hover:text-red-400 opacity-0 group-hover:opacity-100 transition-all text-xs flex-shrink-0"
                        title="Delete session"
                      >✕</button>
                    </div>
                    <div className="flex items-center gap-2 mt-1">
                      <span className={`text-[10px] px-1 rounded font-bold ${session.site_id === 2 ? 'bg-orange-900/40 text-orange-400' : 'bg-blue-900/40 text-blue-400'}`}>
                        {session.site_id === 2 ? 'AV' : 'BB'}
                      </span>
                      <span className="text-[10px] text-[#444]">
                        {new Date(session.last_message_at).toLocaleDateString()}
                      </span>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>

          {/* AI Status */}
          <div className="p-4">
            <h2 className="text-[#555] text-xs font-bold uppercase tracking-widest mb-3">AI Status</h2>
            <div className="flex items-center gap-2 mb-2">
              <div className={`w-2.5 h-2.5 rounded-full ${statusDot.color} flex-shrink-0`} />
              <span className="text-xs text-[#aaa]">{statusDot.label}</span>
            </div>
            {aiStatus?.ollama.models && aiStatus.ollama.models.length > 0 && (
              <div className="text-[10px] text-[#444] mb-2">
                Models: {aiStatus.ollama.models.slice(0, 3).join(', ')}
                {aiStatus.ollama.models.length > 3 && ` +${aiStatus.ollama.models.length - 3} more`}
              </div>
            )}
            <div className="flex gap-2 mt-2">
              <button
                onClick={() => {
                  fetch('/api/ai/console?action=ping').then(r => r.json()).then(setAiStatus).catch(() => {});
                }}
                className="text-[10px] text-[#555] hover:text-[#1D4ED8] transition-colors"
              >
                Refresh
              </button>
              <Link href="/dashboard/ai-console/health" className="text-[10px] text-[#555] hover:text-[#1D4ED8] transition-colors">
                Health Dashboard →
              </Link>
            </div>
          </div>
        </div>

        {/* CENTER — Chat */}
        <div className="flex-1 flex flex-col overflow-hidden min-w-0">
          {/* Site + Pen Name selectors */}
          <div className="bg-[#0d1117] border-b border-[#1e2a3a] px-4 py-2 flex items-center gap-4">
            <div className="flex items-center gap-2">
              <span className="text-[#555] text-xs">Publish to:</span>
              <select
                value={selectedSite}
                onChange={e => setSelectedSite(Number(e.target.value) as 1 | 2)}
                className="bg-[#1e2a3a] border border-[#2a3a50] text-white text-xs rounded px-2 py-1 focus:outline-none focus:border-[#1D4ED8]"
              >
                <option value={1}>AV Beat</option>
                <option value={2}>AV Beat</option>
              </select>
            </div>
            <div className="flex items-center gap-2">
              <span className="text-[#555] text-xs">Byline:</span>
              <select
                value={selectedPenName}
                onChange={e => setSelectedPenName(e.target.value)}
                className="bg-[#1e2a3a] border border-[#2a3a50] text-white text-xs rounded px-2 py-1 focus:outline-none focus:border-[#1D4ED8]"
              >
                {penNames.map(name => (
                  <option key={name} value={name}>{name}</option>
                ))}
              </select>
            </div>
            <button
              onClick={() => setShowStyleGuides(true)}
              className="text-[10px] text-[#1D4ED8] hover:text-[#1D4ED8] transition-colors ml-auto"
            >
              View style guide →
            </button>
          </div>

          {/* Messages */}
          <div className="flex-1 overflow-y-auto px-6 py-4 space-y-4">
            {messages.length === 0 && (
              <div className="flex flex-col items-center justify-center h-full text-center">
                <div className="w-12 h-12 rounded-full bg-[#1e2a3a] flex items-center justify-center mb-4">
                  <span className="text-2xl">✦</span>
                </div>
                <h2 className="text-white font-semibold mb-2">AI Editorial Console</h2>
                <p className="text-[#555] text-sm max-w-md">
                  Generate stories, headlines, social posts, and more. Use Quick Actions on the left or type your request below.
                </p>
                <p className="text-[#333] text-xs mt-3">Cmd+Enter to send · Cmd+Shift+A to open from anywhere</p>
              </div>
            )}

            {messages.map((msg, idx) => (
              <div
                key={msg.id}
                ref={el => { messageRefs.current[msg.id] = el; }}
                className={`flex ${msg.role === 'user' ? 'justify-end' : 'justify-start'}`}
              >
                <div className={`max-w-[80%] ${msg.role === 'user' ? 'order-2' : 'order-1'}`}>
                  {msg.role === 'assistant' && (
                    <div className="flex items-center gap-2 mb-1">
                      <div className={`w-1.5 h-1.5 rounded-full ${msg.provider === 'ollama' ? 'bg-green-500' : 'bg-yellow-500'}`} />
                      <span className="text-[10px] text-[#444]">
                        {msg.provider === 'ollama' ? 'Local AI' : 'Cloud AI'} · {msg.timestamp.toLocaleTimeString()}
                      </span>
                    </div>
                  )}
                  <div className={`rounded-lg px-4 py-3 ${
                    msg.role === 'user' ?'bg-[#DCE6F2] text-white text-sm' :'bg-[#111827] border border-[#1e2a3a] text-[#ccc] text-sm'
                  }`}>
                    {msg.role === 'user' ? (
                      <p className="whitespace-pre-wrap">{msg.content}</p>
                    ) : (
                      <div
                        className="prose-sm"
                        dangerouslySetInnerHTML={{
                          __html: `<p class="mb-3 text-[#ccc] leading-relaxed">${renderMarkdown(msg.content)}</p>`,
                        }}
                      />
                    )}
                    {msg.role === 'user' && (
                      <p className="text-[10px] text-[#4a6a8a] mt-1 text-right">{msg.timestamp.toLocaleTimeString()}</p>
                    )}
                  </div>

                  {/* Post-response action bar */}
                  {msg.role === 'assistant' && idx === messages.length - 1 && !isStreaming && msg.content && (
                    <div className="flex items-center gap-2 mt-2 flex-wrap">
                      <button
                        onClick={() => navigator.clipboard.writeText(msg.content).then(() => showToast('Copied'))}
                        className="text-[10px] text-[#555] hover:text-[#aaa] bg-[#111827] border border-[#1e2a3a] px-2 py-1 rounded transition-colors"
                      >
                        Copy
                      </button>
                      <button
                        onClick={() => setShowDraftPreview(true)}
                        className="text-[10px] text-[#1D4ED8] hover:text-[#1D4ED8] bg-[#111827] border border-[#1D4ED8]/30 px-2 py-1 rounded transition-colors font-medium"
                      >
                        Preview Draft
                      </button>
                      <button
                        onClick={() => handleSaveDraft(false)}
                        className="text-[10px] text-[#555] hover:text-[#aaa] bg-[#111827] border border-[#1e2a3a] px-2 py-1 rounded transition-colors"
                      >
                        Save as Draft
                      </button>
                      <button
                        onClick={() => handleSaveDraft(true)}
                        className="text-[10px] text-[#555] hover:text-[#aaa] bg-[#111827] border border-[#1e2a3a] px-2 py-1 rounded transition-colors"
                      >
                        Open in Editor
                      </button>
                      <button
                        onClick={() => setShowRegenerateModal(true)}
                        className="text-[10px] text-[#555] hover:text-[#aaa] bg-[#111827] border border-[#1e2a3a] px-2 py-1 rounded transition-colors"
                      >
                        Regenerate ↺
                      </button>
                      <button
                        onClick={() => handleSend('Make the previous response shorter and more concise.')}
                        className="text-[10px] text-[#555] hover:text-[#aaa] bg-[#111827] border border-[#1e2a3a] px-2 py-1 rounded transition-colors"
                      >
                        Make Shorter
                      </button>
                      <button
                        onClick={() => handleSend('Expand the previous response with more detail and depth.')}
                        className="text-[10px] text-[#555] hover:text-[#aaa] bg-[#111827] border border-[#1e2a3a] px-2 py-1 rounded transition-colors"
                      >
                        Make Longer
                      </button>
                    </div>
                  )}
                </div>
              </div>
            ))}

            {isStreaming && messages[messages.length - 1]?.role === 'assistant' && messages[messages.length - 1]?.content === '' && (
              <div className="flex justify-start">
                <div className="bg-[#111827] border border-[#1e2a3a] rounded-lg px-4 py-3">
                  <div className="flex gap-1">
                    <div className="w-1.5 h-1.5 bg-[#1D4ED8] rounded-full animate-bounce" style={{ animationDelay: '0ms' }} />
                    <div className="w-1.5 h-1.5 bg-[#1D4ED8] rounded-full animate-bounce" style={{ animationDelay: '150ms' }} />
                    <div className="w-1.5 h-1.5 bg-[#1D4ED8] rounded-full animate-bounce" style={{ animationDelay: '300ms' }} />
                  </div>
                </div>
              </div>
            )}

            <div ref={messagesEndRef} />
          </div>

          {/* URL context indicator */}
          {urlContext && (
            <div className="mx-4 mb-2 bg-[#1e2a3a] border border-[#2a3a50] rounded px-3 py-2 flex items-center justify-between">
              <span className="text-xs text-[#aaa]">
                📎 Context from <strong className="text-white">{urlContext.domain}</strong> ({urlContext.wordCount} words)
              </span>
              <button onClick={() => setUrlContext(null)} className="text-[#555] hover:text-red-400 text-xs ml-2">✕</button>
            </div>
          )}

          {/* URL input */}
          {showUrlInput && (
            <div className="mx-4 mb-2 flex gap-2">
              <input
                type="url"
                value={urlInput}
                onChange={e => setUrlInput(e.target.value)}
                onKeyDown={e => e.key === 'Enter' && handleFetchUrl()}
                placeholder="https://example.com/press-release"
                className="flex-1 bg-[#1e2a3a] border border-[#2a3a50] text-white text-sm rounded px-3 py-2 focus:outline-none focus:border-[#1D4ED8] placeholder-[#444]"
                autoFocus
              />
              <button
                onClick={handleFetchUrl}
                disabled={fetchingUrl}
                className="bg-[#1D4ED8] hover:bg-[#1E3A8A] text-white text-xs px-3 py-2 rounded transition-colors disabled:opacity-50"
              >
                {fetchingUrl ? 'Fetching...' : 'Add'}
              </button>
              <button onClick={() => setShowUrlInput(false)} className="text-[#555] hover:text-[#aaa] text-xs px-2">✕</button>
            </div>
          )}

          {/* Input area */}
          <div className="border-t border-[#1e2a3a] bg-[#0d1117] p-4">
            <div className="flex gap-2 mb-2">
              <button
                onClick={() => setShowUrlInput(!showUrlInput)}
                className="text-xs text-[#555] hover:text-[#1D4ED8] bg-[#111827] border border-[#1e2a3a] px-2 py-1 rounded transition-colors"
              >
                + Add URL
              </button>
              <button
                onClick={() => setInput(prev => prev + '\n\n[Paste story content here for reference]')}
                className="text-xs text-[#555] hover:text-[#1D4ED8] bg-[#111827] border border-[#1e2a3a] px-2 py-1 rounded transition-colors"
              >
                + Add Story
              </button>
              <button
                onClick={() => setInput(prev => prev + `\n\nWrite in the style of ${selectedPenName}.`)}
                className="text-xs text-[#555] hover:text-[#1D4ED8] bg-[#111827] border border-[#1e2a3a] px-2 py-1 rounded transition-colors"
              >
                + Add Style
              </button>
            </div>
            <div className="flex gap-3">
              <textarea
                ref={inputRef}
                value={input}
                onChange={e => setInput(e.target.value)}
                onKeyDown={e => {
                  if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {
                    e.preventDefault();
                    handleSend();
                  }
                }}
                placeholder="Ask the AI to write a story, generate headlines, translate content..."
                rows={3}
                className="flex-1 bg-[#111827] border border-[#1e2a3a] text-white text-sm rounded-lg px-4 py-3 focus:outline-none focus:border-[#1D4ED8] placeholder-[#333] resize-none"
              />
              <div className="flex flex-col gap-2">
                <button
                  onClick={() => handleSend()}
                  disabled={isStreaming || !input.trim()}
                  className="bg-[#1D4ED8] hover:bg-[#1E3A8A] disabled:opacity-40 disabled:cursor-not-allowed text-white text-sm px-4 py-2 rounded-lg transition-colors font-medium flex-1"
                >
                  {isStreaming ? (
                    <span className="flex items-center gap-1">
                      <span className="w-3 h-3 border-2 border-white/30 border-t-white rounded-full animate-spin" />
                    </span>
                  ) : 'Send'}
                </button>
                {isStreaming && (
                  <button
                    onClick={() => abortRef.current?.abort()}
                    className="text-xs text-[#555] hover:text-red-400 bg-[#111827] border border-[#1e2a3a] px-2 py-1 rounded transition-colors"
                  >
                    Stop
                  </button>
                )}
              </div>
            </div>
            <p className="text-[#333] text-[10px] mt-1.5">Cmd+Enter to send</p>
          </div>
        </div>

        {/* RIGHT — Response History Sidebar */}
        {showHistorySidebar && (
          <ResponseHistorySidebar
            messages={messages}
            onJumpTo={handleJumpToMessage}
            onClose={() => setShowHistorySidebar(false)}
          />
        )}
      </div>

      {/* Toast */}
      {toast && (
        <div className={`fixed bottom-6 right-6 px-4 py-3 rounded-lg text-sm font-medium shadow-lg z-50 transition-all ${
          toast.type === 'error' ? 'bg-red-900 text-red-200 border border-red-700' : 'bg-green-900 text-green-200 border border-green-700'
        }`}>
          {toast.message}
        </div>
      )}

      {/* Modals */}
      {showDraftPreview && lastResponseContent && (
        <DraftPreviewModal
          content={lastResponseContent}
          title={lastResponseTitle}
          penName={selectedPenName}
          siteId={selectedSite}
          onClose={() => setShowDraftPreview(false)}
          onSave={handleSaveDraft}
        />
      )}

      {showRegenerateModal && (
        <RegenerateModal
          onClose={() => setShowRegenerateModal(false)}
          onRegenerate={(prompt) => handleSend(prompt)}
        />
      )}

      {showStyleGuides && (
        <StyleGuidesPanel
          onClose={() => setShowStyleGuides(false)}
          onSelectPenName={(name) => {
            setSelectedPenName(name);
            setShowStyleGuides(false);
            showToast(`Byline set to ${name}`);
          }}
        />
      )}
    </div>
  );
}
