import { useStore } from '@nanostores/react';
import { useFetcher, useRouteLoaderData } from '@remix-run/react';
import classNames from 'classnames';
import { format, formatDistanceToNow } from 'date-fns';
import { zhCN } from 'date-fns/locale/zh-CN';
import { motion } from 'framer-motion';
import React, { useEffect, useMemo, useState } from 'react';
import { toast } from 'sonner';
import { Badge } from '~/components/ui/Badge';
import { Button } from '~/components/ui/Button';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '~/components/ui/Collapsible';
import { _1PanelConnectionStore, fetch1PanelStats, isFetchingStats, update1PanelConnection } from '~/lib/stores/1panel';
import { getChatId } from '~/lib/stores/ai-state';
import type { ConnectionSettings } from '~/root';
import type { _1PanelWebsite } from '~/types/1panel';
import type { ApiResponse } from '~/types/global';
import ConnectionBorder from './components/ConnectionBorder';

export default function _1PanelConnection({
  isDeploying,
  onDeploy,
}: {
  isDeploying: boolean;
  onDeploy: (siteId: number) => void;
}) {
  const rootData = useRouteLoaderData<{ connectionSettings?: ConnectionSettings }>('root');
  const connectFetcher = useFetcher<ApiResponse>();
  const settingsFetcher = useFetcher<ApiResponse>();

  const connection = useStore(_1PanelConnectionStore);
  const [serverUrl, setServerUrl] = useState('');
  const [apiKey, setApiKey] = useState('');
  const fetching = useStore(isFetchingStats);
  const [isStatsOpen, setIsStatsOpen] = useState(false);
  const [activeSiteIndex, setActiveSiteIndex] = useState(-1);
  const [isActionLoading, setIsActionLoading] = useState(false);

  // 使用 useMemo 计算 isConnecting 状态
  const isConnecting = useMemo(() => {
    return connectFetcher.state !== 'idle';
  }, [connectFetcher.state]);

  useEffect(() => {
    update1PanelConnection({
      isConnect: rootData?.connectionSettings?._1PanelConnection,
    });
  }, [rootData]);

  useEffect(() => {
    if (connection.isConnect) {
      fetch1PanelStats();
    }
  }, [connection.isConnect]);

  // 监听 connectFetcher 状态变化（连接）
  useEffect(() => {
    const data = connectFetcher.data as ApiResponse<{
      websites: _1PanelWebsite[];
      totalWebsites: number;
      lastUpdated: string;
    }>;
    if (connectFetcher.state === 'idle' && data) {
      if (data.success) {
        update1PanelConnection({
          isConnect: true,
          stats: data.data,
          serverUrl,
        });
        toast.success('连接 1Panel 成功');
      } else if (data.message) {
        toast.error(`连接 1Panel 失败: ${data.message}`);
      }
    }
  }, [connectFetcher.state, connectFetcher.data, serverUrl]);

  // 监听 settingsFetcher 状态变化（断开连接）
  useEffect(() => {
    if (settingsFetcher.state === 'idle' && settingsFetcher.data) {
      if (settingsFetcher.data.success) {
        update1PanelConnection({ isConnect: false, serverUrl: '' });
        toast.success('断开 1Panel 服务器连接');
      }
    }
  }, [settingsFetcher.state, settingsFetcher.data]);

  const handleConnect = async (event: React.FormEvent) => {
    if (!serverUrl) {
      toast.error('请填写服务器地址');
      return;
    }
    if (!apiKey) {
      toast.error('请输入 API 密钥');
      return;
    }

    event.preventDefault();

    try {
      connectFetcher.submit(
        { serverUrl, apiKey },
        {
          method: 'POST',
          action: '/api/1panel/auth',
          encType: 'application/json',
        },
      );
    } catch (error) {
      toast.error(`连接 1Panel 失败: ${error instanceof Error ? error.message : '未知错误'}`);
    }
  };

  const handleDisconnect = async () => {
    try {
      settingsFetcher.submit(
        {
          category: 'connectivity',
          key: '1panel_server_url',
        },
        {
          method: 'DELETE',
          action: '/api/user/settings',
          encType: 'application/json',
        },
      );

      await fetch('/api/user/settings', {
        method: 'DELETE',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          category: 'connectivity',
          key: '1panel_api_key',
        }),
      });
    } catch (error) {
      toast.error('断开 1Panel 连接失败');
      console.error('断开 1Panel 连接失败:', error);
    }
  };

  const handleDeleteWebsite = async (e: React.MouseEvent<HTMLButtonElement>, site: _1PanelWebsite) => {
    e.stopPropagation();

    if (!confirm(`您确定要删除站点 ${site.alias} 吗?`)) {
      return;
    }

    setIsActionLoading(true);
    try {
      const response = await fetch('/api/1panel/websites', {
        method: 'DELETE',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          siteId: site.id,
        }),
      });

      const { success, message } = (await response.json()) as ApiResponse;

      if (!response.ok || !success) {
        toast.error(`删除站点失败: ${message}`);
        return;
      }

      toast.success(message || '站点删除成功');
      const currentSiteId = localStorage.getItem(`1panel-project-${getChatId()}`);
      if (currentSiteId === site.id.toString()) {
        localStorage.removeItem(`1panel-project-${getChatId()}`);
      }
      fetch1PanelStats();
    } catch (err: unknown) {
      const error = err instanceof Error ? err.message : '未知错误';
      toast.error(`删除站点失败: ${error}`);
    }
    setIsActionLoading(false);
  };

  const handleDeployToSite = (e: React.MouseEvent<HTMLButtonElement>, site: _1PanelWebsite) => {
    e.stopPropagation();

    onDeploy(site.id);
  };

  const formatExpirationDate = (date: string) => {
    const dateObj = new Date(date);
    if (isNaN(dateObj.getTime())) {
      return '未知';
    }
    // 将日期格式化为 YYYY-MM-DD
    const formattedDate = format(dateObj, 'yyyy-MM-dd');
    if (formattedDate === '9999-12-31') {
      return '永不过期';
    }
    return formattedDate;
  };

  const renderStats = () => {
    if (!connection.isConnect || !connection.stats) {
      return null;
    }

    return (
      <div className="mt-6">
        <Collapsible open={isStatsOpen} onOpenChange={setIsStatsOpen}>
          <CollapsibleTrigger asChild>
            <div className="flex items-center justify-between p-4 rounded-lg bg-upage-elements-background dark:bg-upage-elements-background-depth-2 border border-upage-elements-borderColor dark:border-upage-elements-borderColor hover:border-upage-elements-borderColorActive/70 dark:hover:border-upage-elements-borderColorActive/70 transition-all duration-200">
              <div className="flex items-center gap-2">
                <div className="i-ph:chart-bar size-4 text-upage-elements-item-contentAccent dark:text-upage-elements-item-contentAccent" />
                <span className="text-sm font-medium text-upage-elements-textPrimary dark:text-upage-elements-textPrimary">
                  1Panel 统计信息
                </span>
              </div>
              <div
                className={classNames(
                  'i-ph:caret-down size-4 transform transition-transform duration-200 text-upage-elements-textSecondary',
                  isStatsOpen ? 'rotate-180' : '',
                )}
              />
            </div>
          </CollapsibleTrigger>
          <CollapsibleContent className="overflow-hidden">
            <div className="space-y-4 mt-4">
              <div className="flex flex-wrap items-center gap-4">
                <Badge
                  variant="outline"
                  className="flex items-center gap-1 text-upage-elements-textPrimary dark:text-upage-elements-textPrimary"
                >
                  <div className="i-heroicons:building-library size-4 text-upage-elements-item-contentAccent" />
                  <span>{connection.stats.totalWebsites} 站点</span>
                </Badge>
                {connection.stats.lastUpdated && (
                  <Badge
                    variant="outline"
                    className="flex items-center gap-1 text-upage-elements-textPrimary dark:text-upage-elements-textPrimary"
                  >
                    <div className="i-lucide:clock size-4 text-upage-elements-item-contentAccent" />
                    <span>
                      更新于 {formatDistanceToNow(new Date(connection.stats.lastUpdated), { locale: zhCN })} 前
                    </span>
                  </Badge>
                )}
              </div>
              {connection.stats.websites.length > 0 && (
                <div className="mt-4 space-y-4">
                  <div className="bg-upage-elements-background dark:bg-upage-elements-background-depth-1 border border-upage-elements-borderColor dark:border-upage-elements-borderColor rounded-lg p-4">
                    <div className="flex items-center justify-between mb-4">
                      <h4 className="text-sm font-medium flex items-center gap-2 text-upage-elements-textPrimary dark:text-upage-elements-textPrimary">
                        <div className="i-heroicons:building-library size-4 text-upage-elements-item-contentAccent dark:text-upage-elements-item-contentAccent" />
                        您的站点
                      </h4>
                      <Button
                        variant="outline"
                        size="sm"
                        onClick={() => fetch1PanelStats()}
                        disabled={fetching}
                        className="flex items-center gap-2 text-upage-elements-textPrimary dark:text-upage-elements-textPrimary hover:bg-upage-elements-item-backgroundActive/10"
                      >
                        <div
                          className={classNames(
                            'i-heroicons:arrow-path size-4 text-upage-elements-item-contentAccent dark:text-upage-elements-item-contentAccent',
                            { 'animate-spin': fetching },
                          )}
                        />
                        {fetching ? '刷新中...' : '刷新'}
                      </Button>
                    </div>
                    <div className="space-y-3">
                      {connection.stats.websites.map((site, index) => (
                        <div
                          key={site.id}
                          className={classNames(
                            'bg-upage-elements-background dark:bg-upage-elements-background-depth-1 border rounded-lg p-4 transition-all',
                            activeSiteIndex === index
                              ? 'border-upage-elements-item-contentAccent bg-upage-elements-item-backgroundActive/10'
                              : 'border-upage-elements-borderColor hover:border-upage-elements-borderColorActive/70',
                          )}
                          onClick={() => {
                            if (activeSiteIndex === index) {
                              setActiveSiteIndex(-1);
                            } else {
                              setActiveSiteIndex(index);
                            }
                          }}
                        >
                          <div className="flex items-center justify-between">
                            <div className="flex items-center gap-2">
                              <div className="i-heroicons:globe-alt size-5 text-upage-elements-item-contentAccent dark:text-upage-elements-item-contentAccent" />
                              <span className="font-medium text-upage-elements-textPrimary dark:text-upage-elements-textPrimary">
                                {site.alias}
                              </span>
                            </div>
                            <div className="flex items-center gap-2">
                              <Badge
                                variant={site.status === 'Running' ? 'default' : 'destructive'}
                                className="flex items-center gap-1 text-upage-elements-textPrimary dark:text-upage-elements-textPrimary"
                              >
                                {site.status === 'Running' ? (
                                  <div className="i-lucide:check-circle size-4 text-green-500" />
                                ) : (
                                  <div className="i-lucide:x-circle size-4 text-red-500" />
                                )}
                                <span className="text-upage-elements-textPrimary dark:text-upage-elements-textPrimary">
                                  {site.status === 'Running' ? '已启动' : '已停止'}
                                </span>
                              </Badge>
                            </div>
                          </div>
                          <div className="mt-3 flex flex-col gap-2">
                            {site.domains.map((domain) => (
                              <a
                                key={domain.id}
                                href={`${site.protocol.toLowerCase()}://${domain.domain}`}
                                target="_blank"
                                rel="noopener noreferrer"
                                className="text-sm flex items-center gap-1 transition-colors text-upage-elements-link-text hover:text-upage-elements-link-textHover dark:text-white dark:hover:text-upage-elements-link-textHover w-fit"
                                onClick={(e) => e.stopPropagation()}
                              >
                                <div className="i-heroicons:paper-airplane size-3 text-upage-elements-item-contentAccent dark:text-upage-elements-item-contentAccent" />
                                <span className="underline decoration-1 underline-offset-2">
                                  {`${site.protocol.toLowerCase()}://${domain.domain}`}
                                </span>
                              </a>
                            ))}
                            <div className="flex items-center gap-2 mt-1">
                              {(() => {
                                const typeInfo = getWebsiteTypeInfo(site.type);
                                return (
                                  <Badge
                                    variant="secondary"
                                    className={`flex items-center gap-1 px-1.5 py-0.5 rounded-md ${typeInfo.color}`}
                                  >
                                    <div className={`${typeInfo.icon} size-3`} />
                                    <span>{typeInfo.label}</span>
                                  </Badge>
                                );
                              })()}
                              {activeSiteIndex === index && (
                                <div className="flex gap-4 text-sm text-gray-700">
                                  <div className="flex items-center gap-1">
                                    <div className="i-lucide:clock size-4 text-upage-elements-item-contentAccent dark:text-upage-elements-item-contentAccent" />
                                    <span className="text-upage-elements-textSecondary dark:text-upage-elements-textSecondary">
                                      创建于{' '}
                                      <span className="text-upage-elements-textPrimary dark:text-upage-elements-textPrimary">
                                        {formatDistanceToNow(new Date(site.createdAt), { locale: zhCN })}
                                      </span>{' '}
                                      前
                                    </span>
                                  </div>
                                  <div className="flex items-center gap-1">
                                    <div className="i-pajamas:expire size-3 text-upage-elements-item-contentAccent dark:text-upage-elements-item-contentAccent"></div>
                                    <span className="text-upage-elements-textSecondary dark:text-upage-elements-textSecondary">
                                      过期时间:{' '}
                                      <span className="text-upage-elements-textPrimary dark:text-upage-elements-textPrimary">
                                        {formatExpirationDate(site.expireDate)}
                                      </span>
                                    </span>
                                  </div>
                                </div>
                              )}
                            </div>
                          </div>
                          {activeSiteIndex === index && (
                            <>
                              <div className="mt-4 pt-3 border-t border-upage-elements-borderColor"></div>
                              <div className="text-sm flex justify-end">
                                <div>
                                  <div className="flex items-center gap-2">
                                    {site.type === 'static' && (
                                      <motion.button
                                        onClick={(e) => handleDeployToSite(e, site)}
                                        disabled={isDeploying}
                                        className="px-4 py-2 rounded-lg h-8 bg-black dark:bg-white dark:text-black text-white text-sm hover:bg-gray-800 dark:hover:bg-gray-200 inline-flex items-center gap-2"
                                        whileHover={{ scale: 1.02 }}
                                        whileTap={{ scale: 0.98 }}
                                      >
                                        {isDeploying ? (
                                          <>
                                            <div className="i-ph:spinner-gap animate-spin size-4" />
                                            部署中...
                                          </>
                                        ) : (
                                          <>
                                            <div className="i-ph:rocket-launch size-4" />
                                            部署到此网站
                                          </>
                                        )}
                                      </motion.button>
                                    )}
                                    <Button
                                      key="delete"
                                      variant="destructive"
                                      size="sm"
                                      onClick={(e) => handleDeleteWebsite(e, site)}
                                      disabled={isActionLoading}
                                      className="flex items-center gap-1 text-upage-elements-textPrimary dark:text-upage-elements-textPrimary"
                                    >
                                      <div className="i-lucide:trash size-4 text-white text-upage-elements-textPrimary dark:text-upage-elements-textPrimary" />
                                      删除网站
                                    </Button>
                                  </div>
                                </div>
                              </div>
                            </>
                          )}
                        </div>
                      ))}
                    </div>
                  </div>
                </div>
              )}
            </div>
          </CollapsibleContent>
        </Collapsible>
      </div>
    );
  };

  // 根据网站类型返回对应的标签信息
  const getWebsiteTypeInfo = (type: string) => {
    switch (type) {
      case 'deployment':
        return {
          label: '一键部署',
          icon: 'i-ph:rocket-launch',
          color: 'bg-blue-100 text-blue-700 dark:bg-blue-800/30 dark:text-blue-300',
        };
      case 'runtime':
        return {
          label: '运行环境',
          icon: 'i-ph:code',
          color: 'bg-green-100 text-green-700 dark:bg-green-800/30 dark:text-green-300',
        };
      case 'proxy':
        return {
          label: '反向代理',
          icon: 'i-ph:arrows-left-right',
          color: 'bg-purple-100 text-purple-700 dark:bg-purple-800/30 dark:text-purple-300',
        };
      case 'static':
        return {
          label: '静态网站',
          icon: 'i-ph:file-html',
          color: 'bg-orange-100 text-orange-700 dark:bg-orange-800/30 dark:text-orange-300',
        };
      case 'subsite':
        return {
          label: '子网站',
          icon: 'i-ph:tree-structure',
          color: 'bg-gray-100 text-gray-700 dark:bg-gray-800/30 dark:text-gray-300',
        };
      default:
        return {
          label: '未知类型',
          icon: 'i-ph:question',
          color: 'bg-gray-100 text-gray-700 dark:bg-gray-800/30 dark:text-gray-300',
        };
    }
  };

  return (
    <ConnectionBorder>
      {!connection.isConnect ? (
        <div className="space-y-4">
          <div>
            <label className="block text-sm text-upage-elements-textSecondary mb-2">服务器地址</label>
            <input
              type="text"
              value={serverUrl}
              onChange={(e) => setServerUrl(e.target.value)}
              disabled={fetching}
              placeholder="https://your-1panel-server.com"
              className={classNames(
                'w-full px-3 py-2 rounded-lg text-sm',
                'bg-[#F8F8F8] dark:bg-[#1A1A1A]',
                'border border-[#E5E5E5] dark:border-[#333333]',
                'text-upage-elements-textPrimary placeholder-upage-elements-textTertiary',
                'focus:outline-none focus:ring-1 focus:ring-upage-elements-borderColorActive',
                'disabled:opacity-50',
              )}
            />
          </div>

          <div>
            <label className="block text-sm text-upage-elements-textSecondary mb-2">API 密钥</label>
            <input
              type="password"
              value={apiKey}
              onChange={(e) => setApiKey(e.target.value)}
              disabled={fetching}
              placeholder="请输入您的 API 密钥"
              className={classNames(
                'w-full px-3 py-2 rounded-lg text-sm',
                'bg-[#F8F8F8] dark:bg-[#1A1A1A]',
                'border border-[#E5E5E5] dark:border-[#333333]',
                'text-upage-elements-textPrimary placeholder-upage-elements-textTertiary',
                'focus:outline-none focus:ring-1 focus:ring-upage-elements-borderColorActive',
                'disabled:opacity-50',
              )}
            />
          </div>

          <button
            onClick={handleConnect}
            disabled={isConnecting || !serverUrl || !apiKey}
            className={classNames(
              'px-4 py-2 rounded-lg text-sm flex items-center gap-2',
              'bg-upage-elements-button-secondary-background',
              'hover:bg-upage-elements-button-secondary-backgroundHover',
              'disabled:opacity-50 disabled:cursor-not-allowed',
              'text-upage-elements-textPrimary',
            )}
          >
            {isConnecting ? (
              <>
                <div className="i-ph:spinner-gap animate-spin" />
                连接中...
              </>
            ) : (
              <>
                <div className="i-ph:plug-charging size-4" />
                连接
              </>
            )}
          </button>
        </div>
      ) : (
        <div className="space-y-6">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-3">
              <span className="text-sm text-upage-elements-textSecondary flex items-center gap-1">
                <div className="i-ph:check-circle size-4 text-green-500" />
                已连接到 1Panel 服务器
              </span>
            </div>

            <div className="flex items-center gap-2 ml-auto">
              <Button
                variant="outline"
                onClick={() => window.open(`${connection.serverUrl}/websites`, '_blank', 'noopener,noreferrer')}
                className="flex items-center gap-2 hover:bg-upage-elements-item-backgroundActive/10 hover:text-upage-elements-textPrimary dark:hover:text-upage-elements-textPrimary transition-colors"
              >
                <div className="i-mingcute:dashboard-line size-4" />
                仪表盘
              </Button>
              <Button
                onClick={() => fetch1PanelStats()}
                disabled={fetching}
                variant="outline"
                className="flex items-center gap-2 hover:bg-upage-elements-item-backgroundActive/10 hover:text-upage-elements-textPrimary dark:hover:text-upage-elements-textPrimary transition-colors"
              >
                {fetching ? (
                  <>
                    <div className="i-ph:spinner-gap size-4 animate-spin text-upage-elements-textPrimary dark:text-upage-elements-textPrimary" />
                    <span className="text-upage-elements-textPrimary dark:text-upage-elements-textPrimary">
                      刷新...
                    </span>
                  </>
                ) : (
                  <>
                    <div className="i-ph:arrows-clockwise size-4 text-upage-elements-textPrimary dark:text-upage-elements-textPrimary" />
                    <span className="text-upage-elements-textPrimary dark:text-upage-elements-textPrimary">
                      刷新统计
                    </span>
                  </>
                )}
              </Button>
              <Button onClick={handleDisconnect} variant="destructive" size="sm" className="flex items-center gap-2">
                <div className="i-ph:sign-out size-4" />
                断开连接
              </Button>
            </div>
          </div>

          {renderStats()}
        </div>
      )}
    </ConnectionBorder>
  );
}
