import { useState, useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { useAuth } from '../../contexts/AuthContext';
import { AppLayout } from '../../components/layout/AppLayout';
import { LoadingSpinner } from '../../components/ui/LoadingSpinner';
import { estimatesApi, type EstimateStage, type FunnelAnalytics, type EstimateStats } from '../../api/estimates';
import {
  BarChart3,
  TrendingUp,
  TrendingDown,
  DollarSign,
  FileText,
  CheckCircle2,
  AlertTriangle,
  Clock,
  Filter,
  RefreshCw,
  ArrowRight,
  Percent,
  Target,
} from 'lucide-react';

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

const FUNNEL_STAGES: { key: EstimateStage; label: string; color: string; bgColor: string }[] = [
  { key: 'draft', label: 'Draft', color: 'text-slate-700', bgColor: 'bg-slate-100' },
  { key: 'delivered', label: 'Delivered', color: 'text-blue-700', bgColor: 'bg-blue-100' },
  { key: 'accepted', label: 'Accepted', color: 'text-emerald-700', bgColor: 'bg-emerald-100' },
  { key: 'scheduled', label: 'Scheduled', color: 'text-amber-700', bgColor: 'bg-amber-100' },
  { key: 'closed', label: 'Closed', color: 'text-green-700', bgColor: 'bg-green-100' },
];

const TERMINAL_STAGES: { key: EstimateStage; label: string; color: string; bgColor: string }[] = [
  { key: 'rejected', label: 'Rejected', color: 'text-red-700', bgColor: 'bg-red-100' },
  { key: 'expired', label: 'Expired', color: 'text-gray-700', bgColor: 'bg-gray-100' },
];

function formatCurrency(value: number): string {
  if (value >= 1_000_000) return `$${(value / 1_000_000).toFixed(1)}M`;
  if (value >= 1_000) return `$${(value / 1_000).toFixed(1)}K`;
  return `$${value.toFixed(0)}`;
}

function formatPct(value: number): string {
  return `${value.toFixed(1)}%`;
}

// ─── Stat Card ────────────────────────────────────────────────────────────

function StatCard({
  icon: Icon,
  label,
  value,
  subtext,
  trend,
}: {
  icon: React.ElementType;
  label: string;
  value: string;
  subtext?: string;
  trend?: 'up' | 'down' | 'neutral';
}) {
  const trendColor = trend === 'up' ? 'text-emerald-600' : trend === 'down' ? 'text-red-600' : 'text-surface-400';

  return (
    <div className="rounded-xl border border-surface-200 bg-white p-5">
      <div className="flex items-center justify-between">
        <p className="text-xs font-medium uppercase tracking-wide text-surface-500">{label}</p>
        <Icon className={`h-4 w-4 ${trendColor}`} />
      </div>
      <p className="mt-2 text-2xl font-bold text-surface-900">{value}</p>
      {subtext && <p className="mt-1 text-xs text-surface-500">{subtext}</p>}
    </div>
  );
}

// ─── Funnel Bar ───────────────────────────────────────────────────────────

function FunnelBar({
  stage,
  count,
  value,
  maxCount,
  conversionRate,
}: {
  stage: { key: EstimateStage; label: string; color: string; bgColor: string };
  count: number;
  value: number;
  maxCount: number;
  conversionRate?: number;
}) {
  const widthPct = maxCount > 0 ? Math.max((count / maxCount) * 100, 8) : 8;

  return (
    <div className="group">
      <div className="flex items-center justify-between mb-1.5">
        <div className="flex items-center gap-2">
          <span className={`inline-flex rounded-full px-2 py-0.5 text-xs font-semibold ${stage.bgColor} ${stage.color}`}>
            {stage.label}
          </span>
          <span className="text-sm font-bold text-surface-900">{count}</span>
          <span className="text-xs text-surface-500">{formatCurrency(value)}</span>
        </div>
        {conversionRate !== undefined && (
          <div className="flex items-center gap-1">
            <ArrowRight className="h-3 w-3 text-surface-300" />
            <span className={`text-xs font-semibold ${conversionRate >= 50 ? 'text-emerald-600' : conversionRate >= 25 ? 'text-amber-600' : 'text-red-600'}`}>
              {formatPct(conversionRate)}
            </span>
          </div>
        )}
      </div>
      <div className="h-3 rounded-full bg-surface-100 overflow-hidden">
        <div
          className={`h-full rounded-full transition-all duration-500 ${stage.bgColor.replace('100', '400')}`}
          style={{ width: `${widthPct}%` }}
        />
      </div>
    </div>
  );
}

// ─── Drop-off Panel ───────────────────────────────────────────────────────

function DropOffPanel({ data }: { data: FunnelAnalytics['drop_off'] }) {
  if (data.total_drop_off_count === 0) return null;

  return (
    <div className="rounded-xl border border-red-200 bg-red-50 p-5">
      <div className="flex items-center gap-2 mb-4">
        <AlertTriangle className="h-5 w-5 text-red-600" />
        <h3 className="text-sm font-semibold text-red-900">Drop-off Analysis</h3>
        <span className="ml-auto text-lg font-bold text-red-700">{formatPct(data.drop_off_rate)}</span>
      </div>

      <div className="grid grid-cols-2 gap-4 mb-4">
        <div className="rounded-lg bg-white p-3 border border-red-100">
          <p className="text-xs text-red-600 font-medium">Rejected</p>
          <p className="text-xl font-bold text-red-700">{data.rejected_count}</p>
        </div>
        <div className="rounded-lg bg-white p-3 border border-red-100">
          <p className="text-xs text-gray-600 font-medium">Expired</p>
          <p className="text-xl font-bold text-gray-700">{data.expired_count}</p>
        </div>
      </div>

      {Object.keys(data.rejection_reasons).length > 0 && (
        <div>
          <p className="text-xs font-medium text-red-800 mb-2">Rejection Reasons</p>
          <div className="space-y-1.5">
            {Object.entries(data.rejection_reasons)
              .sort(([, a], [, b]) => b - a)
              .map(([reason, count]) => (
                <div key={reason} className="flex items-center justify-between text-sm">
                  <span className="text-red-800">{reason}</span>
                  <span className="font-semibold text-red-900">{count}</span>
                </div>
              ))}
          </div>
        </div>
      )}
    </div>
  );
}

// ─── Source Breakdown ─────────────────────────────────────────────────────

function SourcePanel({ sources }: { sources: Record<string, { count: number; total_value: number; conversion_rate: number; avg_value: number }> }) {
  const entries = Object.entries(sources).sort(([, a], [, b]) => b.total_value - a.total_value);
  if (entries.length === 0) return null;

  return (
    <div className="rounded-xl border border-surface-200 bg-white p-5">
      <div className="flex items-center gap-2 mb-4">
        <Target className="h-5 w-5 text-surface-600" />
        <h3 className="text-sm font-semibold text-surface-900">By Source</h3>
      </div>

      <div className="overflow-x-auto">
        <table className="w-full text-sm">
          <thead>
            <tr className="border-b border-surface-200">
              <th className="text-left py-2 px-3 text-xs font-medium text-surface-500 uppercase">Source</th>
              <th className="text-right py-2 px-3 text-xs font-medium text-surface-500 uppercase">Count</th>
              <th className="text-right py-2 px-3 text-xs font-medium text-surface-500 uppercase">Value</th>
              <th className="text-right py-2 px-3 text-xs font-medium text-surface-500 uppercase">Avg</th>
              <th className="text-right py-2 px-3 text-xs font-medium text-surface-500 uppercase">Conv. Rate</th>
            </tr>
          </thead>
          <tbody>
            {entries.map(([source, data]) => (
              <tr key={source} className="border-b border-surface-100 last:border-0">
                <td className="py-2 px-3 font-medium text-surface-900 capitalize">{source}</td>
                <td className="py-2 px-3 text-right text-surface-700">{data.count}</td>
                <td className="py-2 px-3 text-right text-surface-700">{formatCurrency(data.total_value)}</td>
                <td className="py-2 px-3 text-right text-surface-500">{formatCurrency(data.avg_value)}</td>
                <td className={`py-2 px-3 text-right font-semibold ${data.conversion_rate >= 30 ? 'text-emerald-600' : data.conversion_rate >= 15 ? 'text-amber-600' : 'text-red-600'}`}>
                  {formatPct(data.conversion_rate)}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

// ─── Page ─────────────────────────────────────────────────────────────────

export function EstimatesFunnelPage() {
  const { user } = useAuth();
  const companyId = user?.tenantId as string;

  const [days, setDays] = useState(90);
  const [sourceFilter, setSourceFilter] = useState('');

  const daysLabel = days === 30 ? '30 days' : days === 90 ? '90 days' : days === 180 ? '180 days' : days === 365 ? '1 year' : `${days} days`;

  // Funnel analytics
  const { data: funnel, isLoading: funnelLoading, refetch: refetchFunnel } = useQuery({
    queryKey: ['estimates-funnel', companyId, days, sourceFilter],
    queryFn: () =>
      estimatesApi.getFunnelAnalytics(companyId, {
        days,
        ...(sourceFilter ? { source: sourceFilter as any } : {}),
      }),
  });

  // Quick stats
  const { data: stats } = useQuery({
    queryKey: ['estimates-stats', companyId, 30],
    queryFn: () => estimatesApi.getEstimateStats(companyId, 30),
  });

  // Source breakdown
  const { data: bySource } = useQuery({
    queryKey: ['estimates-by-source', companyId, days],
    queryFn: () => estimatesApi.getEstimatesBySource(companyId, days),
  });

  const summary = useMemo(() => funnel?.pipeline_summary ?? null, [funnel]);

  if (funnelLoading) {
    return (
      <AppLayout>
        <div className="flex items-center justify-center h-96">
          <LoadingSpinner />
        </div>
      </AppLayout>
    );
  }

  const maxCount = funnel ? Math.max(...Object.values(funnel.stage_counts)) : 1;

  return (
    <AppLayout>
      <div className="space-y-6">
        {/* Header */}
        <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
          <div>
            <h1 className="text-2xl font-bold text-surface-900">Estimates Funnel</h1>
            <p className="text-sm text-surface-500 mt-1">
              Pipeline tracking and conversion analytics — {daysLabel}
            </p>
          </div>

          <div className="flex items-center gap-2">
            {/* Date range selector */}
            <select
              value={days}
              onChange={(e) => setDays(Number(e.target.value))}
              className="rounded-lg border border-surface-300 bg-white px-3 py-2 text-sm outline-none focus:border-brand-500"
            >
              <option value={30}>Last 30 days</option>
              <option value={90}>Last 90 days</option>
              <option value={180}>Last 180 days</option>
              <option value={365}>Last year</option>
            </select>

            {/* Refresh */}
            <button
              onClick={() => refetchFunnel()}
              className="inline-flex items-center gap-1.5 rounded-lg border border-surface-300 px-3 py-2 text-sm text-surface-600 hover:bg-surface-50 min-h-[44px]"
            >
              <RefreshCw className="h-4 w-4" />
            </button>
          </div>
        </div>

        {/* Summary Cards */}
        <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
          <StatCard
            icon={FileText}
            label="Total Estimates"
            value={String(funnel?.total_estimates ?? 0)}
            subtext={daysLabel}
          />
          <StatCard
            icon={DollarSign}
            label="Pipeline Value"
            value={formatCurrency(summary?.total_pipeline_value ?? 0)}
            subtext={`${summary?.closed_count ?? 0} closed`}
          />
          <StatCard
            icon={Percent}
            label="Win Rate"
            value={formatPct(summary?.win_rate ?? 0)}
            subtext={stats ? `${stats.closed_count} won / ${stats.total_count} total (30d)` : undefined}
          />
          <StatCard
            icon={Clock}
            label="Avg Deal Size"
            value={formatCurrency(summary?.avg_deal_size ?? 0)}
            subtext={
              summary?.avg_time_to_accept_days
                ? `${summary.avg_time_to_accept_days}d to accept`
                : 'No acceptance data yet'
            }
          />
        </div>

        {/* Funnel Visualization */}
        <div className="rounded-xl border border-surface-200 bg-white p-6">
          <div className="flex items-center gap-2 mb-6">
            <BarChart3 className="h-5 w-5 text-surface-600" />
            <h2 className="text-lg font-semibold text-surface-900">Conversion Funnel</h2>
          </div>

          <div className="space-y-4">
            {FUNNEL_STAGES.map((stage, i) => {
              const count = funnel?.stage_counts[stage.key] ?? 0;
              const value = funnel?.stage_values[stage.key] ?? 0;
              const convKey = `${stage.key}_to_${FUNNEL_STAGES[i + 1]?.key}`;
              const convRate = funnel?.conversion_rates[convKey]?.rate;

              return (
                <FunnelBar
                  key={stage.key}
                  stage={stage}
                  count={count}
                  value={value}
                  maxCount={maxCount}
                  conversionRate={convRate}
                />
              );
            })}
          </div>

          {/* Terminal stages */}
          {TERMINAL_STAGES.length > 0 && (
            <>
              <div className="border-t border-surface-200 my-4" />
              <p className="text-xs font-medium uppercase tracking-wide text-surface-500 mb-3">Terminal Stages</p>
              <div className="space-y-4">
                {TERMINAL_STAGES.map((stage) => {
                  const count = funnel?.stage_counts[stage.key] ?? 0;
                  const value = funnel?.stage_values[stage.key] ?? 0;
                  return (
                    <FunnelBar
                      key={stage.key}
                      stage={stage}
                      count={count}
                      value={value}
                      maxCount={maxCount}
                    />
                  );
                })}
              </div>
            </>
          )}
        </div>

        {/* Bottom row: Drop-off + Source */}
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
          {funnel && <DropOffPanel data={funnel.drop_off} />}
          {bySource && <SourcePanel sources={bySource.sources} />}
        </div>

        {/* 30-day quick stats */}
        {stats && (
          <div className="rounded-xl border border-surface-200 bg-white p-6">
            <div className="flex items-center gap-2 mb-4">
              <TrendingUp className="h-5 w-5 text-surface-600" />
              <h2 className="text-lg font-semibold text-surface-900">30-Day Snapshot</h2>
            </div>

            <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-4">
              {[
                { label: 'New Estimates', value: String(stats.total_count) },
                { label: 'Active', value: String(stats.active_count) },
                { label: 'Closed', value: String(stats.closed_count) },
                { label: 'Total Value', value: formatCurrency(stats.total_value) },
                { label: 'Pipeline', value: formatCurrency(stats.pipeline_value) },
                { label: 'Closed Value', value: formatCurrency(stats.closed_value) },
              ].map((item) => (
                <div key={item.label} className="rounded-lg bg-surface-50 p-3">
                  <p className="text-xs text-surface-500">{item.label}</p>
                  <p className="mt-1 text-lg font-bold text-surface-900">{item.value}</p>
                </div>
              ))}
            </div>
          </div>
        )}
      </div>
    </AppLayout>
  );
}
