import React, { useState, useEffect, useMemo } from 'react';
import {
  RefreshCcw,
  ChevronDown,
  User,
  Globe,
  Link,
  Clipboard,
  ShieldAlert,
  Loader2
} from 'lucide-react';
import { Credential, UserGroup, BrowserGroup } from '../types';
import { formatDate } from '../utils';

interface CredentialsTabProps {
  hostname: string;
}

export default function CredentialsTab({ hostname }: CredentialsTabProps) {
  const [credentials, setCredentials] = useState<Credential[]>([]);
  const [loadingCredentials, setLoadingCredentials] = useState(false);
  const [expandedUsers, setExpandedUsers] = useState<string[]>([]);
  const [expandedBrowsers, setExpandedBrowsers] = useState<string[]>([]);
  const [expandedCredentials, setExpandedCredentials] = useState<string[]>([]);
  const [revealedPasswords, setRevealedPasswords] = useState<string[]>([]);

  const fetchCredentials = async () => {
    try {
      setLoadingCredentials(true);
      const response = await fetch(`/hosts/${hostname}/credentials`);
      if (!response.ok) throw new Error('获取凭据数据失败');
      const data = await response.json();
      setCredentials(data);

      if (data.length > 0) {
        const firstUser = data[0].username;
        if (!expandedUsers.includes(firstUser)) {
          setExpandedUsers([firstUser]);
        }
      }
    } catch (error) {
      console.error('获取凭据数据失败:', error);
    } finally {
      setLoadingCredentials(false);
    }
  };

  useEffect(() => {
    fetchCredentials();
  }, [hostname]);

  const credentialsByUser = useMemo<UserGroup[]>(() => {
    const userMap = new Map<string, Credential[]>();

    credentials.forEach(cred => {
      if (!userMap.has(cred.username)) {
        userMap.set(cred.username, []);
      }
      userMap.get(cred.username)!.push(cred);
    });

    const result: UserGroup[] = [];

    userMap.forEach((userCreds, username) => {
      const latestSyncTime = userCreds.reduce((latest, cred) => {
        const credTime = new Date(cred.lastSyncTime);
        return credTime > latest ? credTime : latest;
      }, new Date(0)).toISOString();

      const browserMap = new Map<string, Credential[]>();

      userCreds.forEach(cred => {
        if (!browserMap.has(cred.browser)) {
          browserMap.set(cred.browser, []);
        }
        browserMap.get(cred.browser)!.push(cred);
      });

      const browsers: BrowserGroup[] = [];
      browserMap.forEach((browserCreds, browserName) => {
        browsers.push({
          name: browserName,
          credentials: browserCreds
        });
      });

      result.push({
        username,
        browsers,
        total: userCreds.length,
        lastSyncTime: latestSyncTime
      });
    });

    return result;
  }, [credentials]);

  const toggleUserExpanded = (username: string) => {
    if (expandedUsers.includes(username)) {
      setExpandedUsers(expandedUsers.filter(u => u !== username));
    } else {
      setExpandedUsers([...expandedUsers, username]);
    }
  };

  const toggleBrowserExpanded = (browserKey: string) => {
    if (expandedBrowsers.includes(browserKey)) {
      setExpandedBrowsers(expandedBrowsers.filter(b => b !== browserKey));
    } else {
      setExpandedBrowsers([...expandedBrowsers, browserKey]);
    }
  };

  const toggleCredentialExpanded = (credId: string) => {
    if (expandedCredentials.includes(credId)) {
      setExpandedCredentials(expandedCredentials.filter(c => c !== credId));
    } else {
      setExpandedCredentials([...expandedCredentials, credId]);
    }
  };

  const revealPassword = (passwordKey: string) => {
    if (!revealedPasswords.includes(passwordKey)) {
      setRevealedPasswords([...revealedPasswords, passwordKey]);
    }
  };

  const copyToClipboard = async (text: string) => {
    try {
      await navigator.clipboard.writeText(text);
    } catch (err) {
      console.error('复制失败:', err);
    }
  };

  return (
    <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm p-6">
      <div className="flex items-center justify-between mb-6">
        <h2 className="text-xl font-medium text-gray-900 dark:text-white">凭据信息</h2>
        <div className="flex space-x-2">
          <button
            onClick={fetchCredentials}
            className="px-3 py-1.5 bg-blue-600 hover:bg-blue-700 text-white text-sm rounded focus:outline-none flex items-center"
          >
            <RefreshCcw className={`h-4 w-4 mr-1 ${loadingCredentials ? 'animate-spin' : ''}`} />
            刷新
          </button>
        </div>
      </div>

      {loadingCredentials ? (
        <div className="flex justify-center py-12">
          <div className="animate-pulse flex flex-col items-center">
            <Loader2 className="h-8 w-8 text-blue-600 animate-spin" />
            <p className="mt-2 text-gray-500 dark:text-gray-400">加载凭据信息...</p>
          </div>
        </div>
      ) : credentialsByUser.length === 0 ? (
        <div className="py-12 flex flex-col items-center justify-center">
          <ShieldAlert className="h-12 w-12 text-gray-400 mb-3" />
          <p className="text-gray-500 dark:text-gray-400 mb-1">没有找到任何凭据信息</p>
          <p className="text-sm text-gray-400 dark:text-gray-500">可能是该主机尚未上报凭据数据</p>
        </div>
      ) : (
        <div className="space-y-6">
          {credentialsByUser.map((userGroup, index) => (
            <div key={index} className="border border-gray-200 dark:border-gray-700 rounded-md overflow-hidden">
              <div className="bg-gray-50 dark:bg-gray-700 px-4 py-3">
                <div className="flex items-center justify-between">
                  <div
                    className="flex items-center cursor-pointer"
                    onClick={() => toggleUserExpanded(userGroup.username)}
                  >
                    <User className="h-5 w-5 text-gray-500 dark:text-gray-400 mr-2" />
                    <h3 className="font-medium text-gray-900 dark:text-white">{userGroup.username}</h3>
                    <div className="ml-3 text-sm text-gray-500 dark:text-gray-400">
                      ({userGroup.browsers.length} 个浏览器, {userGroup.total} 个凭据)
                    </div>
                    <div className="ml-2 text-xs text-gray-400 dark:text-gray-500">
                      {userGroup.lastSyncTime ? `最后同步: ${formatDate(userGroup.lastSyncTime, 'short')}` : '未同步'}
                    </div>
                  </div>
                </div>
              </div>

              {expandedUsers.includes(userGroup.username) && (
                <div className="divide-y divide-gray-100 dark:divide-gray-600">
                  {userGroup.browsers.map((browser) => (
                    <div
                      key={`${userGroup.username}-${browser.name}`}
                      className="px-4 py-3 hover:bg-gray-50 dark:hover:bg-gray-700"
                    >
                      <div
                        className="flex items-center mb-2 cursor-pointer"
                        onClick={() => toggleBrowserExpanded(`${userGroup.username}-${browser.name}`)}
                      >
                        <div className="flex items-center">
                          <Globe className="h-4 w-4 text-gray-500 dark:text-gray-400 mr-2" />
                          <span className="font-medium text-gray-800 dark:text-gray-200">{browser.name}</span>
                          <span className="ml-2 text-sm text-gray-500 dark:text-gray-400">
                            ({browser.credentials.length} 个站点)
                          </span>
                        </div>
                        <ChevronDown
                          className={`h-4 w-4 text-gray-500 dark:text-gray-400 ml-2 transition-transform duration-200 ${expandedBrowsers.includes(`${userGroup.username}-${browser.name}`) ? 'rotate-180' : ''
                            }`}
                        />
                      </div>

                      {expandedBrowsers.includes(`${userGroup.username}-${browser.name}`) && (
                        <div className="pl-6 space-y-3 mt-2">
                          {browser.credentials.map((cred) => {
                            const credentialId = cred._id || cred.id || `${userGroup.username}-${browser.name}-${cred.url}-${cred.login}`;
                            const isExpanded = expandedCredentials.includes(credentialId);
                            return (
                              <div
                                key={credentialId}
                                className="border border-gray-200 dark:border-gray-600 rounded-md overflow-hidden"
                              >
                                <div
                                  className="bg-gray-50 dark:bg-gray-700 px-3 py-2 flex items-center justify-between cursor-pointer"
                                  onClick={() => toggleCredentialExpanded(credentialId)}
                                >
                                  <div className="flex items-center">
                                    <Link className="h-4 w-4 text-gray-500 dark:text-gray-400 mr-2" />
                                    <div className="text-sm font-medium text-gray-900 dark:text-white truncate max-w-md">
                                      {cred.url}
                                    </div>
                                  </div>
                                  <ChevronDown
                                    className={`h-4 w-4 text-gray-500 dark:text-gray-400 transition-transform duration-200 ${isExpanded ? 'rotate-180' : ''}`}
                                  />
                                </div>

                                {isExpanded && (
                                  <div className="bg-white dark:bg-gray-800 px-3 py-2">
                                    <div className="grid grid-cols-1 gap-2 sm:grid-cols-2">
                                      <div className="flex items-center">
                                        <span className="text-sm text-gray-500 dark:text-gray-400 w-16">用户名:</span>
                                        <span className="text-sm font-medium ml-2 text-gray-900 dark:text-white">{cred.login}</span>
                                      </div>

                                      <div className="flex flex-col">
                                        <div className="flex items-center mb-1">
                                          <span className="text-sm text-gray-500 dark:text-gray-400 w-16">密码历史:</span>
                                          <span className="text-xs bg-gray-100 dark:bg-gray-600 text-gray-600 dark:text-gray-300 rounded px-1">
                                            {cred.passwords.length} 条记录
                                          </span>
                                        </div>

                                        <div className="pl-6 space-y-2 mt-1">
                                          {cred.passwords.map((pwd, pwdIndex) => {
                                            const pwdKey = `${credentialId}-${pwdIndex}`;
                                            const revealed = revealedPasswords.includes(pwdKey);
                                            return (
                                              <div
                                                key={pwdIndex}
                                                className="flex items-center group relative"
                                              >
                                                <span className="text-xs text-gray-400 dark:text-gray-500 w-24 flex-shrink-0">
                                                  {formatDate(pwd.timestamp, 'short')}
                                                </span>
                                                <div className="flex-1 flex items-center">
                                                  <span
                                                    className="text-sm font-mono bg-gray-50 dark:bg-gray-700 text-gray-900 dark:text-white px-2 py-0.5 rounded flex-1 cursor-pointer"
                                                    onClick={() => revealed ? null : revealPassword(pwdKey)}
                                                  >
                                                    {revealed ? pwd.value : '••••••••'}
                                                  </span>
                                                  <button
                                                    onClick={() => copyToClipboard(pwd.value)}
                                                    className="ml-2 opacity-0 group-hover:opacity-100 text-gray-400 dark:text-gray-500 hover:text-gray-700 dark:hover:text-gray-300"
                                                  >
                                                    <Clipboard className="h-4 w-4" />
                                                  </button>
                                                </div>
                                              </div>
                                            );
                                          })}
                                        </div>
                                      </div>
                                    </div>
                                  </div>
                                )}
                              </div>
                            );
                          })}
                        </div>
                      )}
                    </div>
                  ))}
                </div>
              )}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}
