import { useCallback, useEffect, useState } from 'react';
import { BarChart3, Plus, Loader2, ListChecks } from 'lucide-react';
import { usePluginContext } from './client';
import { CredentialPanel } from './CredentialPanel';
import { NewJobDialog } from './NewJobDialog';
import { JobDetail } from './JobDetail';
import type { S3Credential, AnalysisJob } from './types';

const API_BASE = '/api/v1/plugin/data_analytics';

interface Props {
  pluginName: string;
}

export function Dashboard({ pluginName }: Props) {
  const { client } = usePluginContext();
  const [credentials, setCredentials] = useState<S3Credential[]>([]);
  const [credLoading, setCredLoading] = useState(true);
  const [jobs, setJobs] = useState<AnalysisJob[]>([]);
  const [jobLoading, setJobLoading] = useState(true);
  const [showNewJob, setShowNewJob] = useState(false);
  const [openJobId, setOpenJobId] = useState<string | null>(null);
  const [error, setError] = useState('');

  const loadCredentials = useCallback(async () => {
    setCredLoading(true);
    try {
      const resp = await client.get<{ credentials: S3Credential[] }>(`${API_BASE}/credentials`);
      setCredentials(resp.data.credentials || []);
    } catch (e: unknown) {
      const msg = (e as { response?: { data?: { detail?: string } } }).response?.data?.detail;
      setError(msg || '加载凭证失败');
    } finally {
      setCredLoading(false);
    }
  }, [client]);

  const loadJobs = useCallback(async () => {
    setJobLoading(true);
    try {
      const resp = await client.get<{ jobs: AnalysisJob[] }>(`${API_BASE}/jobs`);
      setJobs(resp.data.jobs || []);
    } catch (e: unknown) {
      const msg = (e as { response?: { data?: { detail?: string } } }).response?.data?.detail;
      setError(msg || '加载任务失败');
    } finally {
      setJobLoading(false);
    }
  }, [client]);

  useEffect(() => {
    loadCredentials();
    loadJobs();
  }, [loadCredentials, loadJobs]);

  // 轮询任务列表，方便看状态变化
  useEffect(() => {
    const t = setInterval(loadJobs, 5000);
    return () => clearInterval(t);
  }, [loadJobs]);

  return (
    <div className="h-full overflow-y-auto p-6 bg-bg-base">
      <div className="max-w-5xl mx-auto space-y-6">
        <div className="flex items-center gap-3 pb-2">
          <div className="w-10 h-10 rounded-xl bg-accent-light text-accent flex items-center justify-center">
            <BarChart3 size={20} />
          </div>
          <div>
            <h2 className="text-lg font-bold text-text-primary">数据分析</h2>
            <p className="text-xs text-text-muted mt-0.5">
              对接 S3，让 agent 自主决定分析路径（python_executor / ray_submit）。{' '}
              <span className="font-mono text-[10px] opacity-70">{pluginName}</span>
            </p>
          </div>
        </div>

        {error && (
          <div className="p-3 bg-danger-bg text-danger text-sm rounded-xl border border-danger/20">{error}</div>
        )}

        <CredentialPanel credentials={credentials} loading={credLoading} onChanged={loadCredentials} />

        <div className="bg-bg-card rounded-2xl border border-border-primary p-5">
          <div className="flex items-center justify-between mb-4">
            <div>
              <h3 className="font-semibold text-text-primary flex items-center gap-2">
                <ListChecks size={16} className="text-accent" /> 分析任务
              </h3>
              <p className="text-xs text-text-muted mt-0.5">点行查看详情和事件流。每 5 秒自动刷新。</p>
            </div>
            <button
              className="px-3 py-1.5 text-xs rounded-lg bg-accent text-white hover:opacity-90 transition flex items-center gap-1.5 disabled:opacity-50"
              onClick={() => setShowNewJob(true)}
              disabled={credentials.length === 0}
              title={credentials.length === 0 ? '请先添加凭证' : ''}
            >
              <Plus size={14} /> 新建任务
            </button>
          </div>

          {jobLoading && jobs.length === 0 ? (
            <div className="flex items-center justify-center py-8 text-text-muted">
              <Loader2 size={20} className="animate-spin" />
            </div>
          ) : jobs.length === 0 ? (
            <div className="text-sm text-text-muted text-center py-8 border border-dashed border-border-primary rounded-xl">
              还没有分析任务。点右上角「新建任务」开始。
            </div>
          ) : (
            <div className="space-y-2">
              {jobs.map((j) => (
                <button
                  key={j.job_id}
                  className="w-full text-left p-3 bg-bg-secondary rounded-xl border border-border-secondary hover:border-accent transition flex items-center justify-between gap-3"
                  onClick={() => setOpenJobId(j.job_id)}
                >
                  <div className="min-w-0 flex-1">
                    <div className="text-sm text-text-primary truncate">{j.description}</div>
                    <div className="text-[11px] text-text-muted mt-0.5 font-mono">
                      {j.job_id.slice(0, 8)} · {j.created_at?.slice(0, 19).replace('T', ' ')}
                    </div>
                  </div>
                  <StatusBadge status={j.status} />
                </button>
              ))}
            </div>
          )}
        </div>
      </div>

      {showNewJob && (
        <NewJobDialog
          credentials={credentials}
          onClose={() => setShowNewJob(false)}
          onCreated={loadJobs}
        />
      )}
      {openJobId && <JobDetail jobId={openJobId} onClose={() => setOpenJobId(null)} />}
    </div>
  );
}

function StatusBadge({ status }: { status: string }) {
  const map: Record<string, string> = {
    pending: 'bg-bg-base text-text-muted border-border-primary',
    running: 'bg-warning-bg text-warning border-warning/20',
    completed: 'bg-success-bg text-success border-success/20',
    failed: 'bg-danger-bg text-danger border-danger/20',
  };
  const cls = map[status] || map.pending;
  return (
    <span className={`text-[10px] font-medium px-2 py-1 rounded-lg border ${cls} shrink-0`}>
      {status}
    </span>
  );
}
