import React, { useEffect, useState, useMemo } from 'react';
import {
  Card,
  CardHeader,
  CardTitle,
} from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge';
import { ScrollArea } from '@/components/ui/scroll-area';
import { useToast } from '@/components/ui/use-toast';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from '@/components/ui/tooltip';
import {
  RefreshCw,
  Search,
  Loader2,
  Server,
  FolderGit2,
  Code2,
  Plus,
  Edit,
  Trash2,
  History,
  GitBranch,
  ExternalLink,
} from 'lucide-react';
import type { JenkinsDTO, JenkinsQuery, JenkinsViewDTO, JenkinsJobDTO, JenkinsBuildDTO } from './types';
import * as jenkinsService from './service';
import SyncStatusDrawer from './components/SyncStatusDrawer';
import dayjs from 'dayjs';

const JenkinsPage: React.FC = () => {
  const { toast } = useToast();

  // Jenkins 实例列表
  const [jenkinsList, setJenkinsList] = useState<JenkinsDTO[]>([]);
  const [selectedJenkins, setSelectedJenkins] = useState<JenkinsDTO>();
  
  // 视图、任务、构建数据
  const [viewData, setViewData] = useState<JenkinsViewDTO[]>([]);
  const [jobData, setJobData] = useState<JenkinsJobDTO[]>([]);
  const [buildData, setBuildData] = useState<JenkinsBuildDTO[]>([]);
  
  // 选中状态
  const [selectedView, setSelectedView] = useState<JenkinsViewDTO>();
  const [selectedJob, setSelectedJob] = useState<JenkinsJobDTO>();
  
  // 加载状态
  const [loading, setLoading] = useState({
    jenkins: false,
    views: false,
    jobs: false,
    builds: false,
  });
  
  // 同步状态
  const [syncing, setSyncing] = useState({
    all: false,
    views: false,
    jobs: false,
    builds: false,
  });
  
  // 搜索过滤
  const [jenkinsSearch, setJenkinsSearch] = useState('');
  const [viewSearch] = useState('');
  const [jobSearch, setJobSearch] = useState('');
  const [buildSearch, setBuildSearch] = useState('');
  
  // 弹窗状态
  const [modalVisible, setModalVisible] = useState(false);
  const [editingJenkins, setEditingJenkins] = useState<JenkinsDTO | null>(null);
  const [syncStatusVisible, setSyncStatusVisible] = useState(false);
  
  // 表单数据
  const [formData, setFormData] = useState({
    name: '',
    url: '',
    username: '',
    password: '',
    remark: '',
  });

  // 加载 Jenkins 列表
  const loadJenkinsList = async (params?: JenkinsQuery) => {
    setLoading((prev) => ({ ...prev, jenkins: true }));
    try {
      const response = await jenkinsService.getJenkinsList(params);
      if (response && Array.isArray(response)) {
        setJenkinsList(response);
      } else {
        setJenkinsList([]);
      }
    } catch (error) {
      toast({
        variant: 'destructive',
        title: '加载失败',
        description: '加载 Jenkins 列表失败',
      });
      setJenkinsList([]);
    } finally {
      setLoading((prev) => ({ ...prev, jenkins: false }));
    }
  };

  // 加载视图列表
  const loadViews = async (jenkinsId: number) => {
    setLoading((prev) => ({ ...prev, views: true }));
    try {
      const response = await jenkinsService.getJenkinsViews(jenkinsId);
      if (response && Array.isArray(response)) {
        setViewData(response);
      } else {
        setViewData([]);
      }
    } catch (error) {
      toast({
        variant: 'destructive',
        title: '加载失败',
        description: '加载视图列表失败',
      });
      setViewData([]);
    } finally {
      setLoading((prev) => ({ ...prev, views: false }));
    }
  };

  // 加载任务列表
  const loadJobs = async (jenkinsId: number, viewName?: string) => {
    setLoading((prev) => ({ ...prev, jobs: true }));
    try {
      const response = await jenkinsService.getJenkinsJobs(jenkinsId);
      if (response && Array.isArray(response)) {
        const filteredJobs = viewName
          ? response.filter((job) => (job as any).viewName === viewName)
          : response;
        setJobData(filteredJobs);
      } else {
        setJobData([]);
      }
    } catch (error) {
      toast({
        variant: 'destructive',
        title: '加载失败',
        description: '加载任务列表失败',
      });
      setJobData([]);
    } finally {
      setLoading((prev) => ({ ...prev, jobs: false }));
    }
  };

  // 加载构建列表
  const loadBuilds = async (jenkinsId: number, jobId: number) => {
    setLoading((prev) => ({ ...prev, builds: true }));
    try {
      const response = await jenkinsService.getJenkinsBuilds(jenkinsId, jobId);
      if (response && Array.isArray(response)) {
        setBuildData(response);
      } else {
        setBuildData([]);
      }
    } catch (error) {
      toast({
        variant: 'destructive',
        title: '加载失败',
        description: '加载构建历史失败',
      });
      setBuildData([]);
    } finally {
      setLoading((prev) => ({ ...prev, builds: false }));
    }
  };

  // 选中 Jenkins
  const handleSelectJenkins = (jenkins: JenkinsDTO) => {
    setSelectedJenkins(jenkins);
    setSelectedView(undefined);
    setSelectedJob(undefined);
    setJobData([]);
    setBuildData([]);
    loadViews(jenkins.id);
  };

  // 选中视图
  const handleSelectView = (view: JenkinsViewDTO) => {
    if (!selectedJenkins) return;
    setSelectedView(view);
    setSelectedJob(undefined);
    setBuildData([]);
    loadJobs(selectedJenkins.id, view.viewName);
  };

  // 选中任务
  const handleSelectJob = (job: JenkinsJobDTO) => {
    if (!selectedJenkins) return;
    setSelectedJob(job);
    loadBuilds(selectedJenkins.id, job.id);
  };

  // 同步
  const handleSync = async (id: number, type: 'ALL' | 'VIEW' | 'JOB' | 'BUILD') => {
    const syncKey = type === 'ALL' ? 'all' : type === 'VIEW' ? 'views' : type === 'JOB' ? 'jobs' : 'builds';
    setSyncing((prev) => ({ ...prev, [syncKey]: true }));
    try {
      await jenkinsService.sync(id, type);
      toast({
        title: '同步任务已启动',
        description: '正在后台同步数据，请稍后手动刷新查看结果',
      });
    } catch (error: any) {
      if (error.response?.data?.message === '该Jenkins已有同步任务正在运行中') {
        toast({
          title: '同步中',
          description: '该Jenkins已有同步任务正在运行中',
        });
      } else {
        toast({
          variant: 'destructive',
          title: '同步失败',
          description: '同步任务启动失败',
        });
      }
    } finally {
      setSyncing((prev) => ({ ...prev, [syncKey]: false }));
    }
  };

  // 新增/编辑
  const handleAdd = () => {
    setEditingJenkins(null);
    setFormData({
      name: '',
      url: '',
      username: '',
      password: '',
      remark: '',
    });
    setModalVisible(true);
  };

  const handleEdit = (record: JenkinsDTO) => {
    setEditingJenkins(record);
    setFormData({
      name: record.name,
      url: record.url,
      username: record.username,
      password: record.password || '',
      remark: record.remark || '',
    });
    setModalVisible(true);
  };

  const handleDelete = async (id: number) => {
    if (!window.confirm('确定要删除这个Jenkins配置吗？')) return;
    
    try {
      await jenkinsService.deleteJenkins(id);
      toast({
        title: '删除成功',
        description: 'Jenkins配置已删除',
      });
      loadJenkinsList();
    } catch (error) {
      toast({
        variant: 'destructive',
        title: '删除失败',
        description: '删除Jenkins配置失败',
      });
    }
  };

  const handleSubmit = async () => {
    if (!formData.name || !formData.url || !formData.username || !formData.password) {
      toast({
        variant: 'destructive',
        title: '验证失败',
        description: '请填写所有必填字段',
      });
      return;
    }

    try {
      if (editingJenkins) {
        await jenkinsService.updateJenkins(editingJenkins.id, formData);
        toast({
          title: '更新成功',
          description: 'Jenkins配置已更新',
        });
      } else {
        await jenkinsService.createJenkins(formData);
        toast({
          title: '创建成功',
          description: 'Jenkins配置已创建',
        });
      }
      setModalVisible(false);
      loadJenkinsList();
    } catch (error) {
      toast({
        variant: 'destructive',
        title: '操作失败',
        description: editingJenkins ? '更新失败' : '创建失败',
      });
    }
  };

  const handleTestConnection = async () => {
    if (!formData.url || !formData.username || !formData.password) {
      toast({
        variant: 'destructive',
        title: '验证失败',
        description: '请填写URL、用户名和密码',
      });
      return;
    }

    try {
      await jenkinsService.testConnection(formData);
      toast({
        title: '连接成功',
        description: 'Jenkins连接测试成功',
      });
    } catch (error) {
      toast({
        variant: 'destructive',
        title: '连接失败',
        description: '连接测试失败，请检查配置',
      });
    }
  };

  // 过滤
  const filteredJenkinsList = useMemo(() => {
    if (!jenkinsSearch) return jenkinsList;
    return jenkinsList.filter(
      (jenkins) =>
        jenkins.name.toLowerCase().includes(jenkinsSearch.toLowerCase()) ||
        (jenkins.url && jenkins.url.toLowerCase().includes(jenkinsSearch.toLowerCase()))
    );
  }, [jenkinsList, jenkinsSearch]);

  const filteredViews = useMemo(() => {
    if (!viewSearch) return viewData;
    return viewData.filter((view) =>
      view.viewName.toLowerCase().includes(viewSearch.toLowerCase())
    );
  }, [viewData, viewSearch]);

  const filteredJobs = useMemo(() => {
    if (!jobSearch) return jobData;
    return jobData.filter((job) =>
      job.jobName.toLowerCase().includes(jobSearch.toLowerCase())
    );
  }, [jobData, jobSearch]);

  const filteredBuilds = useMemo(() => {
    if (!buildSearch) return buildData;
    return buildData.filter((build) =>
      build.buildNumber.toString().includes(buildSearch)
    );
  }, [buildData, buildSearch]);

  // 初始化
  useEffect(() => {
    loadJenkinsList();
  }, []);

  return (
    <TooltipProvider>
      <div className="flex flex-col h-full p-6 gap-4">
        {/* 顶部标题栏 */}
        <div className="flex items-center justify-between flex-shrink-0">
          <div>
            <h1 className="text-3xl font-bold">Jenkins 管理</h1>
            <p className="text-sm text-muted-foreground mt-1">
              管理和监控 Jenkins 视图、任务和构建
            </p>
          </div>
          <div className="flex items-center gap-3">
            <Button onClick={handleAdd}>
              <Plus className="mr-2 h-4 w-4" />
              新增 Jenkins
            </Button>
            <Button
              onClick={() => selectedJenkins && handleSync(selectedJenkins.id, 'ALL')}
              disabled={syncing.all || !selectedJenkins}
              variant="default"
            >
              {syncing.all ? (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              ) : (
                <RefreshCw className="mr-2 h-4 w-4" />
              )}
              同步所有数据
            </Button>
            <Button variant="outline" onClick={() => setSyncStatusVisible(true)}>
              <History className="mr-2 h-4 w-4" />
              查看历史同步记录
            </Button>
          </div>
        </div>

        {/* 三栏布局 */}
        <div className="flex-1 grid grid-cols-12 gap-4 min-h-0 overflow-hidden">
          {/* 左栏：Jenkins 实例 */}
          <Card className="col-span-3 flex flex-col min-h-0">
            <CardHeader className="border-b flex-shrink-0">
              <div className="flex items-center justify-between">
                <CardTitle className="text-base">Jenkins 实例</CardTitle>
                <Button
                  variant="ghost"
                  size="icon"
                  className="h-7 w-7"
                  onClick={() => loadJenkinsList()}
                  disabled={loading.jenkins}
                >
                  <RefreshCw
                    className={`h-4 w-4 ${loading.jenkins ? 'animate-spin' : ''}`}
                  />
                </Button>
              </div>

              <div className="relative mt-2">
                <Search className="absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
                <Input
                  placeholder="搜索 Jenkins..."
                  value={jenkinsSearch}
                  onChange={(e) => setJenkinsSearch(e.target.value)}
                  className="pl-8 h-8"
                />
              </div>
            </CardHeader>
            <ScrollArea className="flex-1">
              <div className="p-2 space-y-1 min-h-[calc(100vh-280px)]">
                {loading.jenkins ? (
                  <div className="flex items-center justify-center h-full min-h-[400px]">
                    <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
                  </div>
                ) : filteredJenkinsList.length === 0 ? (
                  <div className="flex flex-col items-center justify-center h-full min-h-[400px] text-muted-foreground">
                    <Server className="h-12 w-12 mb-2 opacity-20" />
                    <p className="text-sm">暂无 Jenkins 实例</p>
                  </div>
                ) : (
                  filteredJenkinsList.map((jenkins) => (
                    <div
                      key={jenkins.id}
                      className={`group p-3 border rounded-lg cursor-pointer hover:bg-accent transition-colors ${
                        selectedJenkins?.id === jenkins.id
                          ? 'bg-accent border-primary'
                          : ''
                      }`}
                      onClick={() => handleSelectJenkins(jenkins)}
                    >
                      <div className="flex items-start justify-between gap-2">
                        <div className="flex-1 min-w-0">
                          <div className="flex items-center gap-2 mb-1">
                            <Server className="h-4 w-4 flex-shrink-0 text-muted-foreground" />
                            <span className="font-medium truncate">
                              {jenkins.name}
                            </span>
                          </div>
                          <p className="text-xs text-muted-foreground truncate">
                            {jenkins.url}
                          </p>
                          {jenkins.lastAllSyncTime && (
                            <p className="text-xs text-muted-foreground mt-1">
                              最后同步：{dayjs(jenkins.lastAllSyncTime).format('MM-DD HH:mm')}
                            </p>
                          )}
                        </div>
                        <div className="flex-shrink-0 opacity-0 group-hover:opacity-100 transition-opacity flex gap-1">
                          <Tooltip>
                            <TooltipTrigger asChild>
                              <Button
                                variant="ghost"
                                size="icon"
                                className="h-6 w-6"
                                onClick={(e) => {
                                  e.stopPropagation();
                                  handleEdit(jenkins);
                                }}
                              >
                                <Edit className="h-3 w-3" />
                              </Button>
                            </TooltipTrigger>
                            <TooltipContent>
                              <p>编辑</p>
                            </TooltipContent>
                          </Tooltip>
                          <Tooltip>
                            <TooltipTrigger asChild>
                              <Button
                                variant="ghost"
                                size="icon"
                                className="h-6 w-6"
                                onClick={(e) => {
                                  e.stopPropagation();
                                  handleDelete(jenkins.id);
                                }}
                              >
                                <Trash2 className="h-3 w-3 text-destructive" />
                              </Button>
                            </TooltipTrigger>
                            <TooltipContent>
                              <p>删除</p>
                            </TooltipContent>
                          </Tooltip>
                        </div>
                      </div>
                    </div>
                  ))
                )}
              </div>
            </ScrollArea>
          </Card>

          {/* 中栏：视图和任务 */}
          <Card className="col-span-5 flex flex-col min-h-0">
            <CardHeader className="border-b flex-shrink-0">
              <div className="flex items-center justify-between">
                <CardTitle className="text-base">
                  任务 {selectedView && `(${filteredJobs.length})`}
                </CardTitle>
                <Button
                  variant="ghost"
                  size="icon"
                  className="h-7 w-7"
                  onClick={() => selectedJenkins && handleSync(selectedJenkins.id, 'VIEW')}
                  disabled={syncing.views || !selectedJenkins}
                >
                  <RefreshCw
                    className={`h-4 w-4 ${syncing.views ? 'animate-spin' : ''}`}
                  />
                </Button>
              </div>

              {/* 视图选择器 */}
              {selectedJenkins && filteredViews.length > 0 && (
                <div className="flex gap-1 mt-2 flex-wrap">
                  <Button
                    variant={!selectedView ? 'default' : 'outline'}
                    size="sm"
                    onClick={() => {
                      setSelectedView(undefined);
                      loadJobs(selectedJenkins.id);
                    }}
                  >
                    全部视图
                  </Button>
                  {filteredViews.map((view) => (
                    <Button
                      key={view.id}
                      variant={selectedView?.id === view.id ? 'default' : 'outline'}
                      size="sm"
                      onClick={() => handleSelectView(view)}
                    >
                      <FolderGit2 className="mr-1 h-3 w-3" />
                      {view.viewName}
                    </Button>
                  ))}
                </div>
              )}

              <div className="relative mt-2">
                <Search className="absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
                <Input
                  placeholder="搜索任务..."
                  value={jobSearch}
                  onChange={(e) => setJobSearch(e.target.value)}
                  className="pl-8 h-8"
                />
              </div>
            </CardHeader>
            <div className="flex-1 overflow-auto">
              {loading.jobs ? (
                <div className="flex items-center justify-center h-full">
                  <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
                </div>
              ) : !selectedJenkins ? (
                <div className="flex flex-col items-center justify-center h-full text-muted-foreground">
                  <Code2 className="h-12 w-12 mb-2 opacity-20" />
                  <p className="text-sm">请先选择 Jenkins 实例</p>
                </div>
              ) : filteredJobs.length === 0 ? (
                <div className="flex flex-col items-center justify-center h-full text-muted-foreground">
                  <Code2 className="h-12 w-12 mb-2 opacity-20" />
                  <p className="text-sm">暂无任务</p>
                </div>
              ) : (
                <div className="p-2 space-y-2">
                  {filteredJobs.map((job) => (
                    <div
                      key={job.id}
                      className={`p-3 border rounded-lg cursor-pointer hover:bg-accent transition-colors ${
                        selectedJob?.id === job.id
                          ? 'bg-accent border-primary'
                          : ''
                      }`}
                      onClick={() => handleSelectJob(job)}
                    >
                      <div className="flex items-start justify-between gap-2">
                        <div className="flex-1 min-w-0">
                          <div className="flex items-center gap-2 mb-1">
                            <Code2 className="h-4 w-4 text-muted-foreground" />
                            <span className="font-medium truncate">
                              {job.jobName}
                            </span>
                            {job.lastBuildStatus && (
                              <Badge
                                variant={
                                  job.lastBuildStatus === 'SUCCESS'
                                    ? 'default'
                                    : job.lastBuildStatus === 'FAILURE'
                                    ? 'destructive'
                                    : 'secondary'
                                }
                              >
                                {job.lastBuildStatus}
                              </Badge>
                            )}
                          </div>
                          {job.description && (
                            <p className="text-xs text-muted-foreground line-clamp-2">
                              {job.description}
                            </p>
                          )}
                          {job.lastBuildTime && (
                            <p className="text-xs text-muted-foreground mt-1">
                              最后构建：{dayjs(job.lastBuildTime).format('MM-DD HH:mm')}
                            </p>
                          )}
                        </div>
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </div>
          </Card>

          {/* 右栏：构建历史 */}
          <Card className="col-span-4 flex flex-col min-h-0">
            <CardHeader className="border-b flex-shrink-0">
              <div className="flex items-center justify-between">
                <CardTitle className="text-base">
                  构建历史 {selectedJob && `(${filteredBuilds.length})`}
                </CardTitle>
                <Button
                  variant="ghost"
                  size="icon"
                  className="h-7 w-7"
                  onClick={() =>
                    selectedJenkins &&
                    selectedJob &&
                    loadBuilds(selectedJenkins.id, selectedJob.id)
                  }
                  disabled={loading.builds || !selectedJob}
                >
                  <RefreshCw
                    className={`h-4 w-4 ${loading.builds ? 'animate-spin' : ''}`}
                  />
                </Button>
              </div>
              <div className="relative mt-2">
                <Search className="absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
                <Input
                  placeholder="搜索构建..."
                  value={buildSearch}
                  onChange={(e) => setBuildSearch(e.target.value)}
                  className="pl-8 h-8"
                />
              </div>
            </CardHeader>
            <div className="flex-1 overflow-auto">
              {loading.builds ? (
                <div className="flex items-center justify-center h-full">
                  <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
                </div>
              ) : !selectedJob ? (
                <div className="flex flex-col items-center justify-center h-full text-muted-foreground">
                  <GitBranch className="h-12 w-12 mb-2 opacity-20" />
                  <p className="text-sm">请先选择任务</p>
                </div>
              ) : filteredBuilds.length === 0 ? (
                <div className="flex flex-col items-center justify-center h-full text-muted-foreground">
                  <GitBranch className="h-12 w-12 mb-2 opacity-20" />
                  <p className="text-sm">暂无构建历史</p>
                </div>
              ) : (
                <div className="divide-y">
                  {filteredBuilds.map((build) => (
                    <div
                      key={build.id}
                      className="p-3 hover:bg-accent transition-colors"
                    >
                      <div className="flex items-start gap-2">
                        <GitBranch className="h-4 w-4 text-muted-foreground mt-1 flex-shrink-0" />
                        <div className="flex-1 min-w-0">
                          <div className="flex items-center gap-2 flex-wrap">
                            <span className="font-medium font-mono text-sm">
                              #{build.buildNumber}
                            </span>
                            <Badge
                              variant={
                                build.buildStatus === 'SUCCESS'
                                  ? 'default'
                                  : build.buildStatus === 'FAILURE'
                                  ? 'destructive'
                                  : 'secondary'
                              }
                            >
                              {build.buildStatus || '-'}
                            </Badge>
                          </div>
                          {build.startTime && (
                            <p className="text-xs text-muted-foreground mt-1">
                              {dayjs(build.startTime).format('YYYY-MM-DD HH:mm:ss')}
                            </p>
                          )}
                          {build.duration !== undefined && (
                            <p className="text-xs text-muted-foreground">
                              耗时：
                              {(() => {
                                const seconds = Math.floor(build.duration / 1000);
                                if (seconds < 60) return `${seconds}秒`;
                                const minutes = Math.floor(seconds / 60);
                                const remainingSeconds = seconds % 60;
                                return `${minutes}分${remainingSeconds}秒`;
                              })()}
                            </p>
                          )}
                          {build.triggerCause && (
                            <p className="text-xs text-muted-foreground mt-1 line-clamp-2">
                              {build.triggerCause}
                            </p>
                          )}
                          {build.buildUrl && (
                            <a
                              href={build.buildUrl}
                              target="_blank"
                              rel="noopener noreferrer"
                              className="text-xs text-primary hover:underline mt-1 inline-flex items-center gap-1"
                              onClick={(e) => e.stopPropagation()}
                            >
                              查看详情
                              <ExternalLink className="h-3 w-3" />
                            </a>
                          )}
                        </div>
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </div>
          </Card>
        </div>
      </div>

      {/* 新增/编辑弹窗 */}
      <Dialog open={modalVisible} onOpenChange={setModalVisible}>
        <DialogContent className="sm:max-w-[600px]">
          <DialogHeader>
            <DialogTitle>{editingJenkins ? '编辑 Jenkins' : '新增 Jenkins'}</DialogTitle>
            <DialogDescription>
              {editingJenkins ? '修改 Jenkins 配置信息' : '填写 Jenkins 配置信息'}
            </DialogDescription>
          </DialogHeader>
          <div className="grid gap-4 py-4">
            <div className="grid gap-2">
              <Label htmlFor="name">
                Jenkins 名称 <span className="text-destructive">*</span>
              </Label>
              <Input
                id="name"
                value={formData.name}
                onChange={(e) => setFormData({ ...formData, name: e.target.value })}
                placeholder="请输入 Jenkins 名称"
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="url">
                Jenkins 地址 <span className="text-destructive">*</span>
              </Label>
              <Input
                id="url"
                value={formData.url}
                onChange={(e) => setFormData({ ...formData, url: e.target.value })}
                placeholder="请输入 Jenkins 地址"
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="username">
                用户名 <span className="text-destructive">*</span>
              </Label>
              <Input
                id="username"
                value={formData.username}
                onChange={(e) => setFormData({ ...formData, username: e.target.value })}
                placeholder="请输入用户名"
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="password">
                密码/Token <span className="text-destructive">*</span>
              </Label>
              <Input
                id="password"
                type="password"
                value={formData.password}
                onChange={(e) => setFormData({ ...formData, password: e.target.value })}
                placeholder="请输入密码或 Token"
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="remark">备注</Label>
              <Input
                id="remark"
                value={formData.remark}
                onChange={(e) => setFormData({ ...formData, remark: e.target.value })}
                placeholder="请输入备注"
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={handleTestConnection}>
              测试连接
            </Button>
            <Button variant="outline" onClick={() => setModalVisible(false)}>
              取消
            </Button>
            <Button onClick={handleSubmit}>
              确定
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <SyncStatusDrawer
        visible={syncStatusVisible}
        onClose={() => setSyncStatusVisible(false)}
      />
    </TooltipProvider>
  );
};

export default JenkinsPage;
