import React, { useState, useEffect, useCallback } from 'react';
import { createRoot } from 'react-dom/client';

// ============================================================================
// CONFIGURATION
// ============================================================================
const CONFIG = {
  APP_NAME: 'Recex Voice AI',
  BACKEND_URL: '/api',
};

// ============================================================================
// FIREBASE CONFIGURATION
// ============================================================================
// TODO: Replace with your Firebase config from Firebase Console
const FIREBASE_CONFIG = {
  apiKey: "AIzaSyD4wcDdFod7TPvTvb8yaK04warWl7qYjpM",
  authDomain: "recex-voice-ai.firebaseapp.com",
  projectId: "recex-voice-ai",
  storageBucket: "recex-voice-ai.firebasestorage.app",
  messagingSenderId: "406720918394",
  appId: "1:406720918394:web:5506791946adb81ddedcc3"
};

// Check if Firebase is configured
const isFirebaseConfigured = () => FIREBASE_CONFIG.apiKey !== "YOUR_API_KEY";

// Helper to access Firebase from window (avoids TypeScript 'as any' syntax that Babel can't parse)
const getFirebase = (): any => {
  if (typeof window !== 'undefined') {
    return window["firebase"];
  }
  return null;
};

// Initialize Firebase (only if configured)
let firebaseApp: any = null;
let firebaseAuth: any = null;
let firebaseDb: any = null;

const firebase = getFirebase();
if (isFirebaseConfigured() && firebase) {
  firebaseApp = firebase.initializeApp(FIREBASE_CONFIG);
  firebaseAuth = firebase.auth();
  firebaseDb = firebase.firestore();
}

// ============================================================================
// FIREBASE AUTH SERVICE
// ============================================================================
// Helper to get current tenant (subdomain)
const getTenant = (): string => {
  const hostname = window.location.hostname;
  // Handle localhost and IP addresses (no subdomain)
  if (hostname === 'localhost' || hostname.match(/^\d+\.\d+\.\d+\.\d+$/)) {
    return 'demo'; // Default tenant for local development
  }
  // Extract subdomain (e.g., "client1" from "client1.recex-ai.com")
  const parts = hostname.split('.');
  // Skip 'www' prefix if present
  if (parts[0] === 'www') {
    parts.shift();
  }
  if (parts.length >= 3) {
    return parts[0]; // Return subdomain
  }
  return 'demo'; // Default if no subdomain
};

interface AppUser {
  uid: string;
  email: string;
  name: string;
  status: string;
  tenant: string;
  createdAt: any;
}

const authService = {
  // Check if user is signed in
  getCurrentUser: (): any => {
    return firebaseAuth?.currentUser;
  },

  // Sign in with email and password
  signIn: async (email: string, password: string): Promise<any> => {
    if (!firebaseAuth) throw new Error('Firebase not configured');
    return firebaseAuth.signInWithEmailAndPassword(email, password);
  },

  // Sign out
  signOut: async (): Promise<void> => {
    if (!firebaseAuth) {
      localStorage.removeItem('recex_authenticated');
      return;
    }
    return firebaseAuth.signOut();
  },

  // Send password reset email
  sendPasswordReset: async (email: string): Promise<void> => {
    if (!firebaseAuth) throw new Error('Firebase not configured');
    return firebaseAuth.sendPasswordResetEmail(email);
  },

  // Listen to auth state changes
  onAuthStateChanged: (callback: (user: any) => void): (() => void) => {
    if (!firebaseAuth) {
      // Fallback for non-Firebase mode
      const isAuth = localStorage.getItem('recex_authenticated') === 'true';
      callback(isAuth ? { uid: 'local', email: 'admin@local' } : null);
      return () => {};
    }
    return firebaseAuth.onAuthStateChanged(callback);
  },

  // Get user data from Firestore
  getUserData: async (uid: string): Promise<AppUser | null> => {
    if (!firebaseDb) return null;
    const doc = await firebaseDb.collection('users').doc(uid).get();
    if (doc.exists) {
      const data = doc.data();
      return { uid, email: data.email, name: data.name, status: data.status, tenant: data.tenant, createdAt: data.createdAt };
    }
    return null;
  },

  // Verify user belongs to current tenant (subdomain)
  verifyTenant: async (uid: string): Promise<boolean> => {
    if (!firebaseDb) return true; // Allow if no Firebase
    const doc = await firebaseDb.collection('users').doc(uid).get();
    if (!doc.exists) return false;
    const data = doc.data();
    const currentTenant = getTenant();
    return data.tenant === currentTenant;
  },

  // Invite a new user (creates invite record, returns invite link)
  inviteUser: async (email: string, name: string): Promise<string> => {
    if (!firebaseDb) throw new Error('Firebase not configured');

    const tenant = getTenant();

    // Create invite record with tenant
    await firebaseDb.collection('invites').doc(`${tenant}_${email}`).set({
      email,
      name,
      tenant,
      invitedAt: firebase.firestore.FieldValue.serverTimestamp(),
      status: 'pending'
    });

    // Return the invite link (must be opened on same subdomain)
    return `${window.location.origin}?invite=${encodeURIComponent(email)}&name=${encodeURIComponent(name)}`;
  },

  // Complete signup from invite
  completeSignup: async (email: string, password: string, name: string): Promise<any> => {
    if (!firebaseAuth || !firebaseDb) throw new Error('Firebase not configured');

    const tenant = getTenant();
    const inviteId = `${tenant}_${email}`;

    // Verify invite exists for this tenant
    const inviteDoc = await firebaseDb.collection('invites').doc(inviteId).get();
    if (!inviteDoc.exists) {
      throw new Error('Invalid or expired invitation for this domain');
    }
    const inviteData = inviteDoc.data();
    if (inviteData.tenant !== tenant) {
      throw new Error('This invitation is not valid for this domain');
    }
    if (inviteData.status !== 'pending') {
      throw new Error('This invitation has already been used');
    }

    // Create the user
    const userCredential = await firebaseAuth.createUserWithEmailAndPassword(email, password);
    const uid = userCredential.user.uid;

    // Create user document with tenant
    await firebaseDb.collection('users').doc(uid).set({
      email,
      name,
      tenant,
      status: 'active',
      createdAt: firebase.firestore.FieldValue.serverTimestamp()
    });

    // Update invite status
    await firebaseDb.collection('invites').doc(inviteId).update({
      status: 'completed',
      completedAt: firebase.firestore.FieldValue.serverTimestamp(),
      uid
    });

    return userCredential;
  },

  // Get all users (for admin)
  getAllUsers: async (): Promise<AppUser[]> => {
    if (!firebaseDb) return [];
    const tenant = getTenant();
    const snapshot = await firebaseDb.collection('users')
      .where('tenant', '==', tenant)
      .orderBy('createdAt', 'desc')
      .get();
    return snapshot.docs.map((doc: any) => ({ uid: doc.id, ...doc.data() }));
  },

  // Get all pending invites for current tenant
  getPendingInvites: async (): Promise<any[]> => {
    if (!firebaseDb) return [];
    const tenant = getTenant();
    const snapshot = await firebaseDb.collection('invites')
      .where('tenant', '==', tenant)
      .where('status', '==', 'pending')
      .get();
    return snapshot.docs.map((doc: any) => ({ email: doc.data().email, ...doc.data() }));
  },

  // Delete/revoke invite
  revokeInvite: async (email: string): Promise<void> => {
    if (!firebaseDb) throw new Error('Firebase not configured');
    const tenant = getTenant();
    await firebaseDb.collection('invites').doc(`${tenant}_${email}`).delete();
  },

  // Deactivate user
  deactivateUser: async (uid: string): Promise<void> => {
    if (!firebaseDb) throw new Error('Firebase not configured');
    await firebaseDb.collection('users').doc(uid).update({ status: 'inactive' });
  },

  // Reactivate user
  reactivateUser: async (uid: string): Promise<void> => {
    if (!firebaseDb) throw new Error('Firebase not configured');
    await firebaseDb.collection('users').doc(uid).update({ status: 'active' });
  }
};

// ============================================================================
// TYPES
// ============================================================================
interface Agent {
  id: string;
  name: string;
  language: string;
  voice_persona: string;
  persona_name: string;
  status: string;
  agent_prompt?: string;
  introduction?: string;
  objective?: string;
  result_prompt?: string;
  result_schema?: Record<string, string>;
  custom_variables?: string[];
  created_at?: string;
}

interface Call {
  id: string;
  callee_name: string;
  mobile_number: string;
  agent_id: string;
  status: string;
  lifecycle_status: string;
  duration_minutes?: number;
  duration_seconds?: number;
  recording_url?: string;
  result?: Record<string, any>;
  created_at: string;
  started_at?: string;
  ended_at?: string;
  engagement_status?: string;
  answered_by?: string;
  custom_data?: Record<string, string>;
  agent?: { id: string; name: string };
}

// Fixed values from API for filters
const CALL_STATUSES = ['COMPLETED', 'IN_PROGRESS', 'NOT_CONNECTED', 'FAILED', 'SCHEDULED', 'CANCELLED'];
const ENGAGEMENT_STATUSES = ['ENGAGED', 'NOT_ENGAGED'];
const ANSWERED_BY_OPTIONS = ['HUMAN', 'VOICEMAIL', 'UNKNOWN'];

interface Campaign {
  id: string;
  name: string;
  status: string;
  description?: string;
  agent: {
    id: string;
    name: string;
    voice_persona: string;
  };
  total_call_count: number;
  connected_call_count: number;
  not_connected_call_count: number;
  failed_call_count: number;
  engaged_call_count: number;
  not_engaged_call_count: number;
  created_at: string;
  started_at?: string;
  ended_at?: string;
}

type TabType = 'agents' | 'calls' | 'campaigns';
type AgentViewType = 'list' | 'create' | 'edit' | 'view';
type CallViewType = 'history' | 'quick' | 'bulk';
type CampaignViewType = 'list' | 'create' | 'view';

// ============================================================================
// API FUNCTIONS
// ============================================================================
const api = {
  // Agents
  async listAgents(page = 1, pageSize = 20): Promise<{ count: number; results: Agent[] }> {
    const res = await fetch(`${CONFIG.BACKEND_URL}/agents?page=${page}&page_size=${pageSize}`);
    if (!res.ok) throw new Error('Failed to fetch agents');
    return res.json();
  },

  async getAgent(id: string): Promise<Agent> {
    const res = await fetch(`${CONFIG.BACKEND_URL}/agents/${id}`);
    if (!res.ok) throw new Error('Failed to fetch agent');
    return res.json();
  },

  async createAgent(data: Partial<Agent>): Promise<Agent> {
    const res = await fetch(`${CONFIG.BACKEND_URL}/agents`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
    });
    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || err.message || 'Failed to create agent');
    }
    return res.json();
  },

  async updateAgent(id: string, data: Partial<Agent>): Promise<Agent> {
    const res = await fetch(`${CONFIG.BACKEND_URL}/agents/${id}`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
    });
    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || err.message || 'Failed to update agent');
    }
    return res.json();
  },

  // Calls
  async listCalls(params: {
    page?: number;
    pageSize?: number;
    status?: string[];
    engagementStatus?: string[];
    answeredBy?: string[];
    agentId?: string;
    campaignId?: string;
    createdAfter?: string;
    createdBefore?: string;
  }): Promise<{ count: number; results: Call[] }> {
    const searchParams = new URLSearchParams();
    searchParams.set('page', String(params.page || 1));
    searchParams.set('page_size', String(params.pageSize || 100));
    if (params.status?.length) params.status.forEach(s => searchParams.append('status', s));
    if (params.engagementStatus?.length) params.engagementStatus.forEach(s => searchParams.append('engagement_status', s));
    if (params.answeredBy?.length) params.answeredBy.forEach(s => searchParams.append('answered_by', s));
    if (params.agentId) searchParams.set('agent_id', params.agentId);
    if (params.campaignId) searchParams.set('campaign_id', params.campaignId);
    if (params.createdAfter) searchParams.set('created_after', params.createdAfter);
    if (params.createdBefore) searchParams.set('created_before', params.createdBefore);

    const res = await fetch(`${CONFIG.BACKEND_URL}/calls?${searchParams}`);
    if (!res.ok) throw new Error('Failed to fetch calls');
    return res.json();
  },

  // Fetch all calls (for export) - fetches all pages
  async listAllCalls(params: {
    status?: string[];
    engagementStatus?: string[];
    answeredBy?: string[];
    agentId?: string;
    campaignId?: string;
    createdAfter?: string;
    createdBefore?: string;
  }): Promise<Call[]> {
    const allCalls: Call[] = [];
    let page = 1;
    const pageSize = 100;
    let hasMore = true;

    while (hasMore) {
      const data = await this.listCalls({ ...params, page, pageSize });
      allCalls.push(...data.results);
      hasMore = allCalls.length < data.count;
      page++;
      // Safety limit to prevent infinite loops
      if (page > 100) break;
    }

    return allCalls;
  },

  async getCall(id: string): Promise<Call> {
    const res = await fetch(`${CONFIG.BACKEND_URL}/calls/${id}`);
    if (!res.ok) throw new Error('Failed to fetch call');
    return res.json();
  },

  async createCall(data: { agent_id: string; callee_name: string; mobile_number: string; custom_data?: Record<string, string> }): Promise<Call> {
    const res = await fetch(`${CONFIG.BACKEND_URL}/calls`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
    });
    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || err.message || 'Failed to create call');
    }
    return res.json();
  },

  async createBulkCalls(data: { agent_id: string; data: Array<{ callee_name: string; mobile_number: string; custom_data?: Record<string, string> }> }): Promise<Call[]> {
    const res = await fetch(`${CONFIG.BACKEND_URL}/calls/bulk`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
    });
    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || err.message || 'Failed to create bulk calls');
    }
    return res.json();
  },

  // Campaigns
  async listCampaigns(page = 1, pageSize = 20): Promise<{ count: number; results: Campaign[] }> {
    const res = await fetch(`${CONFIG.BACKEND_URL}/campaigns?page=${page}&page_size=${pageSize}`);
    if (!res.ok) throw new Error('Failed to fetch campaigns');
    return res.json();
  },

  async getCampaign(id: string): Promise<Campaign> {
    const res = await fetch(`${CONFIG.BACKEND_URL}/campaigns/${id}`);
    if (!res.ok) throw new Error('Failed to fetch campaign');
    return res.json();
  },

  async createCampaign(formData: FormData): Promise<Campaign> {
    const res = await fetch(`${CONFIG.BACKEND_URL}/campaigns`, {
      method: 'POST',
      body: formData,
    });
    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || err.message || 'Failed to create campaign');
    }
    return res.json();
  },
};

// ============================================================================
// DATE & EXPORT UTILITIES
// ============================================================================
const getDateRange = (range: string): { start: string; end: string } | null => {
  const now = new Date();
  const end = now.toISOString();
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  let start: Date;

  switch (range) {
    case 'today':
      start = today;
      break;
    case 'yesterday':
      start = new Date(today.getTime() - 24 * 60 * 60 * 1000);
      break;
    case '7days':
      start = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
      break;
    case '30days':
      start = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
      break;
    default:
      return null; // No filter
  }

  return { start: start.toISOString(), end };
};

const exportCallsToCSV = (calls: Call[], filename: string, agentsMap?: Map<string, string>) => {
  if (calls.length === 0) {
    alert('No calls to export');
    return;
  }

  const headers = [
    'Call ID',
    'Callee Name',
    'Mobile Number',
    'Agent Name',
    'Status',
    'Lifecycle Status',
    'Duration (minutes)',
    'Duration (seconds)',
    'Engagement Status',
    'Answered By',
    'Created At',
    'Started At',
    'Ended At',
    'Recording URL',
    'Custom Data',
    'Result'
  ];

  const rows = calls.map(call => [
    call.id,
    call.callee_name,
    call.mobile_number,
    call.agent?.name || agentsMap?.get(call.agent_id) || call.agent_id,
    call.status,
    call.lifecycle_status,
    call.duration_minutes?.toFixed(2) || '',
    call.duration_seconds?.toString() || '',
    call.engagement_status || '',
    call.answered_by || '',
    call.created_at,
    call.started_at || '',
    call.ended_at || '',
    call.recording_url || '',
    call.custom_data ? JSON.stringify(call.custom_data) : '',
    call.result ? JSON.stringify(call.result) : ''
  ]);

  const csvContent = [
    headers.join(','),
    ...rows.map(row => row.map(cell => `"${String(cell).replace(/"/g, '""')}"`).join(','))
  ].join('\n');

  const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
  const link = document.createElement('a');
  link.href = URL.createObjectURL(blob);
  link.download = `${filename}_${new Date().toISOString().split('T')[0]}.csv`;
  link.click();
  URL.revokeObjectURL(link.href);
};

// ============================================================================
// UTILITY COMPONENTS
// ============================================================================
const LoadingSpinner = () => (
  <div className="flex items-center justify-center p-8">
    <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-secondary-500"></div>
  </div>
);

// Skeleton loader components for smoother loading states
const Skeleton = ({ className = '' }: { className?: string }) => (
  <div className={`bg-gray-200 rounded animate-pulse-soft ${className}`} />
);

const SkeletonCard = () => (
  <Card hover={false} className="p-6">
    <div className="flex items-center gap-4 mb-4">
      <Skeleton className="w-12 h-12 rounded-full" />
      <div className="flex-1">
        <Skeleton className="h-5 w-32 mb-2" />
        <Skeleton className="h-4 w-24" />
      </div>
    </div>
    <Skeleton className="h-4 w-full mb-2" />
    <Skeleton className="h-4 w-3/4" />
  </Card>
);

const SkeletonTable = ({ rows = 5 }: { rows?: number }) => (
  <div className="overflow-x-auto">
    <table className="w-full">
      <thead>
        <tr className="bg-gray-50">
          {[1, 2, 3, 4, 5].map(i => (
            <th key={i} className="px-4 py-3"><Skeleton className="h-4 w-20" /></th>
          ))}
        </tr>
      </thead>
      <tbody className="divide-y divide-gray-200">
        {Array.from({ length: rows }).map((_, i) => (
          <tr key={i}>
            {[1, 2, 3, 4, 5].map(j => (
              <td key={j} className="px-4 py-3"><Skeleton className="h-4 w-full" /></td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  </div>
);

const SkeletonStats = () => (
  <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
    {[1, 2, 3, 4].map(i => (
      <Card key={i} hover={false} className="p-6">
        <Skeleton className="h-4 w-24 mb-2" />
        <Skeleton className="h-8 w-16" />
      </Card>
    ))}
  </div>
);

// Animated page wrapper for smooth transitions
const PageTransition = ({ children }: { children: React.ReactNode }) => (
  <div className="animate-fade-in">{children}</div>
);

const Alert = ({ type, message, onClose }: { type: 'success' | 'error'; message: string; onClose?: () => void }) => (
  <div className={`p-4 rounded-lg mb-4 flex items-center justify-between ${type === 'success' ? 'bg-green-100 text-green-800 border border-green-200' : 'bg-red-100 text-red-800 border border-red-200'}`}>
    <span>{message}</span>
    {onClose && <button onClick={onClose} className="ml-4 text-lg font-bold hover:opacity-70">&times;</button>}
  </div>
);

const Button = ({ children, onClick, variant = 'primary', disabled = false, className = '', type = 'button' }: {
  children: React.ReactNode;
  onClick?: () => void;
  variant?: 'primary' | 'secondary' | 'outline' | 'danger';
  disabled?: boolean;
  className?: string;
  type?: 'button' | 'submit';
}) => {
  const baseStyles = 'px-4 py-2 rounded-lg font-medium transition-all duration-150 disabled:opacity-50 disabled:cursor-not-allowed active:scale-[0.98] shadow-sm hover:shadow-md';
  const variants = {
    primary: 'bg-secondary-500 text-white hover:bg-secondary-600 shadow-secondary-500/25',
    secondary: 'bg-primary-500 text-white hover:bg-primary-600 shadow-primary-500/25',
    outline: 'border-2 border-secondary-500 text-secondary-500 hover:bg-secondary-50 shadow-none hover:shadow-sm',
    danger: 'bg-red-500 text-white hover:bg-red-600 shadow-red-500/25',
  };
  return (
    <button type={type} onClick={onClick} disabled={disabled} className={`${baseStyles} ${variants[variant]} ${className}`}>
      {children}
    </button>
  );
};

const Input = ({ label, ...props }: { label: string } & React.InputHTMLAttributes<HTMLInputElement>) => (
  <div className="mb-4">
    <label className="block text-sm font-medium text-gray-700 mb-1">{label}</label>
    <input {...props} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-secondary-500 focus:border-secondary-500 outline-none transition-colors" />
  </div>
);

const Select = ({ label, options, ...props }: { label: string; options: { value: string; label: string }[] } & React.SelectHTMLAttributes<HTMLSelectElement>) => (
  <div className="mb-4">
    <label className="block text-sm font-medium text-gray-700 mb-1">{label}</label>
    <select {...props} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-secondary-500 focus:border-secondary-500 outline-none transition-colors bg-white">
      {options.map(opt => <option key={opt.value} value={opt.value}>{opt.label}</option>)}
    </select>
  </div>
);

const TextArea = ({ label, ...props }: { label: string } & React.TextareaHTMLAttributes<HTMLTextAreaElement>) => (
  <div className="mb-4">
    <label className="block text-sm font-medium text-gray-700 mb-1">{label}</label>
    <textarea {...props} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-secondary-500 focus:border-secondary-500 outline-none transition-colors resize-y" />
  </div>
);

const Card = ({ children, className = '', onClick, hover = true }: { children: React.ReactNode; className?: string; onClick?: () => void; hover?: boolean }) => (
  <div
    className={`bg-white rounded-xl shadow-md border border-gray-100 transition-all duration-200 ${hover ? 'hover:shadow-lg hover:-translate-y-0.5' : ''} ${onClick ? 'cursor-pointer' : ''} ${className}`}
    onClick={onClick}
  >
    {children}
  </div>
);

const StatusBadge = ({ status }: { status: string }) => {
  const colors: Record<string, string> = {
    ACTIVE: 'bg-green-100 text-green-800',
    DRAFT: 'bg-gray-100 text-gray-800',
    COMPLETED: 'bg-green-100 text-green-800',
    IN_PROGRESS: 'bg-blue-100 text-blue-800',
    NOT_STARTED: 'bg-gray-100 text-gray-800',
    SCHEDULED: 'bg-yellow-100 text-yellow-800',
    NOT_CONNECTED: 'bg-orange-100 text-orange-800',
    FAILED: 'bg-red-100 text-red-800',
    CANCELLED: 'bg-gray-100 text-gray-800',
  };
  return (
    <span className={`px-2 py-1 rounded-full text-xs font-medium ${colors[status] || 'bg-gray-100 text-gray-800'}`}>
      {status.replace(/_/g, ' ')}
    </span>
  );
};

// ============================================================================
// LOGIN SCREEN
// ============================================================================
// Signup Screen (for invited users)
const SignupScreen = ({ email, name, onComplete }: { email: string; name: string; onComplete: () => void }) => {
  const [password, setPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(false);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (password.length < 6) {
      setError('Password must be at least 6 characters');
      return;
    }
    if (password !== confirmPassword) {
      setError('Passwords do not match');
      return;
    }

    setLoading(true);
    setError('');

    try {
      await authService.completeSignup(email, password, name);
      localStorage.setItem('recex_authenticated', 'true');
      // Clear invite params from URL
      window.history.replaceState({}, '', window.location.pathname);
      onComplete();
    } catch (err) {
      setError(err.message || 'Failed to create account');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-secondary-500 to-secondary-700 p-4">
      <Card className="w-full max-w-md p-8">
        <div className="text-center mb-8">
          <img src="/images/logo.png" alt={CONFIG.APP_NAME} className="h-16 object-contain mx-auto mb-4" />
          <h1 className="text-2xl font-bold text-gray-900">Welcome, {name}!</h1>
          <p className="text-gray-500 mt-2">Set up your password to get started</p>
        </div>

        <form onSubmit={handleSubmit}>
          {error && <Alert type="error" message={error} onClose={() => setError('')} />}
          <div className="mb-4">
            <Input
              label="Email"
              type="email"
              value={email}
              disabled
            />
          </div>
          <div className="mb-4">
            <Input
              label="Password"
              type="password"
              value={password}
              onChange={e => setPassword(e.target.value)}
              placeholder="Create a password"
              required
            />
          </div>
          <Input
            label="Confirm Password"
            type="password"
            value={confirmPassword}
            onChange={e => setConfirmPassword(e.target.value)}
            placeholder="Confirm your password"
            required
          />
          <Button type="submit" className="w-full mt-4" disabled={loading}>
            {loading ? 'Creating Account...' : 'Create Account'}
          </Button>
        </form>
      </Card>
    </div>
  );
};

const LoginScreen = ({ onLogin }: { onLogin: () => void }) => {
  const [mode, setMode] = useState('login');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const [success, setSuccess] = useState('');
  const [loading, setLoading] = useState(false);

  // Check for invite parameter in URL
  const urlParams = new URLSearchParams(window.location.search);
  const inviteEmail = urlParams.get('invite');

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setError('');
    setSuccess('');
    setLoading(true);

    try {
      if (!isFirebaseConfigured()) {
        // Fallback mode - simple password
        if (password === 'recex-demo') {
          localStorage.setItem('recex_authenticated', 'true');
          onLogin();
        } else {
          setError('Invalid password');
        }
      } else {
        // Firebase mode
        const userCredential = await authService.signIn(email, password);

        // Verify user belongs to this tenant/subdomain
        const isValidTenant = await authService.verifyTenant(userCredential.user.uid);
        if (!isValidTenant) {
          await authService.signOut();
          throw new Error('Your account is not registered on this domain');
        }

        localStorage.setItem('recex_authenticated', 'true');
        onLogin();
      }
    } catch (err) {
      if (err.code === 'auth/user-not-found') {
        setError('No account found with this email');
      } else if (err.code === 'auth/wrong-password') {
        setError('Incorrect password');
      } else if (err.code === 'auth/invalid-credential') {
        setError('Invalid email or password');
      } else {
        setError(err.message || 'Failed to sign in');
      }
    } finally {
      setLoading(false);
    }
  };

  const handleForgotPassword = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!email) {
      setError('Please enter your email');
      return;
    }

    setError('');
    setLoading(true);

    try {
      await authService.sendPasswordReset(email);
      setSuccess('Password reset email sent! Check your inbox.');
    } catch (err) {
      setError(err.message || 'Failed to send reset email');
    } finally {
      setLoading(false);
    }
  };

  // If there's an invite, show signup form
  if (inviteEmail && isFirebaseConfigured()) {
    const inviteName = urlParams.get('name') || 'User';
    return <SignupScreen email={decodeURIComponent(inviteEmail)} name={inviteName} onComplete={onLogin} />;
  }

  return (
    <div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-secondary-500 to-secondary-700 p-4">
      <Card className="w-full max-w-md p-8">
        <div className="text-center mb-8">
          <img src="/images/logo.png" alt={CONFIG.APP_NAME} className="h-16 object-contain mx-auto mb-4" />
          <h1 className="text-2xl font-bold text-gray-900">{CONFIG.APP_NAME}</h1>
          <p className="text-gray-500 mt-2">
            {mode === 'login' ? 'Sign in to continue' : 'Reset your password'}
          </p>
        </div>

        {mode === 'login' ? (
          <form onSubmit={handleSubmit}>
            {error && <Alert type="error" message={error} onClose={() => setError('')} />}
            {success && <Alert type="success" message={success} onClose={() => setSuccess('')} />}

            {isFirebaseConfigured() ? (
              <>
                <div className="mb-4">
                  <Input
                    label="Email"
                    type="email"
                    value={email}
                    onChange={e => setEmail(e.target.value)}
                    placeholder="Enter your email"
                    required
                  />
                </div>
                <Input
                  label="Password"
                  type="password"
                  value={password}
                  onChange={e => setPassword(e.target.value)}
                  placeholder="Enter your password"
                  required
                />
                <Button type="submit" className="w-full mt-4" disabled={loading}>
                  {loading ? 'Signing in...' : 'Sign In'}
                </Button>
                <button
                  type="button"
                  onClick={() => setMode('forgot')}
                  className="w-full mt-3 text-sm text-secondary-600 hover:text-secondary-700"
                >
                  Forgot password?
                </button>
              </>
            ) : (
              <>
                <Input
                  label="Password"
                  type="password"
                  value={password}
                  onChange={e => setPassword(e.target.value)}
                  placeholder="Enter password"
                  required
                />
                <Button type="submit" className="w-full mt-4" disabled={loading}>
                  {loading ? 'Signing in...' : 'Sign In'}
                </Button>
                <p className="mt-4 text-xs text-gray-400 text-center">
                  Firebase not configured. Using demo mode.
                </p>
              </>
            )}
          </form>
        ) : (
          <form onSubmit={handleForgotPassword}>
            {error && <Alert type="error" message={error} onClose={() => setError('')} />}
            {success && <Alert type="success" message={success} onClose={() => setSuccess('')} />}

            <Input
              label="Email"
              type="email"
              value={email}
              onChange={e => setEmail(e.target.value)}
              placeholder="Enter your email"
              required
            />
            <Button type="submit" className="w-full mt-4" disabled={loading}>
              {loading ? 'Sending...' : 'Send Reset Link'}
            </Button>
            <button
              type="button"
              onClick={() => setMode('login')}
              className="w-full mt-3 text-sm text-secondary-600 hover:text-secondary-700"
            >
              Back to sign in
            </button>
          </form>
        )}
      </Card>
    </div>
  );
};

// ============================================================================
// AGENTS SECTION
// ============================================================================
// Voice persona options with visual data
const voicePersonas = [
  { id: 'NEHA', name: 'Neha', gender: 'Female', avatarUrl: '/images/neha.png' },
  { id: 'ROY', name: 'Roy', gender: 'Male', avatarUrl: '/images/roy.png' },
];

const languageOptions = [
  { value: 'ENGLISH', label: 'English' },
  { value: 'HINDI', label: 'Hindi' },
  { value: 'TAMIL', label: 'Tamil' },
  { value: 'KANNADA', label: 'Kannada' },
  { value: 'MARATHI', label: 'Marathi' },
  { value: 'TELUGU', label: 'Telugu' },
];

// Create Agent Wizard - Multi-step visual wizard
const CreateAgentWizard = ({ onSave, onCancel }: {
  onSave: (data: Partial<Agent>) => Promise<void>;
  onCancel: () => void;
}) => {
  const [step, setStep] = useState(1);
  const [formData, setFormData] = useState({
    name: '',
    language: 'ENGLISH',
    voice_persona: '',
    persona_name: '',
    agent_prompt: '',
    objective: '',
    introduction: '',
    result_prompt: '',
    result_schema: '{\n  "interest_status": ""\n}',
  });
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  const update = (field: string, value: string) => setFormData(prev => ({ ...prev, [field]: value }));

  const handleSubmit = async () => {
    setLoading(true);
    setError('');
    try {
      let resultSchema;
      try {
        resultSchema = JSON.parse(formData.result_schema);
      } catch {
        throw new Error('Invalid JSON in result schema');
      }
      await onSave({ ...formData, result_schema: resultSchema });
    } catch (err) {
      setError(err instanceof Error ? err.message : 'An error occurred');
    } finally {
      setLoading(false);
    }
  };

  const stepTitles = ['Select Voice', 'Basic Info', 'Behavior', 'Results'];
  const isStep1Valid = formData.voice_persona && formData.language;
  const isStep2Valid = formData.name.trim() && formData.objective.trim();
  const isStep3Valid = formData.agent_prompt.trim() && formData.introduction.trim();

  const canProceed = () => {
    switch (step) {
      case 1: return isStep1Valid;
      case 2: return isStep2Valid;
      case 3: return isStep3Valid;
      case 4: return true;
      default: return false;
    }
  };

  return (
    <div>
      {/* Breadcrumb */}
      <div className="text-sm text-gray-500 mb-2">
        Agents / <span className="text-gray-900">New Agent</span>
      </div>

      {/* Step indicator */}
      <div className="flex items-center gap-2 text-sm text-gray-500 mb-2">
        <span>Step {step} of 4</span>
        <span>•</span>
        <span>{stepTitles[step - 1]}</span>
      </div>

      {/* Title */}
      <h1 className="text-2xl font-bold text-gray-900 mb-1">
        {step === 1 ? 'Create New Agent' : formData.name || 'New Agent'}
      </h1>
      <p className="text-sm text-gray-500 mb-6">
        {step === 1 ? 'Select a voice persona for your agent' : `Voice: ${voicePersonas.find(v => v.id === formData.voice_persona)?.name || ''}`}
      </p>

      {error && <Alert type="error" message={error} onClose={() => setError('')} />}

      {/* Step progress bar */}
      <div className="flex gap-2 mb-8">
        {[1, 2, 3, 4].map(s => (
          <div
            key={s}
            className={`h-1 flex-1 rounded-full ${s <= step ? 'bg-primary-500' : 'bg-gray-200'}`}
          />
        ))}
      </div>

      <Card className="p-6">
        {/* Step 1: Language and Voice Selection */}
        {step === 1 && (
          <div>
            <h3 className="text-lg font-semibold text-gray-900 mb-4">Select Language & Voice</h3>
            <p className="text-sm text-gray-600 mb-6">Choose the language and voice persona for your AI agent</p>

            <Select
              label="Language *"
              value={formData.language}
              onChange={e => update('language', e.target.value)}
              options={languageOptions}
            />

            <div className="mt-6">
              <label className="block text-sm font-medium text-gray-700 mb-3">Voice Persona *</label>
              <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
                {voicePersonas.map(persona => (
                  <div
                    key={persona.id}
                    onClick={() => update('voice_persona', persona.id)}
                    className={`p-4 rounded-xl border-2 cursor-pointer transition-all hover:shadow-md ${
                      formData.voice_persona === persona.id
                        ? 'border-primary-500 bg-primary-50'
                        : 'border-gray-200 hover:border-gray-300'
                    }`}
                  >
                    {/* Avatar */}
                    <img
                      src={persona.avatarUrl}
                      alt={persona.name}
                      className="w-20 h-20 mx-auto mb-3 rounded-full object-cover"
                    />

                    {/* Name */}
                    <div className="text-center">
                      <h4 className="font-semibold text-gray-900">{persona.name}</h4>
                    </div>

                    {/* Selection indicator */}
                    {formData.voice_persona === persona.id && (
                      <div className="mt-3 flex justify-center">
                        <div className="w-5 h-5 rounded-full bg-primary-500 flex items-center justify-center">
                          <svg className="w-3 h-3 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
                          </svg>
                        </div>
                      </div>
                    )}
                  </div>
                ))}
              </div>
            </div>
          </div>
        )}

        {/* Step 2: Basic Info */}
        {step === 2 && (
          <div>
            <h3 className="text-lg font-semibold text-gray-900 mb-4">Basic Information</h3>
            <p className="text-sm text-gray-600 mb-6">Define your agent's identity and purpose</p>

            <Input
              label="Agent Name *"
              value={formData.name}
              onChange={e => update('name', e.target.value)}
              required
              maxLength={64}
              placeholder="e.g., Sales Assistant, Support Bot"
            />

            <Input
              label="Persona Name"
              value={formData.persona_name}
              onChange={e => update('persona_name', e.target.value)}
              placeholder="e.g., Seema, Raj - The name the agent uses for itself"
            />

            <TextArea
              label="Objective *"
              value={formData.objective}
              onChange={e => update('objective', e.target.value)}
              rows={3}
              required
              placeholder="What is the business goal of this agent? e.g., Qualify leads for product demo, Schedule appointments..."
            />
          </div>
        )}

        {/* Step 3: Behavior */}
        {step === 3 && (
          <div>
            <h3 className="text-lg font-semibold text-gray-900 mb-4">Agent Behavior</h3>
            <p className="text-sm text-gray-600 mb-6">Configure how your agent communicates</p>

            <TextArea
              label="Agent Prompt *"
              value={formData.agent_prompt}
              onChange={e => update('agent_prompt', e.target.value)}
              rows={6}
              required
              placeholder="System prompt that defines the agent's behavior, tone, and conversation style..."
            />

            <TextArea
              label="Introduction *"
              value={formData.introduction}
              onChange={e => update('introduction', e.target.value)}
              rows={3}
              required
              placeholder="Opening message when call connects. Use {persona_name}, {company}, {callee_name} as variables..."
            />
          </div>
        )}

        {/* Step 4: Results */}
        {step === 4 && (
          <div>
            <h3 className="text-lg font-semibold text-gray-900 mb-4">Result Configuration</h3>
            <p className="text-sm text-gray-600 mb-6">Define how call results are captured and structured</p>

            <TextArea
              label="Result Prompt"
              value={formData.result_prompt}
              onChange={e => update('result_prompt', e.target.value)}
              rows={3}
              placeholder="Instructions for extracting structured results from the conversation..."
            />

            <TextArea
              label="Result Schema (JSON)"
              value={formData.result_schema}
              onChange={e => update('result_schema', e.target.value)}
              rows={6}
              placeholder='{"interest_status": "", "qualified": "", "callback_requested": ""}'
            />

            <div className="mt-4 p-4 bg-gray-50 rounded-lg">
              <h4 className="text-sm font-medium text-gray-700 mb-2">Schema Preview</h4>
              <pre className="text-xs text-gray-600 overflow-x-auto">
                {formData.result_schema || '{}'}
              </pre>
            </div>
          </div>
        )}
      </Card>

      {/* Navigation buttons */}
      <div className="flex justify-between mt-6">
        <Button variant="outline" onClick={step === 1 ? onCancel : () => setStep(step - 1)}>
          {step === 1 ? 'Cancel' : 'Back'}
        </Button>

        {step < 4 ? (
          <Button onClick={() => setStep(step + 1)} disabled={!canProceed()}>
            Continue
          </Button>
        ) : (
          <Button onClick={handleSubmit} disabled={loading}>
            {loading ? 'Creating...' : 'Create Agent'}
          </Button>
        )}
      </div>
    </div>
  );
};

// Agent Form for editing (simpler single-page form)
const AgentForm = ({ agent, onSave, onCancel, isEdit = false }: {
  agent?: Agent;
  onSave: (data: Partial<Agent>) => Promise<void>;
  onCancel: () => void;
  isEdit?: boolean;
}) => {
  const [formData, setFormData] = useState({
    name: agent?.name || '',
    language: agent?.language || 'ENGLISH',
    voice_persona: agent?.voice_persona || 'NEHA',
    persona_name: agent?.persona_name || '',
    agent_prompt: agent?.agent_prompt || '',
    objective: agent?.objective || '',
    introduction: agent?.introduction || '',
    result_prompt: agent?.result_prompt || '',
    result_schema: JSON.stringify(agent?.result_schema || { interest_status: '' }, null, 2),
  });
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setLoading(true);
    setError('');
    try {
      let resultSchema;
      try {
        resultSchema = JSON.parse(formData.result_schema);
      } catch {
        throw new Error('Invalid JSON in result schema');
      }
      await onSave({ ...formData, result_schema: resultSchema });
    } catch (err) {
      setError(err instanceof Error ? err.message : 'An error occurred');
    } finally {
      setLoading(false);
    }
  };

  const update = (field: string, value: string) => setFormData(prev => ({ ...prev, [field]: value }));

  return (
    <form onSubmit={handleSubmit}>
      {error && <Alert type="error" message={error} onClose={() => setError('')} />}

      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        <Input label="Agent Name *" value={formData.name} onChange={e => update('name', e.target.value)} required maxLength={64} />
        <Input label="Persona Name" value={formData.persona_name} onChange={e => update('persona_name', e.target.value)} placeholder="e.g., Seema, Raj" />
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        <Select
          label="Language *"
          value={formData.language}
          onChange={e => update('language', e.target.value)}
          options={languageOptions}
        />
        <Select
          label="Voice Persona *"
          value={formData.voice_persona}
          onChange={e => update('voice_persona', e.target.value)}
          options={[
            { value: 'NEHA', label: 'Neha (Female)' },
            { value: 'ROY', label: 'Roy (Male)' },
          ]}
        />
      </div>

      <TextArea label="Objective *" value={formData.objective} onChange={e => update('objective', e.target.value)} rows={2} required placeholder="Business objective that guides the agent's responses" />
      <TextArea label="Agent Prompt *" value={formData.agent_prompt} onChange={e => update('agent_prompt', e.target.value)} rows={4} required placeholder="System prompt that defines the agent's behavior" />
      <TextArea label="Introduction *" value={formData.introduction} onChange={e => update('introduction', e.target.value)} rows={2} required placeholder="Opening message when call connects. Use {persona_name}, {company}, etc." />
      <TextArea label="Result Prompt" value={formData.result_prompt} onChange={e => update('result_prompt', e.target.value)} rows={2} placeholder="Instructions for generating structured results" />
      <TextArea label="Result Schema (JSON)" value={formData.result_schema} onChange={e => update('result_schema', e.target.value)} rows={4} placeholder='{"interest_status": "", "qualified": ""}' />

      <div className="flex gap-3 mt-6">
        <Button type="submit" disabled={loading}>{loading ? 'Saving...' : isEdit ? 'Update Agent' : 'Create Agent'}</Button>
        <Button variant="outline" onClick={onCancel}>Cancel</Button>
      </div>
    </form>
  );
};

const AgentsList = ({ onSelect, onCreate }: { onSelect: (id: string, mode: 'view' | 'edit') => void; onCreate: () => void }) => {
  const [agents, setAgents] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');

  useEffect(() => {
    loadAgents();
  }, []);

  const loadAgents = async () => {
    try {
      const data = await api.listAgents();
      setAgents(data.results);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'An error occurred');
    } finally {
      setLoading(false);
    }
  };

  if (loading) return <LoadingSpinner />;

  return (
    <div>
      <div className="flex justify-between items-center mb-6">
        <h2 className="text-xl font-semibold text-gray-900">Your Agents</h2>
        <Button onClick={onCreate}>+ Create Agent</Button>
      </div>

      {error && <Alert type="error" message={error} />}

      {agents.length === 0 ? (
        <Card className="p-8 text-center">
          <div className="text-gray-400 mb-4">
            <svg className="w-16 h-16 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z" />
            </svg>
          </div>
          <h3 className="text-lg font-medium text-gray-900 mb-2">No agents yet</h3>
          <p className="text-gray-500 mb-4">Create your first voice agent to get started</p>
          <Button onClick={onCreate}>Create Agent</Button>
        </Card>
      ) : (
        <div className="grid gap-4">
          {agents.map(agent => (
            <Card key={agent.id} className="p-4 hover:shadow-md transition-shadow">
              <div className="flex items-center justify-between">
                <div className="flex-1">
                  <div className="flex items-center gap-3">
                    <h3 className="font-medium text-gray-900">{agent.name}</h3>
                    <StatusBadge status={agent.status} />
                  </div>
                  <p className="text-sm text-gray-500 mt-1">
                    {agent.voice_persona} ({agent.persona_name || agent.voice_persona}) &bull; {agent.language}
                  </p>
                </div>
                <div className="flex gap-2">
                  <Button variant="outline" onClick={() => onSelect(agent.id, 'view')}>View</Button>
                  <Button variant="secondary" onClick={() => onSelect(agent.id, 'edit')}>Edit</Button>
                </div>
              </div>
            </Card>
          ))}
        </div>
      )}
    </div>
  );
};

const AgentDetail = ({ agentId, onBack, onEdit }: { agentId: string; onBack: () => void; onEdit: () => void }) => {
  const [agent, setAgent] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    api.getAgent(agentId).then(setAgent).finally(() => setLoading(false));
  }, [agentId]);

  if (loading) return <LoadingSpinner />;
  if (!agent) return <Alert type="error" message="Agent not found" />;

  return (
    <div>
      <button onClick={onBack} className="flex items-center text-secondary-500 hover:text-secondary-600 mb-4">
        <svg className="w-5 h-5 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" /></svg>
        Back to Agents
      </button>

      <Card className="p-6">
        <div className="flex justify-between items-start mb-6">
          <div>
            <h2 className="text-2xl font-bold text-gray-900">{agent.name}</h2>
            <div className="flex items-center gap-3 mt-2">
              <StatusBadge status={agent.status} />
              <span className="text-gray-500">{agent.voice_persona} &bull; {agent.language}</span>
            </div>
          </div>
          <Button onClick={onEdit}>Edit Agent</Button>
        </div>

        <div className="space-y-6">
          <div>
            <h4 className="font-medium text-gray-700 mb-2">Objective</h4>
            <p className="text-gray-600 bg-gray-50 p-3 rounded-lg">{agent.objective || '-'}</p>
          </div>
          <div>
            <h4 className="font-medium text-gray-700 mb-2">Agent Prompt</h4>
            <p className="text-gray-600 bg-gray-50 p-3 rounded-lg whitespace-pre-wrap">{agent.agent_prompt || '-'}</p>
          </div>
          <div>
            <h4 className="font-medium text-gray-700 mb-2">Introduction</h4>
            <p className="text-gray-600 bg-gray-50 p-3 rounded-lg">{agent.introduction || '-'}</p>
          </div>
          {agent.custom_variables && agent.custom_variables.length > 0 && (
            <div>
              <h4 className="font-medium text-gray-700 mb-2">Custom Variables</h4>
              <div className="flex flex-wrap gap-2">
                {agent.custom_variables.map(v => (
                  <span key={v} className="px-2 py-1 bg-secondary-100 text-secondary-700 rounded text-sm">{`{${v}}`}</span>
                ))}
              </div>
            </div>
          )}
          {agent.result_schema && (
            <div>
              <h4 className="font-medium text-gray-700 mb-2">Result Schema</h4>
              <pre className="text-gray-600 bg-gray-50 p-3 rounded-lg text-sm overflow-auto">{JSON.stringify(agent.result_schema, null, 2)}</pre>
            </div>
          )}
        </div>
      </Card>
    </div>
  );
};

const AgentsSection = () => {
  const [view, setView] = useState('list');
  const [selectedAgentId, setSelectedAgentId] = useState(null);
  const [successMsg, setSuccessMsg] = useState('');
  const [listKey, setListKey] = useState(0);

  const handleSelect = (id: string, mode: 'view' | 'edit') => {
    setSelectedAgentId(id);
    setView(mode);
  };

  const handleSaveNew = async (data: Partial<Agent>) => {
    await api.createAgent(data);
    setSuccessMsg('Agent created successfully!');
    setListKey(k => k + 1); // Force list reload
    setView('list');
  };

  const handleSaveEdit = async (data: Partial<Agent>) => {
    if (!selectedAgentId) return;
    await api.updateAgent(selectedAgentId, data);
    setSuccessMsg('Agent updated successfully!');
    setListKey(k => k + 1); // Force list reload
    setView('list');
  };

  return (
    <div>
      {successMsg && <Alert type="success" message={successMsg} onClose={() => setSuccessMsg('')} />}

      {view === 'list' && (
        <AgentsList key={listKey} onSelect={handleSelect} onCreate={() => setView('create')} />
      )}
      {view === 'create' && (
        <CreateAgentWizard onSave={handleSaveNew} onCancel={() => setView('list')} />
      )}
      {view === 'edit' && selectedAgentId && (
        <AgentEditWrapper agentId={selectedAgentId} onSave={handleSaveEdit} onCancel={() => setView('list')} />
      )}
      {view === 'view' && selectedAgentId && (
        <AgentDetail agentId={selectedAgentId} onBack={() => setView('list')} onEdit={() => setView('edit')} />
      )}
    </div>
  );
};

const AgentEditWrapper = ({ agentId, onSave, onCancel }: { agentId: string; onSave: (data: Partial<Agent>) => Promise<void>; onCancel: () => void }) => {
  const [agent, setAgent] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    api.getAgent(agentId).then(setAgent).finally(() => setLoading(false));
  }, [agentId]);

  if (loading) return <LoadingSpinner />;
  if (!agent) return <Alert type="error" message="Agent not found" />;

  return (
    <div>
      <h2 className="text-xl font-semibold text-gray-900 mb-6">Edit Agent: {agent.name}</h2>
      <Card className="p-6">
        <AgentForm agent={agent} onSave={onSave} onCancel={onCancel} isEdit />
      </Card>
    </div>
  );
};

// ============================================================================
// CALLS SECTION
// ============================================================================
const QuickCall = ({ agents, onSuccess }: { agents: Agent[]; onSuccess: () => void }) => {
  const [agentId, setAgentId] = useState('');
  const [selectedAgent, setSelectedAgent] = useState(null);
  const [calleeName, setCalleeName] = useState('');
  const [mobileNumber, setMobileNumber] = useState('');
  const [customData, setCustomData] = useState({});
  const [loading, setLoading] = useState(false);
  const [loadingAgent, setLoadingAgent] = useState(false);
  const [error, setError] = useState('');
  const [success, setSuccess] = useState('');

  // Fetch agent details when agent is selected
  const handleAgentSelect = async (id: string) => {
    setAgentId(id);
    setCustomData({});
    if (id) {
      setLoadingAgent(true);
      try {
        const agent = await api.getAgent(id);
        setSelectedAgent(agent);
      } catch (err) {
        console.error(err);
        setSelectedAgent(null);
      } finally {
        setLoadingAgent(false);
      }
    } else {
      setSelectedAgent(null);
    }
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!agentId) { setError('Please select an agent'); return; }
    setLoading(true);
    setError('');
    try {
      const callData = {
        agent_id: agentId,
        callee_name: calleeName,
        mobile_number: mobileNumber,
        custom_data: Object.keys(customData).length > 0 ? customData : undefined
      };
      const call = await api.createCall(callData);
      setSuccess(`Call initiated! ID: ${call.id}`);
      setCalleeName('');
      setMobileNumber('');
      setCustomData({});
      onSuccess();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'An error occurred');
    } finally {
      setLoading(false);
    }
  };

  const customVariables = selectedAgent?.custom_variables || [];

  return (
    <Card className="p-6">
      <h3 className="text-lg font-semibold text-gray-900 mb-4">Quick Call</h3>
      <p className="text-gray-500 mb-6">Make a single call to one contact</p>

      {error && <Alert type="error" message={error} onClose={() => setError('')} />}
      {success && <Alert type="success" message={success} onClose={() => setSuccess('')} />}

      <form onSubmit={handleSubmit}>
        <Select
          label="Select Agent *"
          value={agentId}
          onChange={e => handleAgentSelect(e.target.value)}
          options={[{ value: '', label: 'Choose an agent...' }, ...agents.filter(a => a.status === 'ACTIVE').map(a => ({ value: a.id, label: a.name }))]}
        />
        <Input label="Contact Name *" value={calleeName} onChange={e => setCalleeName(e.target.value)} required placeholder="John Doe" />
        <Input label="Phone Number *" value={mobileNumber} onChange={e => setMobileNumber(e.target.value)} required placeholder="+919876543210" />

        {/* Custom Variables */}
        {loadingAgent && <p className="text-sm text-gray-500 mb-4">Loading agent details...</p>}
        {customVariables.length > 0 && (
          <div className="mt-4 pt-4 border-t border-gray-200">
            <h4 className="text-sm font-medium text-gray-700 mb-3">Custom Variables</h4>
            {customVariables.map(varName => (
              <Input
                key={varName}
                label={varName}
                value={customData[varName] || ''}
                onChange={e => setCustomData(prev => ({ ...prev, [varName]: e.target.value }))}
                placeholder={`Enter ${varName}`}
              />
            ))}
          </div>
        )}

        <Button type="submit" disabled={loading} className="mt-2">{loading ? 'Initiating...' : 'Start Call'}</Button>
      </form>
    </Card>
  );
};

const BulkCalls = ({ agents, onSuccess }: { agents: Agent[]; onSuccess: () => void }) => {
  const [agentId, setAgentId] = useState('');
  const [selectedAgent, setSelectedAgent] = useState(null);
  const [contacts, setContacts] = useState('');
  const [loading, setLoading] = useState(false);
  const [loadingAgent, setLoadingAgent] = useState(false);
  const [error, setError] = useState('');
  const [success, setSuccess] = useState('');

  // Fetch agent details when agent is selected
  const handleAgentSelect = async (id: string) => {
    setAgentId(id);
    if (id) {
      setLoadingAgent(true);
      try {
        const agent = await api.getAgent(id);
        setSelectedAgent(agent);
      } catch (err) {
        console.error(err);
        setSelectedAgent(null);
      } finally {
        setLoadingAgent(false);
      }
    } else {
      setSelectedAgent(null);
    }
  };

  const customVariables = selectedAgent?.custom_variables || [];

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!agentId) { setError('Please select an agent'); return; }

    const lines = contacts.trim().split('\n').filter(l => l.trim());
    if (lines.length === 0) { setError('Please enter at least one contact'); return; }

    // Parse CSV-style data: Name, Phone, CustomVar1, CustomVar2, ...
    const data = lines.map(line => {
      const parts = line.split(',').map(s => s.trim());
      const callData: any = {
        callee_name: parts[0] || 'Unknown',
        mobile_number: parts[1] || parts[0]
      };

      // Map additional columns to custom variables
      if (customVariables.length > 0 && parts.length > 2) {
        callData.custom_data = {};
        customVariables.forEach((varName, idx) => {
          if (parts[idx + 2]) {
            callData.custom_data[varName] = parts[idx + 2];
          }
        });
      }

      return callData;
    });

    setLoading(true);
    setError('');
    try {
      const calls = await api.createBulkCalls({ agent_id: agentId, data });
      setSuccess(`${calls.length} calls initiated successfully!`);
      setContacts('');
      onSuccess();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'An error occurred');
    } finally {
      setLoading(false);
    }
  };

  // Generate placeholder based on custom variables
  const getPlaceholder = () => {
    if (customVariables.length === 0) {
      return "John Doe, +919876543210\nJane Smith, +919876543211\nBob Johnson, +919876543212";
    }
    const vars = customVariables.join(', ');
    return `Name, Phone, ${vars}\nJohn Doe, +919876543210, value1, value2\nJane Smith, +919876543211, value1, value2`;
  };

  return (
    <Card className="p-6">
      <h3 className="text-lg font-semibold text-gray-900 mb-4">Bulk Calls</h3>
      <p className="text-gray-500 mb-6">Call multiple contacts at once</p>

      {error && <Alert type="error" message={error} onClose={() => setError('')} />}
      {success && <Alert type="success" message={success} onClose={() => setSuccess('')} />}

      <form onSubmit={handleSubmit}>
        <Select
          label="Select Agent *"
          value={agentId}
          onChange={e => handleAgentSelect(e.target.value)}
          options={[{ value: '', label: 'Choose an agent...' }, ...agents.filter(a => a.status === 'ACTIVE').map(a => ({ value: a.id, label: a.name }))]}
        />

        {loadingAgent && <p className="text-sm text-gray-500 mb-4">Loading agent details...</p>}

        {selectedAgent && customVariables.length > 0 && (
          <div className="mb-4 p-3 bg-blue-50 border border-blue-200 rounded-lg">
            <p className="text-sm text-blue-800 font-medium mb-1">Custom variables required:</p>
            <p className="text-sm text-blue-600">{customVariables.join(', ')}</p>
            <p className="text-xs text-blue-500 mt-1">Include these as columns after Name and Phone</p>
          </div>
        )}

        <TextArea
          label={customVariables.length > 0
            ? `Contacts (Name, Phone, ${customVariables.join(', ')}) - one per line *`
            : "Contacts (Name, Phone - one per line) *"}
          value={contacts}
          onChange={e => setContacts(e.target.value)}
          rows={8}
          required
          placeholder={getPlaceholder()}
        />
        <Button type="submit" disabled={loading || loadingAgent} className="mt-2">{loading ? 'Initiating...' : 'Start Bulk Calls'}</Button>
      </form>
    </Card>
  );
};

const CallHistory = ({ agents }: { agents: Agent[] }) => {
  const [calls, setCalls] = useState([]);
  const [totalCount, setTotalCount] = useState(0);
  const [loading, setLoading] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);
  const [exporting, setExporting] = useState(false);
  const [page, setPage] = useState(1);
  const [filter, setFilter] = useState({
    status: '',
    engagementStatus: '',
    answeredBy: '',
    agentId: '',
    dateRange: '30days'
  });
  const [selectedCall, setSelectedCall] = useState(null);

  const getFilterParams = useCallback(() => {
    const dateRange = getDateRange(filter.dateRange);
    const params: any = {
      createdAfter: dateRange ? dateRange.start : undefined,
      createdBefore: dateRange ? dateRange.end : undefined,
    };
    if (filter.status) params.status = [filter.status];
    if (filter.engagementStatus) params.engagementStatus = [filter.engagementStatus];
    if (filter.answeredBy) params.answeredBy = [filter.answeredBy];
    if (filter.agentId) params.agentId = filter.agentId;
    return params;
  }, [filter]);

  const loadCalls = useCallback(async (resetPage = true) => {
    if (resetPage) {
      setLoading(true);
      setPage(1);
    } else {
      setLoadingMore(true);
    }
    try {
      const params = getFilterParams();
      const currentPage = resetPage ? 1 : page;
      const data = await api.listCalls({ ...params, page: currentPage, pageSize: 100 });
      if (resetPage) {
        setCalls(data.results);
      } else {
        setCalls(prev => [...prev, ...data.results]);
      }
      setTotalCount(data.count);
    } catch (err) {
      console.error(err);
    } finally {
      setLoading(false);
      setLoadingMore(false);
    }
  }, [filter, page, getFilterParams]);

  useEffect(() => { loadCalls(true); }, [filter]);

  const loadMore = async () => {
    const nextPage = page + 1;
    setPage(nextPage);
    setLoadingMore(true);
    try {
      const params = getFilterParams();
      const data = await api.listCalls({ ...params, page: nextPage, pageSize: 100 });
      setCalls(prev => [...prev, ...data.results]);
    } catch (err) {
      console.error(err);
    } finally {
      setLoadingMore(false);
    }
  };

  const handleExport = async () => {
    setExporting(true);
    try {
      const params = getFilterParams();
      const allCalls = await api.listAllCalls(params);
      const agentsMap = new Map(agents.map(a => [a.id, a.name]));
      exportCallsToCSV(allCalls, 'call_history', agentsMap);
    } catch (err) {
      console.error(err);
      alert('Failed to export calls');
    } finally {
      setExporting(false);
    }
  };

  const hasMore = calls.length < totalCount;

  return (
    <div>
      {selectedCall ? (
        <CallDetail call={selectedCall} onBack={() => setSelectedCall(null)} agents={agents} />
      ) : (
        <>
          <div className="flex flex-wrap items-center gap-3 mb-6">
            <select
              value={filter.dateRange}
              onChange={e => setFilter(f => ({ ...f, dateRange: e.target.value }))}
              className="px-3 py-2 border border-gray-300 rounded-lg bg-white text-sm"
            >
              <option value="today">Today</option>
              <option value="yesterday">Yesterday</option>
              <option value="7days">Last 7 days</option>
              <option value="30days">Last 30 days</option>
              <option value="all">No filter</option>
            </select>
            <select
              value={filter.status}
              onChange={e => setFilter(f => ({ ...f, status: e.target.value }))}
              className="px-3 py-2 border border-gray-300 rounded-lg bg-white text-sm"
            >
              <option value="">All Statuses</option>
              {CALL_STATUSES.map(s => <option key={s} value={s}>{s.replace(/_/g, ' ')}</option>)}
            </select>
            <select
              value={filter.engagementStatus}
              onChange={e => setFilter(f => ({ ...f, engagementStatus: e.target.value }))}
              className="px-3 py-2 border border-gray-300 rounded-lg bg-white text-sm"
            >
              <option value="">All Engagement</option>
              {ENGAGEMENT_STATUSES.map(s => <option key={s} value={s}>{s.replace(/_/g, ' ')}</option>)}
            </select>
            <select
              value={filter.answeredBy}
              onChange={e => setFilter(f => ({ ...f, answeredBy: e.target.value }))}
              className="px-3 py-2 border border-gray-300 rounded-lg bg-white text-sm"
            >
              <option value="">Answered By</option>
              {ANSWERED_BY_OPTIONS.map(s => <option key={s} value={s}>{s}</option>)}
            </select>
            <select
              value={filter.agentId}
              onChange={e => setFilter(f => ({ ...f, agentId: e.target.value }))}
              className="px-3 py-2 border border-gray-300 rounded-lg bg-white text-sm"
            >
              <option value="">All Agents</option>
              {agents.map(a => <option key={a.id} value={a.id}>{a.name}</option>)}
            </select>
            <Button variant="outline" onClick={() => loadCalls(true)}>Refresh</Button>
            <Button variant="secondary" onClick={handleExport} disabled={totalCount === 0 || exporting}>
              {exporting ? 'Exporting...' : `Export All (${totalCount})`}
            </Button>
          </div>

          {(() => {
            // Apply client-side filters (status, engagement, answered_by, agent)
            const filteredCalls = calls.filter(call => {
              if (filter.status && call.status?.toUpperCase() !== filter.status.toUpperCase()) return false;
              if (filter.engagementStatus && call.engagement_status?.toUpperCase() !== filter.engagementStatus.toUpperCase()) return false;
              if (filter.answeredBy && call.answered_by?.toUpperCase() !== filter.answeredBy.toUpperCase()) return false;
              if (filter.agentId && call.agent_id !== filter.agentId) return false;
              return true;
            });

            return (
              <>
                <p className="text-sm text-gray-500 mb-4">
                  Showing {filteredCalls.length} of {totalCount} calls {filteredCalls.length !== calls.length && `(${calls.length} loaded, ${filteredCalls.length} matching filters)`}
                </p>

                {loading ? <SkeletonTable rows={5} /> : filteredCalls.length === 0 ? (
                  <Card className="p-8 text-center">
                    <p className="text-gray-500">No calls found</p>
                  </Card>
                ) : (
                  <>
                    <div className="overflow-x-auto">
                      <table className="w-full">
                        <thead>
                          <tr className="bg-gray-50">
                            <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Contact</th>
                            <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Phone</th>
                            <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Agent</th>
                            <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Status</th>
                            <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Engagement</th>
                            <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Duration</th>
                            <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Date</th>
                            <th className="px-4 py-3 text-left text-sm font-medium text-gray-700"></th>
                          </tr>
                        </thead>
                        <tbody className="divide-y divide-gray-200">
                          {filteredCalls.map(call => (
                            <tr key={call.id} className="hover:bg-gray-50 transition-colors">
                              <td className="px-4 py-3 text-sm">{call.callee_name}</td>
                              <td className="px-4 py-3 text-sm text-gray-500">{call.mobile_number}</td>
                              <td className="px-4 py-3 text-sm text-gray-500">{agents.find(a => a.id === call.agent_id)?.name || '-'}</td>
                              <td className="px-4 py-3"><StatusBadge status={call.status} /></td>
                              <td className="px-4 py-3 text-sm text-gray-500">{call.engagement_status || '-'}</td>
                              <td className="px-4 py-3 text-sm text-gray-500">{call.duration_minutes ? `${call.duration_minutes.toFixed(1)} min` : '-'}</td>
                              <td className="px-4 py-3 text-sm text-gray-500">{new Date(call.created_at).toLocaleDateString()}</td>
                              <td className="px-4 py-3"><Button variant="outline" onClick={() => setSelectedCall(call)}>View</Button></td>
                            </tr>
                          ))}
                        </tbody>
                      </table>
                    </div>

                    {hasMore && (
                      <div className="mt-6 text-center">
                        <Button variant="outline" onClick={loadMore} disabled={loadingMore}>
                          {loadingMore ? 'Loading...' : `Load More (${totalCount - calls.length} remaining)`}
                        </Button>
                      </div>
                    )}
                  </>
                )}
              </>
            );
          })()}
        </>
      )}
    </div>
  );
};

const CallDetail = ({ call: initialCall, onBack, agents, backLabel = 'Back to Call History' }: {
  call: Call;
  onBack: () => void;
  agents?: Agent[];
  backLabel?: string;
}) => {
  const [call, setCall] = useState(initialCall);
  const [loading, setLoading] = useState(true);

  // Fetch full call details to get custom_data
  useEffect(() => {
    api.getCall(initialCall.id)
      .then(fullCall => setCall(fullCall))
      .catch(console.error)
      .finally(() => setLoading(false));
  }, [initialCall.id]);

  const agentName = call.agent?.name || agents?.find(a => a.id === call.agent_id)?.name || call.agent_id;

  if (loading) return <LoadingSpinner />;

  return (
    <div>
      <button onClick={onBack} className="flex items-center text-secondary-500 hover:text-secondary-600 mb-4">
        <svg className="w-5 h-5 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" /></svg>
        {backLabel}
      </button>
      <Card className="p-6">
        <div className="flex justify-between items-start mb-6">
          <div>
            <h2 className="text-xl font-bold text-gray-900">{call.callee_name}</h2>
            <p className="text-gray-500">{call.mobile_number}</p>
          </div>
          <StatusBadge status={call.status} />
        </div>

        {/* Agent Info */}
        <div className="bg-secondary-50 border border-secondary-200 rounded-lg p-4 mb-6">
          <p className="text-xs text-secondary-600 mb-1">Agent</p>
          <p className="font-semibold text-secondary-800">{agentName}</p>
        </div>

        <div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
          <div className="bg-gray-50 p-3 rounded-lg">
            <p className="text-xs text-gray-500">Duration</p>
            <p className="font-medium">{call.duration_minutes ? `${call.duration_minutes.toFixed(1)} min` : '-'}</p>
          </div>
          <div className="bg-gray-50 p-3 rounded-lg">
            <p className="text-xs text-gray-500">Engagement</p>
            <p className="font-medium">{call.engagement_status || '-'}</p>
          </div>
          <div className="bg-gray-50 p-3 rounded-lg">
            <p className="text-xs text-gray-500">Answered By</p>
            <p className="font-medium">{call.answered_by || '-'}</p>
          </div>
          <div className="bg-gray-50 p-3 rounded-lg">
            <p className="text-xs text-gray-500">Created</p>
            <p className="font-medium">{new Date(call.created_at).toLocaleString()}</p>
          </div>
        </div>

        {/* Custom Variables / Data */}
        {call.custom_data && Object.keys(call.custom_data).length > 0 && (
          <div className="mb-6">
            <h4 className="font-medium text-gray-700 mb-2">Custom Variables</h4>
            <div className="bg-gray-50 p-3 rounded-lg">
              <div className="grid grid-cols-2 md:grid-cols-3 gap-3">
                {Object.entries(call.custom_data).map(([key, value]) => (
                  <div key={key}>
                    <p className="text-xs text-gray-500">{key}</p>
                    <p className="font-medium text-sm">{value}</p>
                  </div>
                ))}
              </div>
            </div>
          </div>
        )}

        {call.recording_url && (
          <div className="mb-6">
            <h4 className="font-medium text-gray-700 mb-2">Recording</h4>
            <audio controls src={call.recording_url} className="w-full" />
          </div>
        )}
        {call.result && Object.keys(call.result).length > 0 && (
          <div>
            <h4 className="font-medium text-gray-700 mb-2">Call Result</h4>
            <pre className="bg-gray-50 p-3 rounded-lg text-sm overflow-auto">{JSON.stringify(call.result, null, 2)}</pre>
          </div>
        )}
      </Card>
    </div>
  );
};

const CallsSection = () => {
  const [view, setView] = useState('history');
  const [agents, setAgents] = useState([]);

  useEffect(() => {
    api.listAgents().then(data => setAgents(data.results)).catch(console.error);
  }, []);

  return (
    <div>
      <div className="flex gap-2 mb-6">
        <Button variant={view === 'history' ? 'primary' : 'outline'} onClick={() => setView('history')}>Call History</Button>
        <Button variant={view === 'quick' ? 'primary' : 'outline'} onClick={() => setView('quick')}>Quick Call</Button>
        <Button variant={view === 'bulk' ? 'primary' : 'outline'} onClick={() => setView('bulk')}>Bulk Calls</Button>
      </div>

      {view === 'history' && <CallHistory agents={agents} />}
      {view === 'quick' && <QuickCall agents={agents} onSuccess={() => setView('history')} />}
      {view === 'bulk' && <BulkCalls agents={agents} onSuccess={() => setView('history')} />}
    </div>
  );
};

// ============================================================================
// CAMPAIGNS SECTION
// ============================================================================

// CSV Parser utility
const parseCSV = (text: string): { headers: string[]; rows: string[][] } => {
  const lines = text.split('\n').filter(line => line.trim());
  if (lines.length === 0) return { headers: [], rows: [] };

  const parseRow = (row: string): string[] => {
    const result: string[] = [];
    let current = '';
    let inQuotes = false;

    for (let i = 0; i < row.length; i++) {
      const char = row[i];
      if (char === '"') {
        inQuotes = !inQuotes;
      } else if (char === ',' && !inQuotes) {
        result.push(current.trim());
        current = '';
      } else {
        current += char;
      }
    }
    result.push(current.trim());
    return result;
  };

  const headers = parseRow(lines[0]);
  const rows = lines.slice(1).map(parseRow);
  return { headers, rows };
};

const CreateCampaignWizard = ({ agents, onSuccess, onCancel }: { agents: Agent[]; onSuccess: () => void; onCancel: () => void }) => {
  const [step, setStep] = useState(1);
  const [name, setName] = useState('');
  const [agentId, setAgentId] = useState('');
  const [selectedAgent, setSelectedAgent] = useState(null);
  const [file, setFile] = useState(null);
  const [csvData, setCsvData] = useState({ headers: [], rows: [] });
  const [columnMapping, setColumnMapping] = useState({});
  const [removeInvalidRows, setRemoveInvalidRows] = useState(true);
  const [removeDuplicates, setRemoveDuplicates] = useState(true);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  // Retry configuration
  const [enableRedials, setEnableRedials] = useState(false);
  const [maxRedialCount, setMaxRedialCount] = useState(2);
  const [redialInterval, setRedialInterval] = useState(6); // hours

  // Required fields for mapping
  const requiredFields = [
    { key: 'callee_name', label: 'Candidate Name', required: true },
    { key: 'mobile_number', label: 'Phone Number', required: true },
  ];

  // Get custom variables from agent
  const customVariables = selectedAgent?.custom_variables || [];

  // All fields that can be mapped
  const allMappableFields = [
    ...requiredFields,
    ...customVariables.map(v => ({ key: v, label: v, required: false }))
  ];

  // Handle agent selection
  const handleAgentSelect = async (id: string) => {
    setAgentId(id);
    if (id) {
      try {
        const agent = await api.getAgent(id);
        setSelectedAgent(agent);
      } catch (err) {
        console.error(err);
      }
    } else {
      setSelectedAgent(null);
    }
  };

  // Handle file upload and parsing
  const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const uploadedFile = e.target.files?.[0];
    if (!uploadedFile) return;

    setFile(uploadedFile);
    const reader = new FileReader();
    reader.onload = (event) => {
      const text = event.target?.result;
      if (typeof text === 'string') {
        const parsed = parseCSV(text);
        setCsvData(parsed);

        // Auto-map columns if names match
        const autoMapping = {};
        allMappableFields.forEach(field => {
          const matchingHeader = parsed.headers.find(h =>
            h.toLowerCase().replace(/[_\s]/g, '') === field.key.toLowerCase().replace(/[_\s]/g, '') ||
            h.toLowerCase().includes(field.key.toLowerCase())
          );
          if (matchingHeader) {
            autoMapping[field.key] = matchingHeader;
          }
        });
        setColumnMapping(autoMapping);
      }
    };
    reader.readAsText(uploadedFile);
  };

  // Update column mapping
  const updateMapping = (fieldKey: string, csvColumn: string) => {
    setColumnMapping(prev => ({
      ...prev,
      [fieldKey]: csvColumn || undefined
    }));
  };

  // Check if step 1 is valid
  const isStep1Valid = name.trim() && agentId;

  // Check if step 2 is valid
  const isStep2Valid = file && columnMapping['callee_name'] && columnMapping['mobile_number'];

  // Handle form submission
  const handleSubmit = async () => {
    if (!file || !isStep2Valid) return;

    setLoading(true);
    setError('');
    try {
      const formData = new FormData();
      formData.append('file', file);
      formData.append('data', JSON.stringify({
        name,
        agent_id: agentId,
        column_mapping: columnMapping,
        remove_invalid_rows: removeInvalidRows,
        remove_duplicate_phone_numbers: removeDuplicates,
        ...(enableRedials && {
          retry_config: {
            max_retry_count: maxRedialCount,
            retry_interval_hours: redialInterval,
          }
        }),
      }));
      await api.createCampaign(formData);
      onSuccess();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'An error occurred');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      {/* Breadcrumb */}
      <div className="text-sm text-gray-500 mb-2">
        Campaigns / <span className="text-gray-900">New Campaign</span>
      </div>

      {/* Step indicator */}
      <div className="flex items-center gap-2 text-sm text-gray-500 mb-2">
        <span>Step {step} of 2</span>
        <span>•</span>
        <span>{step === 1 ? 'Choose Agent' : 'Calling list'}</span>
      </div>

      {/* Title */}
      <h1 className="text-2xl font-bold text-gray-900 mb-1">
        {step === 1 ? 'New Campaign' : name || 'New Campaign'}
      </h1>
      <p className="text-gray-500 mb-6">
        {step === 1 ? (agentId ? `Agent: ${agents.find(a => a.id === agentId)?.name}` : 'Agent not selected') : `Agent: ${agents.find(a => a.id === agentId)?.name}`}
      </p>

      {error && <Alert type="error" message={error} onClose={() => setError('')} />}

      {step === 1 && (
        <Card className="p-6 max-w-xl">
          <div className="mb-4">
            <label className="block text-sm font-medium text-gray-700 mb-1">
              Campaign name <span className="text-red-500">*</span>
            </label>
            <input
              type="text"
              value={name}
              onChange={e => setName(e.target.value)}
              placeholder="Eg: Hunar sourcing campaign..."
              className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-secondary-500 focus:border-secondary-500 outline-none"
            />
          </div>

          <div className="mb-4">
            <label className="block text-sm font-medium text-gray-700 mb-1">
              Choose campaign Agent <span className="text-red-500">*</span>
            </label>
            <select
              value={agentId}
              onChange={e => handleAgentSelect(e.target.value)}
              className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-secondary-500 focus:border-secondary-500 outline-none bg-white"
            >
              <option value="">Choose agent</option>
              {agents.filter(a => a.status === 'ACTIVE').map(a => <option key={a.id} value={a.id}>{a.name}</option>)}
            </select>
          </div>

          {/* Retry Configuration */}
          <div className="mt-6 pt-6 border-t border-gray-200">
            <div className="flex items-center justify-between mb-4">
              <div>
                <label className="block text-sm font-medium text-gray-700">Enable Retries</label>
                <p className="text-xs text-gray-500">Automatically retry failed or unanswered calls</p>
              </div>
              <button
                type="button"
                onClick={() => setEnableRedials(!enableRedials)}
                className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${enableRedials ? 'bg-secondary-500' : 'bg-gray-300'}`}
              >
                <span className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${enableRedials ? 'translate-x-6' : 'translate-x-1'}`} />
              </button>
            </div>

            {enableRedials && (
              <div className="space-y-4 bg-gray-50 rounded-lg p-4">
                <div>
                  <label className="block text-sm font-medium text-gray-700 mb-1">
                    Maximum Retry Count
                  </label>
                  <select
                    value={maxRedialCount}
                    onChange={e => setMaxRedialCount(Number(e.target.value))}
                    className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-secondary-500 focus:border-secondary-500 outline-none bg-white"
                  >
                    <option value={1}>1 attempt</option>
                    <option value={2}>2 attempts</option>
                    <option value={3}>3 attempts</option>
                    <option value={4}>4 attempts</option>
                    <option value={5}>5 attempts</option>
                  </select>
                  <p className="text-xs text-gray-500 mt-1">Number of times to retry if call is not connected</p>
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 mb-1">
                    Retry Interval
                  </label>
                  <select
                    value={redialInterval}
                    onChange={e => setRedialInterval(Number(e.target.value))}
                    className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-secondary-500 focus:border-secondary-500 outline-none bg-white"
                  >
                    <option value={1}>1 hour</option>
                    <option value={2}>2 hours</option>
                    <option value={4}>4 hours</option>
                    <option value={6}>6 hours</option>
                    <option value={12}>12 hours</option>
                    <option value={24}>24 hours</option>
                  </select>
                  <p className="text-xs text-gray-500 mt-1">Time to wait between retry attempts</p>
                </div>
              </div>
            )}
          </div>
        </Card>
      )}

      {step === 2 && (
        <div className="grid grid-cols-2 gap-6">
          {/* Left side - Upload and mapping */}
          <Card className="p-6">
            <div className="mb-6">
              <div className="flex items-center justify-between mb-2">
                <label className="block text-sm font-medium text-gray-700">
                  CSV <span className="text-red-500">*</span>
                </label>
                <button className="text-sm text-gray-500 hover:text-gray-700 flex items-center gap-1">
                  Download CSV format
                  <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
                  </svg>
                </button>
              </div>

              {!file ? (
                <label className="flex items-center justify-center w-full h-32 border-2 border-dashed border-gray-300 rounded-lg cursor-pointer hover:border-secondary-500 transition-colors">
                  <div className="text-center">
                    <svg className="w-8 h-8 mx-auto text-gray-400 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
                    </svg>
                    <p className="text-sm text-gray-500">Click to upload CSV</p>
                  </div>
                  <input type="file" accept=".csv" onChange={handleFileUpload} className="hidden" />
                </label>
              ) : (
                <div className="flex items-center justify-between p-3 bg-gray-50 rounded-lg border border-gray-200">
                  <div className="flex items-center gap-2">
                    <svg className="w-5 h-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
                    </svg>
                    <span className="text-sm font-medium">{file.name}</span>
                    <span className="text-sm text-gray-500">{(file.size / 1024).toFixed(0)} KB</span>
                  </div>
                  <button onClick={() => { setFile(null); setCsvData({ headers: [], rows: [] }); setColumnMapping({}); }} className="text-gray-400 hover:text-gray-600">
                    <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                    </svg>
                  </button>
                </div>
              )}
            </div>

            {csvData.headers.length > 0 && (
              <>
                <div className="mb-6">
                  <label className="block text-sm font-medium text-gray-700 mb-3">
                    Map CSV Columns <span className="text-red-500">*</span>
                  </label>
                  <div className="space-y-3">
                    {allMappableFields.map(field => (
                      <div key={field.key} className="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
                        <span className="text-sm text-gray-700">{field.key}</span>
                        <select
                          value={columnMapping[field.key] || ''}
                          onChange={e => updateMapping(field.key, e.target.value)}
                          className="px-3 py-1.5 border border-gray-300 rounded-lg bg-white text-sm min-w-40"
                        >
                          <option value="">Choose column</option>
                          {csvData.headers.map(h => <option key={h} value={h}>{h}</option>)}
                        </select>
                      </div>
                    ))}
                  </div>
                </div>

                <div className="space-y-3">
                  <label className="flex items-start gap-3 cursor-pointer">
                    <input
                      type="checkbox"
                      checked={removeInvalidRows}
                      onChange={e => setRemoveInvalidRows(e.target.checked)}
                      className="mt-0.5 w-4 h-4 text-secondary-500 rounded border-gray-300 focus:ring-secondary-500"
                    />
                    <div>
                      <p className="text-sm font-medium text-gray-700">Remove invalid rows</p>
                      <p className="text-xs text-gray-500">Automatically remove entries with invalid data (eg: incomplete numbers).</p>
                    </div>
                  </label>
                  <label className="flex items-start gap-3 cursor-pointer">
                    <input
                      type="checkbox"
                      checked={removeDuplicates}
                      onChange={e => setRemoveDuplicates(e.target.checked)}
                      className="mt-0.5 w-4 h-4 text-secondary-500 rounded border-gray-300 focus:ring-secondary-500"
                    />
                    <div>
                      <p className="text-sm font-medium text-gray-700">Remove duplicate phone numbers</p>
                      <p className="text-xs text-gray-500">Automatically remove numbers which occur more than once.</p>
                    </div>
                  </label>
                </div>
              </>
            )}
          </Card>

          {/* Right side - Preview */}
          <Card className="p-6">
            {csvData.headers.length > 0 ? (
              <>
                <div className="flex items-center justify-between mb-4">
                  <div className="flex items-center gap-2">
                    <svg className="w-5 h-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2" />
                    </svg>
                    <span className="text-sm font-medium">{file?.name}</span>
                  </div>
                  <span className="text-sm text-gray-500">{csvData.rows.length.toLocaleString()} entries</span>
                </div>
                <div className="overflow-x-auto max-h-96 overflow-y-auto">
                  <table className="w-full text-sm">
                    <thead className="sticky top-0 bg-gray-50">
                      <tr>
                        {csvData.headers.slice(0, 4).map(h => (
                          <th key={h} className="px-3 py-2 text-left font-medium text-gray-700 border-b">{h}</th>
                        ))}
                      </tr>
                    </thead>
                    <tbody>
                      {csvData.rows.slice(0, 10).map((row, i) => (
                        <tr key={i} className="border-b border-gray-100">
                          {row.slice(0, 4).map((cell, j) => (
                            <td key={j} className="px-3 py-2 text-gray-600">{cell}</td>
                          ))}
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
                {csvData.rows.length > 10 && (
                  <p className="text-xs text-gray-500 mt-2 text-center">Showing first 10 of {csvData.rows.length} rows</p>
                )}
              </>
            ) : (
              <div className="flex items-center justify-center h-64 text-gray-400">
                <div className="text-center">
                  <svg className="w-12 h-12 mx-auto mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
                  </svg>
                  <p className="text-sm">Upload a CSV to see preview</p>
                </div>
              </div>
            )}
          </Card>
        </div>
      )}

      {/* Footer buttons */}
      <div className="flex items-center justify-between mt-8 pt-6 border-t border-gray-200">
        <button
          onClick={onCancel}
          className="px-4 py-2 text-red-600 hover:text-red-700 font-medium"
        >
          Cancel
        </button>
        <div className="flex items-center gap-3">
          {step > 1 && (
            <Button variant="outline" onClick={() => setStep(step - 1)}>
              Back
            </Button>
          )}
          {step === 1 ? (
            <Button onClick={() => setStep(2)} disabled={!isStep1Valid}>
              Proceed
            </Button>
          ) : (
            <Button onClick={handleSubmit} disabled={!isStep2Valid || loading}>
              {loading ? 'Creating...' : 'Create Campaign'}
            </Button>
          )}
        </div>
      </div>
    </div>
  );
};

const CampaignList = ({ onSelect, onCreate, agents }: { onSelect: (id: string) => void; onCreate: () => void; agents: Agent[] }) => {
  const [campaigns, setCampaigns] = useState([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState('');
  const [statusFilter, setStatusFilter] = useState('');
  const [agentFilter, setAgentFilter] = useState('');
  const [dateFilter, setDateFilter] = useState('30days');
  const [currentPage, setCurrentPage] = useState(1);
  const [sortOrder, setSortOrder] = useState('desc'); // 'asc' or 'desc' - Sort by start time
  const pageSize = 10;

  useEffect(() => {
    api.listCampaigns().then(data => setCampaigns(data.results)).catch(console.error).finally(() => setLoading(false));
  }, []);

  // Get date cutoff based on filter
  const getDateCutoff = () => {
    const now = new Date();
    const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    switch (dateFilter) {
      case 'today': return today;
      case 'yesterday': return new Date(today.getTime() - 24 * 60 * 60 * 1000);
      case '7days': return new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
      case '30days': return new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
      default: return null; // no filter
    }
  };

  // Filter campaigns by date first
  const dateFilteredCampaigns = campaigns.filter(c => {
    const cutoff = getDateCutoff();
    if (!cutoff) return true;
    const campaignDate = new Date(c.created_at);
    return campaignDate >= cutoff;
  });

  // Calculate stats from date-filtered campaigns
  const stats = {
    totalCalls: dateFilteredCampaigns.reduce((sum, c) => sum + c.total_call_count, 0),
    connectedCalls: dateFilteredCampaigns.reduce((sum, c) => sum + c.connected_call_count, 0),
    engagedCalls: dateFilteredCampaigns.reduce((sum, c) => sum + c.engaged_call_count, 0),
    completedCampaigns: dateFilteredCampaigns.filter(c => c.status === 'COMPLETED').length,
    inProgressCampaigns: dateFilteredCampaigns.filter(c => c.status === 'IN_PROGRESS').length,
  };
  const connectionRate = stats.totalCalls > 0 ? Math.round((stats.connectedCalls / stats.totalCalls) * 100) : 0;
  const engagementRate = stats.connectedCalls > 0 ? Math.round((stats.engagedCalls / stats.connectedCalls) * 100) : 0;

  // Apply additional filters (search, status, agent)
  const filteredCampaigns = dateFilteredCampaigns
    .filter(c => {
      if (search && !c.name.toLowerCase().includes(search.toLowerCase())) return false;
      if (statusFilter && c.status !== statusFilter) return false;
      if (agentFilter && c.agent.id !== agentFilter) return false;
      return true;
    })
    .sort((a, b) => {
      const dateA = a.started_at ? new Date(a.started_at).getTime() : 0;
      const dateB = b.started_at ? new Date(b.started_at).getTime() : 0;
      return sortOrder === 'desc' ? dateB - dateA : dateA - dateB;
    });

  // Export campaigns to CSV
  const handleExportCampaigns = () => {
    if (filteredCampaigns.length === 0) {
      alert('No campaigns to export');
      return;
    }
    const headers = ['Name', 'Status', 'Agent', 'Total Calls', 'Connected', 'Not Connected', 'Failed', 'Engaged', 'Not Engaged', 'Created At', 'Started At'];
    const rows = filteredCampaigns.map(c => [
      c.name,
      c.status,
      c.agent.name,
      c.total_call_count,
      c.connected_call_count,
      c.not_connected_call_count,
      c.failed_call_count,
      c.engaged_call_count,
      c.not_engaged_call_count,
      c.created_at,
      c.started_at || ''
    ]);
    const csvContent = [
      headers.join(','),
      ...rows.map(row => row.map(cell => `"${String(cell).replace(/"/g, '""')}"`).join(','))
    ].join('\n');
    const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = `campaigns_${new Date().toISOString().split('T')[0]}.csv`;
    link.click();
    URL.revokeObjectURL(link.href);
  };

  // Get greeting based on time
  const getGreeting = () => {
    const hour = new Date().getHours();
    if (hour < 12) return 'Good morning';
    if (hour < 17) return 'Good afternoon';
    return 'Good evening';
  };

  if (loading) return (
    <div>
      <div className="flex justify-between items-start mb-6">
        <div>
          <Skeleton className="h-4 w-24 mb-2" />
          <Skeleton className="h-8 w-48" />
        </div>
        <Skeleton className="h-10 w-40" />
      </div>
      <SkeletonStats />
      <SkeletonTable rows={5} />
    </div>
  );

  return (
    <PageTransition>
    <div>
      {/* Header */}
      <div className="flex justify-between items-start mb-6">
        <div>
          <p className="text-sm text-gray-500">All Campaigns</p>
          <h1 className="text-2xl font-bold text-gray-900">{getGreeting()}</h1>
        </div>
        <div className="flex items-center gap-3">
          <select
            value={dateFilter}
            onChange={e => { setDateFilter(e.target.value); setCurrentPage(1); }}
            className="px-3 py-2 border border-gray-300 rounded-lg bg-white text-sm"
          >
            <option value="today">Today</option>
            <option value="yesterday">Yesterday</option>
            <option value="7days">Last 7 days</option>
            <option value="30days">Last 30 days</option>
            <option value="all">No filter</option>
          </select>
          <Button onClick={onCreate}>+ New Campaign</Button>
        </div>
      </div>

      {/* Stats Cards */}
      <div className="grid grid-cols-4 gap-4 mb-8">
        <Card className="p-4">
          <div className="flex items-center justify-between mb-2">
            <p className="text-sm text-gray-500">Call connection rate</p>
            <svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
          </div>
          <p className="text-3xl font-bold text-gray-900">{connectionRate}%</p>
          <div className="mt-2 h-1.5 bg-gray-200 rounded-full overflow-hidden">
            <div className="h-full bg-green-500 rounded-full" style={{ width: `${connectionRate}%` }}></div>
          </div>
        </Card>
        <Card className="p-4">
          <div className="flex items-center justify-between mb-2">
            <p className="text-sm text-gray-500">Engagement rate</p>
            <svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
          </div>
          <p className="text-3xl font-bold text-gray-900">{engagementRate}%</p>
          <div className="mt-2 h-1.5 bg-gray-200 rounded-full overflow-hidden">
            <div className="h-full bg-secondary-500 rounded-full" style={{ width: `${engagementRate}%` }}></div>
          </div>
        </Card>
        <Card className="p-4">
          <div className="flex items-center justify-between mb-2">
            <p className="text-sm text-gray-500">Campaigns completed</p>
            <svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
          </div>
          <p className="text-3xl font-bold text-gray-900">{stats.completedCampaigns}</p>
        </Card>
        <Card className="p-4">
          <div className="flex items-center justify-between mb-2">
            <p className="text-sm text-gray-500">Campaigns in progress</p>
            <svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
          </div>
          <p className="text-3xl font-bold text-gray-900">{stats.inProgressCampaigns}</p>
        </Card>
      </div>

      {/* Filters Row */}
      <div className="flex items-center justify-between mb-4">
        <div className="flex items-center gap-3">
          <div className="relative">
            <svg className="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
            </svg>
            <input
              type="text"
              placeholder="Search by campaign..."
              value={search}
              onChange={e => setSearch(e.target.value)}
              className="pl-9 pr-4 py-2 border border-gray-300 rounded-lg text-sm w-64 focus:ring-2 focus:ring-secondary-500 focus:border-secondary-500 outline-none"
            />
          </div>
          <select
            value={statusFilter}
            onChange={e => setStatusFilter(e.target.value)}
            className="px-3 py-2 border border-gray-300 rounded-lg bg-white text-sm"
          >
            <option value="">Status</option>
            <option value="COMPLETED">Completed</option>
            <option value="IN_PROGRESS">In Progress</option>
            <option value="NOT_STARTED">Not Started</option>
            <option value="FAILED">Failed</option>
          </select>
          <select
            value={agentFilter}
            onChange={e => setAgentFilter(e.target.value)}
            className="px-3 py-2 border border-gray-300 rounded-lg bg-white text-sm"
          >
            <option value="">Agent</option>
            {agents.map(a => <option key={a.id} value={a.id}>{a.name}</option>)}
          </select>
        </div>
        <Button variant="outline" onClick={handleExportCampaigns} disabled={filteredCampaigns.length === 0} className="flex items-center gap-2">
          <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" />
          </svg>
          Export table
        </Button>
      </div>

      {/* Campaigns Table */}
      {(() => {
        const totalPages = Math.ceil(filteredCampaigns.length / pageSize);
        const paginatedCampaigns = filteredCampaigns.slice((currentPage - 1) * pageSize, currentPage * pageSize);

        if (filteredCampaigns.length === 0) {
          return (
            <Card className="p-8 text-center">
              <p className="text-gray-500 mb-4">{campaigns.length === 0 ? 'No campaigns yet' : 'No campaigns match your filters'}</p>
              {campaigns.length === 0 && <Button onClick={onCreate}>Create Campaign</Button>}
            </Card>
          );
        }
        return (
          <>
            <Card className="overflow-hidden">
              <table className="w-full">
                <thead>
                  <tr className="bg-gray-50 border-b border-gray-200">
                    <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Campaign name</th>
                    <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Status</th>
                    <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Calls completed</th>
                    <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">
                      <button
                        onClick={() => setSortOrder(s => s === 'desc' ? 'asc' : 'desc')}
                        className="flex items-center gap-1 hover:text-secondary-600 transition-colors"
                      >
                        Start time
                        <svg className={`w-4 h-4 transition-transform ${sortOrder === 'asc' ? 'rotate-180' : ''}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
                        </svg>
                      </button>
                    </th>
                    <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Agent</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-gray-200">
                  {paginatedCampaigns.map(campaign => (
                    <tr
                      key={campaign.id}
                      className="hover:bg-gray-50 cursor-pointer transition-colors"
                      onClick={() => onSelect(campaign.id)}
                    >
                      <td className="px-4 py-3">
                        <span className="text-secondary-600 font-medium hover:text-secondary-700">{campaign.name}</span>
                      </td>
                      <td className="px-4 py-3">
                        <StatusBadge status={campaign.status} />
                      </td>
                      <td className="px-4 py-3 text-sm text-gray-600">
                        {campaign.connected_call_count}/{campaign.total_call_count}
                      </td>
                      <td className="px-4 py-3 text-sm text-gray-600">
                        {campaign.started_at ? new Date(campaign.started_at).toLocaleString('en-US', { day: 'numeric', month: 'short', hour: 'numeric', minute: '2-digit', hour12: true }) : '-'}
                      </td>
                      <td className="px-4 py-3 text-sm text-gray-600">
                        {campaign.agent.name}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </Card>
            {/* Pagination */}
            {totalPages > 1 && (
              <div className="flex items-center justify-between mt-4">
                <p className="text-sm text-gray-500">
                  Showing {(currentPage - 1) * pageSize + 1} to {Math.min(currentPage * pageSize, filteredCampaigns.length)} of {filteredCampaigns.length} campaigns
                </p>
                <div className="flex items-center gap-2">
                  <Button variant="outline" onClick={() => setCurrentPage(p => Math.max(1, p - 1))} disabled={currentPage === 1}>
                    Previous
                  </Button>
                  <span className="text-sm text-gray-600">Page {currentPage} of {totalPages}</span>
                  <Button variant="outline" onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))} disabled={currentPage === totalPages}>
                    Next
                  </Button>
                </div>
              </div>
            )}
          </>
        );
      })()}
    </div>
    </PageTransition>
  );
};

const CampaignDetail = ({ campaignId, onBack }: { campaignId: string; onBack: () => void }) => {
  const [campaign, setCampaign] = useState(null);
  const [calls, setCalls] = useState([]);
  const [totalCount, setTotalCount] = useState(0);
  const [loading, setLoading] = useState(true);
  const [callsLoading, setCallsLoading] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);
  const [exporting, setExporting] = useState(false);
  const [page, setPage] = useState(1);
  const [filter, setFilter] = useState({
    status: '',
    engagementStatus: '',
    answeredBy: '',
    search: ''
  });
  const [selectedCall, setSelectedCall] = useState(null);

  useEffect(() => {
    api.getCampaign(campaignId).then(setCampaign).finally(() => setLoading(false));
  }, [campaignId]);

  const getFilterParams = useCallback(() => {
    const params: any = { campaignId };
    if (filter.status) params.status = [filter.status];
    if (filter.engagementStatus) params.engagementStatus = [filter.engagementStatus];
    if (filter.answeredBy) params.answeredBy = [filter.answeredBy];
    return params;
  }, [campaignId, filter]);

  const loadCalls = useCallback(async (resetPage = true) => {
    if (resetPage) {
      setCallsLoading(true);
      setPage(1);
    } else {
      setLoadingMore(true);
    }
    try {
      const params = getFilterParams();
      const currentPage = resetPage ? 1 : page;
      const data = await api.listCalls({ ...params, page: currentPage, pageSize: 100 });
      if (resetPage) {
        setCalls(data.results);
      } else {
        setCalls(prev => [...prev, ...data.results]);
      }
      setTotalCount(data.count);
    } catch (err) {
      console.error(err);
    } finally {
      setCallsLoading(false);
      setLoadingMore(false);
    }
  }, [filter, page, getFilterParams]);

  useEffect(() => { loadCalls(true); }, [filter, campaignId]);

  const loadMore = async () => {
    const nextPage = page + 1;
    setPage(nextPage);
    setLoadingMore(true);
    try {
      const params = getFilterParams();
      const data = await api.listCalls({ ...params, page: nextPage, pageSize: 100 });
      setCalls(prev => [...prev, ...data.results]);
    } catch (err) {
      console.error(err);
    } finally {
      setLoadingMore(false);
    }
  };

  const handleExport = async () => {
    if (!campaign) return;
    setExporting(true);
    try {
      const params = getFilterParams();
      const allCalls = await api.listAllCalls(params);
      const agentsMap = new Map([[campaign.agent.id, campaign.agent.name]]);
      exportCallsToCSV(allCalls, `campaign_${campaign.name.replace(/\s+/g, '_')}`, agentsMap);
    } catch (err) {
      console.error(err);
      alert('Failed to export calls');
    } finally {
      setExporting(false);
    }
  };

  if (loading) return (
    <div>
      <div className="flex items-center gap-2 mb-6">
        <Skeleton className="w-5 h-5" />
        <Skeleton className="h-4 w-64" />
      </div>
      <div className="grid grid-cols-6 gap-4 mb-6">
        {[1, 2, 3, 4, 5, 6].map(i => (
          <Card key={i} hover={false} className="p-4">
            <Skeleton className="h-4 w-16 mb-2" />
            <Skeleton className="h-8 w-12" />
          </Card>
        ))}
      </div>
      <SkeletonTable rows={5} />
    </div>
  );
  if (!campaign) return <Alert type="error" message="Campaign not found" />;

  const stats = [
    { label: 'Total Calls', value: campaign.total_call_count, color: 'bg-gray-100 text-gray-800' },
    { label: 'Connected', value: campaign.connected_call_count, color: 'bg-green-100 text-green-800' },
    { label: 'Not Connected', value: campaign.not_connected_call_count, color: 'bg-orange-100 text-orange-800' },
    { label: 'Failed', value: campaign.failed_call_count, color: 'bg-red-100 text-red-800' },
    { label: 'Engaged', value: campaign.engaged_call_count, color: 'bg-blue-100 text-blue-800' },
    { label: 'Not Engaged', value: campaign.not_engaged_call_count, color: 'bg-yellow-100 text-yellow-800' },
  ];

  const hasMore = calls.length < totalCount;

  if (selectedCall) {
    return (
      <CallDetail
        call={selectedCall}
        onBack={() => setSelectedCall(null)}
        backLabel="Back to Campaign"
        agents={[{ id: campaign.agent.id, name: campaign.agent.name }]}
      />
    );
  }

  // Calculate percentages for progress bars
  const total = campaign.total_call_count || 1;
  const connectedPct = Math.round((campaign.connected_call_count / total) * 100);
  const notConnectedPct = Math.round((campaign.not_connected_call_count / total) * 100);
  const failedPct = Math.round((campaign.failed_call_count / total) * 100);
  const engagedTotal = campaign.engaged_call_count + campaign.not_engaged_call_count || 1;
  const engagedPct = Math.round((campaign.engaged_call_count / engagedTotal) * 100);
  const notEngagedPct = 100 - engagedPct;

  return (
    <PageTransition>
    <div>
      {/* Header with breadcrumb */}
      <div className="flex items-center justify-between mb-6">
        <div className="flex items-center gap-2">
          <button onClick={onBack} className="p-1 hover:bg-gray-100 rounded transition-colors">
            <svg className="w-5 h-5 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
            </svg>
          </button>
          <nav className="text-sm text-gray-500">
            <span className="hover:text-gray-700 cursor-pointer transition-colors" onClick={onBack}>Dashboard</span>
            <span className="mx-2">/</span>
            <span className="hover:text-gray-700 cursor-pointer" onClick={onBack}>Campaigns</span>
            <span className="mx-2">/</span>
            <span className="text-gray-900 font-medium">{campaign.name}</span>
          </nav>
        </div>
        <div className="flex items-center gap-4">
          <div className="flex items-center gap-2">
            <span className="w-2 h-2 bg-green-500 rounded-full"></span>
            <span className="text-sm text-gray-600">Campaign progress</span>
            <div className="w-24 h-2 bg-gray-200 rounded-full overflow-hidden">
              <div
                className="h-full bg-secondary-500 rounded-full"
                style={{ width: `${Math.min(100, (campaign.connected_call_count / total) * 100)}%` }}
              ></div>
            </div>
            <span className="text-sm font-medium">{campaign.connected_call_count} / {campaign.total_call_count}</span>
          </div>
          <Button variant="outline" onClick={() => loadCalls(true)} className="flex items-center gap-2">
            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
            </svg>
            Refresh
          </Button>
        </div>
      </div>

      {/* Progress Bar Stats */}
      <div className="grid grid-cols-2 gap-6 mb-8">
        {/* Campaign Health */}
        <Card className="p-5">
          <div className="flex items-center gap-2 mb-4">
            <h3 className="text-sm font-medium text-gray-700">Campaign health</h3>
            <svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
          </div>
          {/* Stacked progress bar */}
          <div className="h-3 rounded-full overflow-hidden flex mb-4">
            <div className="bg-green-500" style={{ width: `${connectedPct}%` }}></div>
            <div className="bg-blue-400" style={{ width: `${notConnectedPct}%` }}></div>
            <div className="bg-red-500" style={{ width: `${failedPct}%` }}></div>
          </div>
          <div className="flex items-center gap-6 text-sm">
            <div className="flex items-center gap-2">
              <span className="w-3 h-3 bg-green-500 rounded-sm"></span>
              <span className="text-gray-600">Connected: <strong>{connectedPct}%</strong></span>
            </div>
            <div className="flex items-center gap-2">
              <span className="w-3 h-3 bg-blue-400 rounded-sm"></span>
              <span className="text-gray-600">No answer: <strong>{notConnectedPct}%</strong></span>
            </div>
            <div className="flex items-center gap-2">
              <span className="w-3 h-3 bg-red-500 rounded-sm"></span>
              <span className="text-gray-600">Failed: <strong>{failedPct}%</strong></span>
            </div>
          </div>
        </Card>

        {/* Engagement Rate */}
        <Card className="p-5">
          <div className="flex items-center gap-2 mb-4">
            <h3 className="text-sm font-medium text-gray-700">Engagement rate</h3>
            <svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
          </div>
          {/* Stacked progress bar */}
          <div className="h-3 rounded-full overflow-hidden flex mb-4">
            <div className="bg-green-500" style={{ width: `${engagedPct}%` }}></div>
            <div className="bg-red-400" style={{ width: `${notEngagedPct}%` }}></div>
          </div>
          <div className="flex items-center gap-6 text-sm">
            <div className="flex items-center gap-2">
              <span className="w-3 h-3 bg-green-500 rounded-sm"></span>
              <span className="text-gray-600">Engaged: <strong>{engagedPct}%</strong></span>
            </div>
            <div className="flex items-center gap-2">
              <span className="w-3 h-3 bg-red-400 rounded-sm"></span>
              <span className="text-gray-600">Not engaged: <strong>{notEngagedPct}%</strong></span>
            </div>
          </div>
        </Card>
      </div>

      {/* Filters Row */}
      <div className="flex flex-wrap items-center justify-between gap-4 mb-4">
        <div className="flex items-center gap-3">
          <div className="relative">
            <svg className="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
            </svg>
            <input
              type="text"
              placeholder="Search by name or number..."
              value={filter.search}
              onChange={e => setFilter(f => ({ ...f, search: e.target.value }))}
              className="pl-9 pr-4 py-2 border border-gray-300 rounded-lg text-sm w-64 focus:ring-2 focus:ring-secondary-500 focus:border-secondary-500 outline-none"
            />
          </div>
          <select
            value={filter.status}
            onChange={e => setFilter(f => ({ ...f, status: e.target.value }))}
            className="px-3 py-2 border border-gray-300 rounded-lg bg-white text-sm"
          >
            <option value="">Status</option>
            {CALL_STATUSES.map(s => <option key={s} value={s}>{s.replace(/_/g, ' ')}</option>)}
          </select>
          <select
            value={filter.engagementStatus}
            onChange={e => setFilter(f => ({ ...f, engagementStatus: e.target.value }))}
            className="px-3 py-2 border border-gray-300 rounded-lg bg-white text-sm"
          >
            <option value="">Engagement</option>
            {ENGAGEMENT_STATUSES.map(s => <option key={s} value={s}>{s.replace(/_/g, ' ')}</option>)}
          </select>
          <select
            value={filter.answeredBy}
            onChange={e => setFilter(f => ({ ...f, answeredBy: e.target.value }))}
            className="px-3 py-2 border border-gray-300 rounded-lg bg-white text-sm"
          >
            <option value="">Call ended by</option>
            {ANSWERED_BY_OPTIONS.map(s => <option key={s} value={s}>{s}</option>)}
          </select>
        </div>
        <Button variant="outline" onClick={handleExport} disabled={totalCount === 0 || exporting} className="flex items-center gap-2">
          <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" />
          </svg>
          {exporting ? 'Exporting...' : 'Export table'}
        </Button>
      </div>

      {(() => {
        // Apply client-side filters (status, engagement, answered_by, search)
        const filteredCalls = calls.filter(call => {
          if (filter.status && call.status?.toUpperCase() !== filter.status.toUpperCase()) return false;
          if (filter.engagementStatus && call.engagement_status?.toUpperCase() !== filter.engagementStatus.toUpperCase()) return false;
          if (filter.answeredBy && call.answered_by?.toUpperCase() !== filter.answeredBy.toUpperCase()) return false;
          if (filter.search) {
            const searchLower = filter.search.toLowerCase();
            if (!call.callee_name.toLowerCase().includes(searchLower) && !call.mobile_number.includes(filter.search)) {
              return false;
            }
          }
          return true;
        });

        if (callsLoading) return <LoadingSpinner />;
        if (filteredCalls.length === 0) {
          return (
            <Card className="p-8 text-center">
              <p className="text-gray-500">{filter.search ? 'No calls match your search' : 'No calls found in this campaign'}</p>
            </Card>
          );
        }
        return (
          <>
            <div className="overflow-x-auto">
              <table className="w-full">
                <thead>
                  <tr className="bg-gray-50">
                    <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Contact</th>
                    <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Phone</th>
                    <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Status</th>
                    <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Duration</th>
                    <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Engagement</th>
                    <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Answered By</th>
                    <th className="px-4 py-3 text-left text-sm font-medium text-gray-700">Date</th>
                    <th className="px-4 py-3 text-left text-sm font-medium text-gray-700"></th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-gray-200">
                  {filteredCalls.map(call => (
                    <tr key={call.id} className="hover:bg-gray-50 transition-colors">
                      <td className="px-4 py-3 text-sm">{call.callee_name}</td>
                      <td className="px-4 py-3 text-sm text-gray-500">{call.mobile_number}</td>
                      <td className="px-4 py-3"><StatusBadge status={call.status} /></td>
                      <td className="px-4 py-3 text-sm text-gray-500">{call.duration_minutes ? `${call.duration_minutes.toFixed(1)} min` : '-'}</td>
                      <td className="px-4 py-3 text-sm text-gray-500">{call.engagement_status || '-'}</td>
                      <td className="px-4 py-3 text-sm text-gray-500">{call.answered_by || '-'}</td>
                      <td className="px-4 py-3 text-sm text-gray-500">{new Date(call.created_at).toLocaleDateString()}</td>
                      <td className="px-4 py-3"><Button variant="outline" onClick={() => setSelectedCall(call)}>View</Button></td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>

            {hasMore && !filter.search && (
              <div className="mt-6 text-center">
                <Button variant="outline" onClick={loadMore} disabled={loadingMore}>
                  {loadingMore ? 'Loading...' : `Load More (${totalCount - calls.length} remaining)`}
                </Button>
              </div>
            )}
          </>
        );
      })()}
    </div>
    </PageTransition>
  );
};

const CampaignsSection = () => {
  const [view, setView] = useState('list');
  const [selectedCampaignId, setSelectedCampaignId] = useState(null);
  const [agents, setAgents] = useState([]);
  const [successMsg, setSuccessMsg] = useState('');
  const [listKey, setListKey] = useState(0);

  useEffect(() => {
    api.listAgents().then(data => setAgents(data.results)).catch(console.error);
  }, []);

  const handleCampaignCreated = () => {
    setSuccessMsg('Campaign created!');
    setListKey(k => k + 1); // Force list reload
    setView('list');
  };

  return (
    <div>
      {successMsg && <Alert type="success" message={successMsg} onClose={() => setSuccessMsg('')} />}

      {view === 'list' && (
        <CampaignList
          key={listKey}
          onSelect={id => { setSelectedCampaignId(id); setView('view'); }}
          onCreate={() => setView('create')}
          agents={agents}
        />
      )}
      {view === 'create' && (
        <CreateCampaignWizard
          agents={agents}
          onSuccess={handleCampaignCreated}
          onCancel={() => setView('list')}
        />
      )}
      {view === 'view' && selectedCampaignId && (
        <CampaignDetail campaignId={selectedCampaignId} onBack={() => setView('list')} />
      )}
    </div>
  );
};

// ============================================================================
// USERS SECTION
// ============================================================================
const UsersSection = () => {
  const [users, setUsers] = useState([]);
  const [invites, setInvites] = useState([]);
  const [loading, setLoading] = useState(true);
  const [showInviteModal, setShowInviteModal] = useState(false);
  const [inviteEmail, setInviteEmail] = useState('');
  const [inviteName, setInviteName] = useState('');
  const [inviteLoading, setInviteLoading] = useState(false);
  const [error, setError] = useState('');
  const [success, setSuccess] = useState('');
  const [inviteLink, setInviteLink] = useState('');
  const [linkCopied, setLinkCopied] = useState(false);
  const [copiedInviteEmail, setCopiedInviteEmail] = useState('');

  const loadData = async () => {
    setLoading(true);
    try {
      const [usersData, invitesData] = await Promise.all([
        authService.getAllUsers(),
        authService.getPendingInvites()
      ]);
      setUsers(usersData);
      setInvites(invitesData);
    } catch (err) {
      console.error('Error loading users:', err);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    if (isFirebaseConfigured()) {
      loadData();
    } else {
      setLoading(false);
    }
  }, []);

  const handleInvite = async (e: React.FormEvent) => {
    e.preventDefault();
    setInviteLoading(true);
    setError('');
    setInviteLink('');
    setLinkCopied(false);

    try {
      const link = await authService.inviteUser(inviteEmail, inviteName);
      setInviteLink(link);
      loadData();
    } catch (err) {
      setError(err.message || 'Failed to create invitation');
    } finally {
      setInviteLoading(false);
    }
  };

  const handleCopyLink = async () => {
    try {
      await navigator.clipboard.writeText(inviteLink);
      setLinkCopied(true);
      setTimeout(() => setLinkCopied(false), 2000);
    } catch (err) {
      // Fallback for older browsers
      const textArea = document.createElement('textarea');
      textArea.value = inviteLink;
      document.body.appendChild(textArea);
      textArea.select();
      document.execCommand('copy');
      document.body.removeChild(textArea);
      setLinkCopied(true);
      setTimeout(() => setLinkCopied(false), 2000);
    }
  };

  const handleCopyInviteLink = async (email: string, name: string) => {
    const link = `${window.location.origin}?invite=${encodeURIComponent(email)}&name=${encodeURIComponent(name)}`;
    try {
      await navigator.clipboard.writeText(link);
      setCopiedInviteEmail(email);
      setTimeout(() => setCopiedInviteEmail(''), 2000);
    } catch (err) {
      // Fallback for older browsers
      const textArea = document.createElement('textarea');
      textArea.value = link;
      document.body.appendChild(textArea);
      textArea.select();
      document.execCommand('copy');
      document.body.removeChild(textArea);
      setCopiedInviteEmail(email);
      setTimeout(() => setCopiedInviteEmail(''), 2000);
    }
  };

  const handleCloseInviteModal = () => {
    const wasInviteCreated = !!inviteLink;
    const invitedEmail = inviteEmail;
    setShowInviteModal(false);
    setInviteEmail('');
    setInviteName('');
    setInviteLink('');
    setLinkCopied(false);
    setError('');
    if (wasInviteCreated) {
      setSuccess(`Invitation created for ${invitedEmail}`);
    }
  };

  const handleRevokeInvite = async (email: string) => {
    if (!confirm(`Revoke invitation for ${email}?`)) return;
    try {
      await authService.revokeInvite(email);
      loadData();
    } catch (err) {
      alert(err.message || 'Failed to revoke invitation');
    }
  };

  const handleToggleUserStatus = async (user: AppUser) => {
    const action = user.status === 'active' ? 'deactivate' : 'reactivate';
    if (!confirm(`${action.charAt(0).toUpperCase() + action.slice(1)} ${user.name}?`)) return;
    try {
      if (user.status === 'active') {
        await authService.deactivateUser(user.uid);
      } else {
        await authService.reactivateUser(user.uid);
      }
      loadData();
    } catch (err) {
      alert(err.message || `Failed to ${action} user`);
    }
  };

  if (!isFirebaseConfigured()) {
    return (
      <div className="animate-fade-in">
        <div className="mb-6">
          <h1 className="text-2xl font-bold text-gray-900">User Management</h1>
          <p className="text-gray-500 mt-1">Manage users and invitations</p>
        </div>
        <Card className="p-8 text-center">
          <div className="w-16 h-16 bg-yellow-100 rounded-full flex items-center justify-center mx-auto mb-4">
            <svg className="w-8 h-8 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
            </svg>
          </div>
          <h2 className="text-lg font-semibold text-gray-900 mb-2">Firebase Not Configured</h2>
          <p className="text-gray-500 mb-4">
            To use user management, you need to configure Firebase.
          </p>
          <p className="text-sm text-gray-400">
            See FIREBASE_SETUP.md for instructions.
          </p>
        </Card>
      </div>
    );
  }

  if (loading) {
    return (
      <div className="animate-fade-in">
        <div className="mb-6">
          <h1 className="text-2xl font-bold text-gray-900">User Management</h1>
          <p className="text-gray-500 mt-1">Manage users and invitations</p>
        </div>
        <div className="space-y-4">
          {[1, 2, 3].map(i => (
            <div key={i} className="bg-white rounded-lg border border-gray-200 p-4 animate-pulse">
              <div className="flex items-center gap-4">
                <div className="w-10 h-10 bg-gray-200 rounded-full" />
                <div className="flex-1">
                  <div className="h-4 bg-gray-200 rounded w-1/3 mb-2" />
                  <div className="h-3 bg-gray-100 rounded w-1/4" />
                </div>
              </div>
            </div>
          ))}
        </div>
      </div>
    );
  }

  return (
    <div className="animate-fade-in">
      {/* Header */}
      <div className="flex items-center justify-between mb-6">
        <div>
          <h1 className="text-2xl font-bold text-gray-900">User Management</h1>
          <p className="text-gray-500 mt-1">{users.length} users, {invites.length} pending invites</p>
        </div>
        <Button onClick={() => setShowInviteModal(true)}>+ Invite User</Button>
      </div>

      {success && <Alert type="success" message={success} onClose={() => setSuccess('')} />}
      {error && <Alert type="error" message={error} onClose={() => setError('')} />}

      {/* Pending Invites */}
      {invites.length > 0 && (
        <div className="mb-8">
          <h2 className="text-lg font-semibold text-gray-900 mb-4">Pending Invitations</h2>
          <div className="space-y-3">
            {invites.map(invite => (
              <Card key={invite.email} className="p-4">
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-3">
                    <div className="w-10 h-10 bg-yellow-100 rounded-full flex items-center justify-center">
                      <svg className="w-5 h-5 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
                      </svg>
                    </div>
                    <div>
                      <p className="font-medium text-gray-900">{invite.name}</p>
                      <p className="text-sm text-gray-500">{invite.email}</p>
                    </div>
                  </div>
                  <div className="flex items-center gap-2">
                    <span className="px-2 py-1 text-xs font-medium bg-yellow-100 text-yellow-800 rounded">
                      Pending
                    </span>
                    <button
                      onClick={() => handleCopyInviteLink(invite.email, invite.name)}
                      className={`p-2 rounded-lg transition-colors ${copiedInviteEmail === invite.email ? 'text-green-600 bg-green-50' : 'text-gray-400 hover:text-secondary-600 hover:bg-secondary-50'}`}
                      title={copiedInviteEmail === invite.email ? 'Copied!' : 'Copy invite link'}
                    >
                      {copiedInviteEmail === invite.email ? (
                        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
                        </svg>
                      ) : (
                        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
                        </svg>
                      )}
                    </button>
                    <button
                      onClick={() => handleRevokeInvite(invite.email)}
                      className="p-2 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors"
                      title="Revoke invitation"
                    >
                      <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
                      </svg>
                    </button>
                  </div>
                </div>
              </Card>
            ))}
          </div>
        </div>
      )}

      {/* Active Users */}
      <div>
        <h2 className="text-lg font-semibold text-gray-900 mb-4">Users</h2>
        {users.length === 0 ? (
          <Card className="p-8 text-center">
            <div className="w-12 h-12 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
              <svg className="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
              </svg>
            </div>
            <h3 className="text-lg font-medium text-gray-900 mb-2">No users yet</h3>
            <p className="text-gray-500 mb-4">Invite team members to collaborate on your campaigns</p>
            <Button onClick={() => setShowInviteModal(true)}>+ Invite User</Button>
          </Card>
        ) : (
          <div className="space-y-3">
            {users.map(user => (
              <Card key={user.uid} className="p-4">
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-3">
                    <div className={`w-10 h-10 rounded-full flex items-center justify-center text-white font-medium ${user.status === 'active' ? 'bg-secondary-500' : 'bg-gray-400'}`}>
                      {user.name?.charAt(0).toUpperCase() || 'U'}
                    </div>
                    <div>
                      <p className="font-medium text-gray-900">{user.name}</p>
                      <p className="text-sm text-gray-500">{user.email}</p>
                    </div>
                  </div>
                  <div className="flex items-center gap-2">
                    <span className={`px-2 py-1 text-xs font-medium rounded ${user.status === 'active' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-600'}`}>
                      {user.status === 'active' ? 'Active' : 'Inactive'}
                    </span>
                    <button
                      onClick={() => handleToggleUserStatus(user)}
                      className={`p-2 rounded-lg transition-colors ${user.status === 'active' ? 'text-gray-400 hover:text-red-600 hover:bg-red-50' : 'text-gray-400 hover:text-green-600 hover:bg-green-50'}`}
                      title={user.status === 'active' ? 'Deactivate user' : 'Reactivate user'}
                    >
                      {user.status === 'active' ? (
                        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636" />
                        </svg>
                      ) : (
                        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
                        </svg>
                      )}
                    </button>
                  </div>
                </div>
              </Card>
            ))}
          </div>
        )}
      </div>

      {/* Invite Modal */}
      {showInviteModal && (
        <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50">
          <Card className="w-full max-w-md p-6">
            <div className="flex items-center justify-between mb-4">
              <h2 className="text-lg font-semibold text-gray-900">
                {inviteLink ? 'Invitation Created' : 'Invite User'}
              </h2>
              <button onClick={handleCloseInviteModal} className="p-1 text-gray-400 hover:text-gray-600">
                <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                </svg>
              </button>
            </div>

            {inviteLink ? (
              <div>
                <div className="mb-4">
                  <div className="w-12 h-12 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-3">
                    <svg className="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
                    </svg>
                  </div>
                  <p className="text-center text-gray-600 mb-4">
                    Share this link with <strong>{inviteName}</strong> to let them set up their account:
                  </p>
                  <div className="bg-gray-50 border border-gray-200 rounded-lg p-3 mb-3">
                    <p className="text-sm text-gray-700 break-all font-mono">{inviteLink}</p>
                  </div>
                </div>
                <div className="flex gap-3">
                  <Button type="button" variant="secondary" onClick={handleCloseInviteModal} className="flex-1">
                    Close
                  </Button>
                  <Button type="button" onClick={handleCopyLink} className="flex-1">
                    {linkCopied ? 'Copied!' : 'Copy Link'}
                  </Button>
                </div>
              </div>
            ) : (
              <form onSubmit={handleInvite}>
                {error && (
                  <div className="mb-4 p-3 bg-red-50 border border-red-200 rounded-lg text-red-700 text-sm">
                    {error}
                  </div>
                )}
                <div className="mb-4">
                  <Input
                    label="Name"
                    type="text"
                    value={inviteName}
                    onChange={e => setInviteName(e.target.value)}
                    placeholder="Enter user's name"
                    required
                  />
                </div>
                <div className="mb-4">
                  <Input
                    label="Email"
                    type="email"
                    value={inviteEmail}
                    onChange={e => setInviteEmail(e.target.value)}
                    placeholder="Enter user's email"
                    required
                  />
                </div>
                <div className="flex gap-3">
                  <Button type="button" variant="secondary" onClick={handleCloseInviteModal} className="flex-1">
                    Cancel
                  </Button>
                  <Button type="submit" className="flex-1" disabled={inviteLoading}>
                    {inviteLoading ? 'Creating...' : 'Create Invitation'}
                  </Button>
                </div>
              </form>
            )}
          </Card>
        </div>
      )}
    </div>
  );
};

// ============================================================================
// SIDEBAR COMPONENT
// ============================================================================
const Sidebar = ({ activeTab, onTabChange, onLogout }: {
  activeTab: string;
  onTabChange: (tab: string) => void;
  onLogout: () => void;
}) => {
  const navItems = [
    { id: 'campaigns', label: 'Campaigns', icon: 'M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z' },
    { id: 'agents', label: 'Agents', icon: 'M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z' },
    { id: 'calls', label: 'Calls', icon: 'M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z' },
    { id: 'users', label: 'Users', icon: 'M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z' },
  ];

  return (
    <aside className="w-64 bg-white border-r border-gray-200 flex flex-col h-screen fixed left-0 top-0">
      {/* Logo */}
      <div className="p-4 border-b border-gray-200">
        <div className="flex items-center gap-3">
          <img src="/images/logo.png" alt={CONFIG.APP_NAME} className="h-10 object-contain" />
          <span className="text-lg font-bold text-gray-900">{CONFIG.APP_NAME}</span>
        </div>
      </div>

      {/* Navigation */}
      <nav className="flex-1 p-4">
        <p className="text-xs font-medium text-gray-400 uppercase tracking-wider mb-3">Platform</p>
        <div className="space-y-1">
          {navItems.map(item => (
            <button
              key={item.id}
              onClick={() => onTabChange(item.id)}
              className={`w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors ${
                activeTab === item.id
                  ? 'bg-secondary-50 text-secondary-600 border border-secondary-200'
                  : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'
              }`}
            >
              <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d={item.icon} />
              </svg>
              {item.label}
            </button>
          ))}
        </div>
      </nav>

      {/* Bottom section */}
      <div className="p-4 border-t border-gray-200">
        {/* User profile */}
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-3">
            <div className="w-9 h-9 bg-secondary-500 rounded-full flex items-center justify-center text-white font-medium text-sm">
              R
            </div>
            <div>
              <p className="text-sm font-medium text-gray-900">Recex User</p>
              <p className="text-xs text-gray-500">Admin</p>
            </div>
          </div>
          <button
            onClick={onLogout}
            className="p-2 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg transition-colors"
            title="Logout"
          >
            <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
            </svg>
          </button>
        </div>
      </div>
    </aside>
  );
};

// ============================================================================
// MAIN APP
// ============================================================================
// Helper to get tab from URL hash
const getTabFromHash = () => {
  const hash = window.location.hash.slice(1); // Remove #
  const validTabs = ['campaigns', 'agents', 'calls', 'users'];
  return validTabs.includes(hash) ? hash : 'campaigns';
};

const App = () => {
  const [authenticated, setAuthenticated] = useState(() => localStorage.getItem('recex_authenticated') === 'true');
  const [activeTab, setActiveTab] = useState(() => getTabFromHash());

  // Handle tab change with URL update
  const handleTabChange = useCallback((tab: string) => {
    setActiveTab(tab);
    window.history.pushState({ tab }, '', `#${tab}`);
  }, []);

  // Listen for browser back/forward navigation
  useEffect(() => {
    const handlePopState = () => {
      setActiveTab(getTabFromHash());
    };
    window.addEventListener('popstate', handlePopState);
    return () => window.removeEventListener('popstate', handlePopState);
  }, []);

  // Set initial URL hash if not present
  useEffect(() => {
    if (!window.location.hash && authenticated) {
      window.history.replaceState({ tab: 'campaigns' }, '', '#campaigns');
    }
  }, [authenticated]);

  const handleLogout = () => {
    localStorage.removeItem('recex_authenticated');
    setAuthenticated(false);
    // Clear hash on logout
    window.history.replaceState({}, '', window.location.pathname);
  };

  if (!authenticated) {
    return <LoginScreen onLogin={() => setAuthenticated(true)} />;
  }

  return (
    <div className="min-h-screen bg-gray-50">
      {/* Sidebar */}
      <Sidebar activeTab={activeTab} onTabChange={handleTabChange} onLogout={handleLogout} />

      {/* Main Content */}
      <main className="ml-64 min-h-screen">
        <div className="p-8">
          {activeTab === 'agents' && <AgentsSection />}
          {activeTab === 'calls' && <CallsSection />}
          {activeTab === 'campaigns' && <CampaignsSection />}
          {activeTab === 'users' && <UsersSection />}
        </div>
      </main>
    </div>
  );
};

// Mount the app
const root = document.getElementById('root');
if (root) {
  createRoot(root).render(<App />);
}
