import { useState, useRef, useEffect } from 'react';
import { Loader2, X } from 'lucide-react';
import { t } from '@/lib/i18n';
import { useSkills } from '@/hooks/useApi';
import { toggleSkill as toggleSkillApi, openSkillhub } from '@/lib/api';
import { uninstallSkill } from '@/lib/skillhubApi';
import { assetBasePath } from '@/lib/basePath';
import type { Skill } from '@/types/api';

function SkillSwitch({
  enabled,
  loading,
  onToggle,
}: {
  enabled: boolean;
  loading: boolean;
  onToggle: () => void;
}) {
  return (
    <button
      onClick={onToggle}
      disabled={loading}
      className="relative w-10 h-6 rounded-full transition-colors disabled:opacity-50 flex-shrink-0"
      style={{
        background: enabled ? 'var(--pc-accent)' : 'var(--pc-border)',
      }}
      aria-pressed={enabled}
      aria-label={enabled ? t('skills.enabled') : t('skills.disabled')}
    >
      {loading ? (
        <Loader2 className="absolute top-1 left-1 w-4 h-4 animate-spin text-white" />
      ) : (
        <span
          className="absolute top-1 left-1 w-4 h-4 rounded-full bg-white transition-transform"
          style={{
            transform: enabled ? 'translateX(16px)' : 'translateX(0)',
          }}
        />
      )}
    </button>
  );
}

function UninstallConfirmDialog({
  open,
  onCancel,
  onConfirm,
  uninstalling,
}: {
  open: boolean;
  onCancel: () => void;
  onConfirm: () => void;
  uninstalling: boolean;
}) {
  if (!open) return null;

  return (
    <div
      style={{
        position: 'fixed',
        top: 0,
        left: 0,
        width: '100vw',
        height: '100vh',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        zIndex: 200,
        transform: 'translate(-28px, -40px)',
      }}
    >
      <div
        style={{
          width: 376,
          height: 212,
          background: '#fff',
          borderRadius: 8,
          boxSizing: 'border-box',
          display: 'flex',
          flexDirection: 'column',
          overflow: 'hidden',
          boxShadow: '0 6px 30px rgba(0,0,0,0.12)',
        }}
      >
        <div
          style={{
            width: 376,
            height: 40,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'flex-end',
            paddingRight: 8,
            boxSizing: 'border-box',
            flexShrink: 0,
          }}
        >
          <button
            className="skill-dialog-close-btn"
            onClick={onCancel}
          >
            <X size={16} />
          </button>
        </div>

        <div
          style={{
            paddingLeft: 24,
            paddingRight: 24,
            paddingBottom: 24,
            flex: 1,
            display: 'flex',
            flexDirection: 'column',
          }}
        >
          <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8, marginBottom: 4 }}>
            <img
              src={`${assetBasePath}/icons/dialog-question.svg`}
              alt="question"
              width={16}
              height={16}
              style={{ flexShrink: 0, marginTop: 2 }}
            />
            <span style={{ fontSize: 14, color: 'var(--pc-text-primary)', lineHeight: '20px' }}>
              确认卸载该技能？
            </span>
          </div>

          <span
            style={{
              fontSize: 14,
              color: 'var(--pc-text-muted)',
              lineHeight: '20px',
              marginLeft: 24,
            }}
          >
            卸载后，该技能的本地文件与配置数据将被删除，且无法恢复。
          </span>

          <div style={{ flex: 1 }} />

          <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
            <button
              className="skill-dialog-cancel-btn"
              onClick={onCancel}
            >
              取消
            </button>
            <button
              className="skill-dialog-uninstall-btn"
              onClick={onConfirm}
              disabled={uninstalling}
            >
              {uninstalling ? (
                <Loader2 className="h-4 w-4 animate-spin" style={{ color: '#fff' }} />
              ) : (
                '卸载'
              )}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

function SkillOperateMenu({
  skillName,
  onUninstalled,
}: {
  skillName: string;
  onUninstalled: () => void;
}) {
  const [menuOpen, setMenuOpen] = useState(false);
  const [dialogOpen, setDialogOpen] = useState(false);
  const [uninstalling, setUninstalling] = useState(false);
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!menuOpen) return;
    const handler = (e: MouseEvent) => {
      if (ref.current && !ref.current.contains(e.target as Node)) setMenuOpen(false);
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [menuOpen]);

  const handleUninstall = async () => {
    setUninstalling(true);
    try {
      await uninstallSkill(skillName);
      setDialogOpen(false);
      setMenuOpen(false);
      onUninstalled();
    } catch (err) {
      console.error('Failed to uninstall skill:', err);
    } finally {
      setUninstalling(false);
    }
  };

  return (
    <>
      <UninstallConfirmDialog
        open={dialogOpen}
        onCancel={() => setDialogOpen(false)}
        onConfirm={handleUninstall}
        uninstalling={uninstalling}
      />
      <div ref={ref} style={{ position: 'relative', display: 'inline-block' }}>
        <button
          className="skill-operate-btn"
          onClick={() => setMenuOpen((v) => !v)}
        >
          <img
            src={`${assetBasePath}/icons/operate-omit.svg`}
            alt="operate"
            width={16}
            height={16}
          />
        </button>
        {menuOpen && (
          <div
            style={{
              position: 'absolute',
              right: 0,
              top: '100%',
              zIndex: 100,
              background: '#fff',
              border: '1px solid #e8e8e8',
              borderRadius: 8,
              boxShadow: '0 4px 16px rgba(0,0,0,0.12)',
              width: 180,
              height: 52,
              padding: 8,
              boxSizing: 'border-box',
            }}
          >
            <button
              className="skill-uninstall-btn"
              onClick={() => { setMenuOpen(false); setDialogOpen(true); }}
            >
              卸载
            </button>
          </div>
        )}
      </div>
    </>
  );
}

function SkillCard({
  skill,
  isDefault,
  isToggling,
  onToggle,
  onUninstalled,
}: {
  skill: Skill;
  isDefault: boolean;
  isToggling: boolean;
  onToggle: () => void;
  onUninstalled: () => void;
}) {
  const descRef = useRef<HTMLParagraphElement>(null);
  const [isTruncated, setIsTruncated] = useState(false);
  const [showTooltip, setShowTooltip] = useState(false);
  const [tooltipAbove, setTooltipAbove] = useState(false);

  useEffect(() => {
    requestAnimationFrame(() => {
      if (descRef.current) {
        setIsTruncated(descRef.current.scrollHeight > descRef.current.clientHeight);
      }
    });
  }, [skill.description]);

  return (
    <div
      style={{
        width: 326,
        height: 140,
        padding: 16,
        background: '#F6F6F6',
        borderRadius: 6,
        boxSizing: 'border-box',
        position: 'relative',
      }}
    >
      <div
        style={{
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          height: 20,
        }}
      >
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0, flex: 1 }}>
          <div
            style={{
              width: 32,
              height: 32,
              background: '#E1EEFE',
              borderRadius: 4,
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
              flexShrink: 0,
            }}
          >
            <span style={{ fontSize: 16, color: '#3790FA', fontWeight: 600, lineHeight: 1 }}>
              {skill.name.charAt(0).toUpperCase()}
            </span>
          </div>
          <span
            style={{
              fontSize: 14,
              color: 'var(--pc-text-primary)',
              fontWeight: 600,
              overflow: 'hidden',
              textOverflow: 'ellipsis',
              whiteSpace: 'nowrap',
            }}
          >
            {skill.name}
          </span>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 4, flexShrink: 0 }}>
          {!isDefault && (
            <SkillOperateMenu
              skillName={skill.name}
              onUninstalled={onUninstalled}
            />
          )}
          <SkillSwitch
            enabled={skill.enabled}
            loading={isToggling}
            onToggle={onToggle}
          />
        </div>
      </div>

        <div
          className="relative"
          onMouseEnter={() => {
            if (!isTruncated) return;
            if (descRef.current) {
              const rect = descRef.current.getBoundingClientRect();
              setTooltipAbove(rect.bottom + 100 > window.innerHeight);
            }
            setShowTooltip(true);
          }}
          onMouseLeave={() => setShowTooltip(false)}
        >
        <p
          ref={descRef}
          style={{
            width: 294,
            height: 40,
            fontSize: 14,
            color: 'var(--pc-text-muted)',
            margin: 0,
            marginTop: 8,
            lineHeight: '20px',
            overflow: 'hidden',
            display: '-webkit-box',
            WebkitLineClamp: 2,
            WebkitBoxOrient: 'vertical',
          }}
        >
          {skill.description}
        </p>
        {isTruncated && showTooltip && (
          <div
            className={`absolute z-50 left-0 p-2 rounded-md text-xs whitespace-pre-wrap max-w-[300px] shadow-lg border ${tooltipAbove ? 'bottom-full mb-1' : 'top-full mt-1'}`}
            style={{
              background: '#ffffff',
              color: 'var(--pc-text-primary)',
              borderColor: 'var(--pc-border)',
            }}
          >
            {skill.description}
          </div>
        )}
      </div>

      <div style={{ position: 'absolute', bottom: 16, left: 16 }}>
        <span
          style={{
            display: 'inline-flex',
            alignItems: 'center',
            height: 24,
            paddingLeft: 8,
            paddingRight: 8,
            fontSize: 12,
            color: 'var(--pc-text-secondary)',
            background: '#E6E6E6',
            borderRadius: 10,
            boxSizing: 'border-box',
          }}
        >
          {isDefault ? '内置' : '技能市场'}
        </span>
      </div>
    </div>
  );
}

export default function Skills() {
  const { data: skills, loading, error, refetch } = useSkills();
  const [toggling, setToggling] = useState<string | null>(null);
  const [searchQuery, setSearchQuery] = useState('');
  const [isSearchFocused, setIsSearchFocused] = useState(false);
  const searchInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    const handler = (e: MouseEvent) => e.preventDefault();
    document.addEventListener('contextmenu', handler);
    return () => document.removeEventListener('contextmenu', handler);
  }, []);

  const handleToggle = async (skillName: string, currentEnabled: boolean) => {
    setToggling(skillName);
    try {
      await toggleSkillApi(skillName, !currentEnabled);
      refetch();
    } catch (err) {
      console.error('Failed to toggle skill:', err);
    } finally {
      setToggling(null);
    }
  };

  const filtered = (skills || []).filter((skill) => {
    if (!searchQuery) return true;
    const q = searchQuery.toLowerCase();
    return (
      skill.name.toLowerCase().includes(q) ||
      skill.description.toLowerCase().includes(q)
    );
  });

  const sorted = [...filtered].sort((a, b) => {
    const aDefault = a.is_default;
    const bDefault = b.is_default;
    if (aDefault && !bDefault) return -1;
    if (!aDefault && bDefault) return 1;
    return 0;
  });

  if (loading) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: 200 }}>
        <Loader2 className="h-8 w-8 animate-spin" style={{ color: 'var(--pc-accent)' }} />
      </div>
    );
  }

  if (error) {
    return (
      <div style={{ textAlign: 'center', padding: 24 }}>
        <p style={{ color: 'var(--pc-text-muted)' }}>{t('skills.empty')}</p>
      </div>
    );
  }

  return (
    <div
      style={{
        maxWidth: 1040,
        width: '100%',
        padding: '0 0 0 24px',
        boxSizing: 'border-box',
        height: '100%',
        display: 'flex',
        flexDirection: 'column',
      }}
    >
      <div
        style={{
          height: 36,
          display: 'flex',
          alignItems: 'center',
          flexShrink: 0,
          paddingRight: 24,
        }}
      >
        <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
          <span style={{ fontSize: 14, color: 'var(--pc-text-primary)', fontWeight: 500 }}>
            已安装（{skills?.length || 0}）
          </span>
        </div>

        <div style={{ flex: 1 }} />

        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <div
            onClick={() => searchInputRef.current?.focus()}
            style={{
              width: 236,
              height: 36,
              background: isSearchFocused ? '#FFFFFF' : '#E6E6E6',
              borderRadius: 4,
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
              paddingLeft: 10,
              paddingRight: 10,
              gap: 6,
              boxSizing: 'border-box',
              border: isSearchFocused ? '2px solid #3790FA' : '2px solid transparent',
              transition: 'background 0.2s ease, border-color 0.2s ease',
              cursor: 'text',
            }}
          >
            <div
              style={{
                display: 'flex',
                alignItems: 'center',
                gap: 6,
                width: '100%',
                justifyContent: isSearchFocused || searchQuery ? 'flex-start' : 'center',
              }}
            >
              <img
                src={`${assetBasePath}/icons/search.svg`}
                alt="search"
                width={14}
                height={14}
                style={{ flexShrink: 0 }}
              />
              <input
                ref={searchInputRef}
                type="text"
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                onFocus={() => setIsSearchFocused(true)}
                onBlur={() => setIsSearchFocused(false)}
                placeholder="搜索"
                className="placeholder-[#A6A6A6]"
                style={{
                  border: 'none',
                  outline: 'none',
                  background: 'transparent',
                  fontSize: 14,
                  color: 'var(--pc-text-primary)',
                  width: isSearchFocused || searchQuery ? '100%' : 40,
                  flex: isSearchFocused || searchQuery ? 1 : 'none',
                  padding: 0,
                  textAlign: 'left',
                }}
              />
            </div>
          </div>

          <button
            onClick={async () => {
              try {
                await openSkillhub();
              } catch (err) {
                console.error('Failed to open skillhub:', err);
              }
            }}
            style={{
              height: 36,
              paddingLeft: 16,
              paddingRight: 16,
              background: '#E6E6E6',
              border: 'none',
              borderRadius: 4,
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
              gap: 4,
              cursor: 'pointer',
              color: 'var(--pc-text-primary)',
              fontSize: 14,
              boxSizing: 'border-box',
            }}
          >
            <img
              src={`${assetBasePath}/icons/skill-icon.svg`}
              alt="skill"
              width={14}
              height={14}
              style={{ flexShrink: 0 }}
            />
            <span>技能中心</span>
          </button>
        </div>
      </div>

      <div
        className="skill-list-scroll scrollbar-auto-hide"
        style={{
          flex: 1,
          minHeight: 0,
          overflowY: 'overlay',
          marginTop: 8,
          paddingRight: 24,
        }}
      >
        <div
          style={{
            width: 992,
            display: 'flex',
            flexWrap: 'wrap',
            gap: 7,
          }}
        >
        {sorted.length === 0 ? (
          <div
            style={{
              width: 992,
              textAlign: 'center',
              padding: '48px 0',
              color: 'var(--pc-text-muted)',
              fontSize: 14,
            }}
          >
            {t('skills.empty')}
          </div>
        ) : (
          sorted.map((skill) => (
            <SkillCard
              key={skill.name}
              skill={skill}
              isDefault={skill.is_default}
              isToggling={toggling === skill.name}
              onToggle={() => handleToggle(skill.name, skill.enabled)}
              onUninstalled={() => refetch()}
            />
          ))
        )}
        </div>
      </div>
    </div>
  );
}
