import { useEffect, useState, useRef } from "react";
import { getToken } from "@/lib/auth";
import { useWorkspace } from "@/lib/workspace";
import {
  fetchAvailableSkills,
  enableSkill,
  disableSkill,
  deleteSkill,
  triggerHotReload,
  uploadSkill,
  type Skill,
} from "@/lib/skills";
import { useTranslation } from "@/lib/i18n";

interface SkillsSectionProps {
  workspaceId: string;
}

export default function SkillsSection({ workspaceId }: SkillsSectionProps) {
  const { t } = useTranslation();
  const { triggerSkillsRefresh } = useWorkspace();
  const [skills, setSkills] = useState<Skill[]>([]);
  const [pendingChanges, setPendingChanges] = useState<Map<string, boolean>>(new Map());
  const [loading, setLoading] = useState(true);
  const [reloading, setReloading] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [uploadingFileName, setUploadingFileName] = useState<string | null>(null);
  const [uploadError, setUploadError] = useState<string | null>(null);
  const [uploadSuccess, setUploadSuccess] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [successMessage, setSuccessMessage] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    loadSkills();
  }, [workspaceId]);

  const loadSkills = async () => {
    const token = getToken();
    if (!token) {
      setError(t("skillHub.notAuthenticated"));
      setLoading(false);
      return;
    }

    try {
      setLoading(true);
      setError(null);
      const availableSkills = await fetchAvailableSkills(workspaceId, token);
      setSkills(availableSkills);
      setPendingChanges(new Map());
    } catch (err) {
      setError(err instanceof Error ? err.message : t("skillHub.loadFailed"));
    } finally {
      setLoading(false);
    }
  };

  const handleToggleSkill = (skill: Skill) => {
    const currentEnabled = pendingChanges.has(skill.name)
      ? pendingChanges.get(skill.name)!
      : skill.enabled;

    const newPendingChanges = new Map(pendingChanges);
    const newEnabled = !currentEnabled;

    // If the new state matches the original state, remove from pending changes
    if (newEnabled === skill.enabled) {
      newPendingChanges.delete(skill.name);
    } else {
      newPendingChanges.set(skill.name, newEnabled);
    }

    setPendingChanges(newPendingChanges);
  };

  const handleReload = async () => {
    const token = getToken();
    if (!token || reloading) return;

    try {
      setReloading(true);
      setError(null);
      setSuccessMessage(null);

      // Apply all pending changes
      for (const [skillName, shouldEnable] of pendingChanges.entries()) {
        // Find the skill to check its category
        const skill = skills.find(s => s.name === skillName);

        if (shouldEnable) {
          await enableSkill(workspaceId, skillName, token);
        } else {
          // For custom skills, delete them; for others, disable them
          if (skill?.category === 'custom') {
            await deleteSkill(workspaceId, skillName, token);
          } else {
            await disableSkill(workspaceId, skillName, token);
          }
        }
      }

      // Trigger hot reload
      try {
        const result = await triggerHotReload(workspaceId, token);
        if (result.status === "error") {
          setError(result.message || t("skillHub.hotReloadFailed"));
        } else {
          setSuccessMessage(t("skillHub.applySuccess", { n: pendingChanges.size }));
          // Auto-hide success message after 3 seconds
          setTimeout(() => setSuccessMessage(null), 3000);
        }
      } catch (reloadErr) {
        console.log("Hot reload skipped (no active session)");
        setSuccessMessage(t("skillHub.applySkipped", { n: pendingChanges.size }));
        setTimeout(() => setSuccessMessage(null), 3000);
      }

      // Reload skills and trigger SourcesPanel refresh
      await loadSkills();
      triggerSkillsRefresh();
    } catch (err) {
      setError(err instanceof Error ? err.message : t("skillHub.operationFailed"));
    } finally {
      setReloading(false);
    }
  };

  const handleUploadClick = () => {
    fileInputRef.current?.click();
  };

  const handleFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (!file) return;

    const token = getToken();
    if (!token) {
      setUploadError(t("skillHub.notAuthenticated"));
      return;
    }

    try {
      setUploading(true);
      setUploadingFileName(file.name);
      setUploadError(null);
      setUploadSuccess(null);

      const result = await uploadSkill(workspaceId, file, token);
      setUploadSuccess(t("skillHub.uploadSuccess", { name: result.skill_name }));
      setTimeout(() => setUploadSuccess(null), 5000);

      // Reload skills list
      await loadSkills();
      triggerSkillsRefresh();
    } catch (err) {
      setUploadError(err instanceof Error ? err.message : t("skillHub.uploadFailed"));
      setTimeout(() => setUploadError(null), 8000);
    } finally {
      setUploading(false);
      setUploadingFileName(null);
      // Reset file input
      if (fileInputRef.current) {
        fileInputRef.current.value = "";
      }
    }
  };

  const getSkillEnabled = (skill: Skill): boolean => {
    return pendingChanges.has(skill.name)
      ? pendingChanges.get(skill.name)!
      : skill.enabled;
  };

  const hasChanges = pendingChanges.size > 0;

  // Group skills by category
  const skillsByCategory = skills.reduce((acc, skill) => {
    if (!acc[skill.category]) {
      acc[skill.category] = [];
    }
    acc[skill.category].push(skill);
    return acc;
  }, {} as Record<string, typeof skills>);

  // Ensure custom category always exists
  if (!skillsByCategory['custom']) {
    skillsByCategory['custom'] = [];
  }

  // Sort categories to put 'custom' first
  const sortedCategories = Object.entries(skillsByCategory).sort(([categoryA], [categoryB]) => {
    if (categoryA === 'custom') return -1;
    if (categoryB === 'custom') return 1;
    return 0;
  });

  if (loading) {
    return (
      <div className="flex items-center justify-center py-8">
        <div className="text-gray-500">{t("skillHub.loadingSkills")}</div>
      </div>
    );
  }

  return (
    <div className="space-y-5">
      {/* Header */}
      <div className="flex items-center justify-between pb-3 border-b border-gray-200">
        <div>
          <h3 className="text-xl font-semibold text-gray-900">{t("skillHub.title")}</h3>
          <p className="text-sm text-gray-500 mt-0.5">{t("skillHub.description")}</p>
        </div>
        <div className="flex items-center gap-3">
          <input
            ref={fileInputRef}
            type="file"
            accept=".zip"
            onChange={handleFileChange}
            style={{ display: "none" }}
          />
          <div className="relative group">
            <button
              onClick={handleUploadClick}
              disabled={uploading}
              style={{
                padding: '8px 16px',
                borderRadius: '8px',
                border: '1px solid #d1d5db',
                background: uploading ? '#f3f4f6' : '#fff',
                color: '#374151',
                fontSize: '13px',
                fontWeight: 600,
                cursor: uploading ? 'not-allowed' : 'pointer',
                display: 'flex',
                alignItems: 'center',
                gap: '8px',
                transition: 'all 0.2s',
              }}
              onMouseEnter={(e) => {
                if (!uploading) {
                  e.currentTarget.style.background = '#f9fafb';
                  e.currentTarget.style.borderColor = '#9ca3af';
                }
              }}
              onMouseLeave={(e) => {
                if (!uploading) {
                  e.currentTarget.style.background = '#fff';
                  e.currentTarget.style.borderColor = '#d1d5db';
                }
              }}
            >
              {uploading ? (
                <>
                  <svg style={{ animation: 'spin 1s linear infinite', height: '16px', width: '16px' }} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                    <circle style={{ opacity: 0.25 }} cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
                    <path style={{ opacity: 0.75 }} fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                  </svg>
                  <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>
                  {t("skillHub.uploading")}
                </>
              ) : (
                <>
                  <span style={{ fontSize: '16px' }}>+</span>
                  {t("skillHub.upload")}
                  <span style={{ fontSize: '12px' }}>{t("skillHub.uploadInfo")}</span>
                </>
              )}
            </button>
            <div className="absolute right-0 top-full mt-2 w-96 p-4 bg-gray-900 text-white text-xs rounded-lg shadow-xl opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-50 pointer-events-none group-hover:pointer-events-auto">
              <div className="font-semibold text-sm mb-3 flex items-center gap-2">
                <span className="text-base">📦</span>
                {t("skillHub.uploadCustomSkill")}
              </div>
              <div className="space-y-2 text-gray-300">
                <div className="flex items-start gap-2">
                  <span className="text-green-400 mt-0.5">•</span>
                  <span>{t("skillHub.uploadFormat")}</span>
                </div>
                <div className="flex items-start gap-2">
                  <span className="text-green-400 mt-0.5">•</span>
                  <span>{t("skillHub.uploadStructure")}</span>
                </div>
                <div className="mt-3 pt-3 border-t border-gray-700">
                  <div className="text-gray-400 mb-2">{t("skillHub.exampleStructureLabel")}</div>
                  <div className="ml-2 font-mono text-xs bg-gray-800 p-2 rounded">
                    my-skill.zip<br/>
                    └── my-skill/<br/>
                    &nbsp;&nbsp;&nbsp;&nbsp;├── SKILL.md<br/>
                    &nbsp;&nbsp;&nbsp;&nbsp;└── ... (other files)
                  </div>
                </div>
              </div>
            </div>
          </div>
          <button
            onClick={handleReload}
            disabled={!hasChanges || reloading}
            style={{
              padding: '8px 16px',
              borderRadius: '8px',
              border: 'none',
              background: (!hasChanges || reloading) ? '#d1d5db' : '#5c5fbc',
              color: '#fff',
              fontSize: '13px',
              fontWeight: 600,
              cursor: (!hasChanges || reloading) ? 'not-allowed' : 'pointer',
              display: 'flex',
              alignItems: 'center',
              gap: '8px',
              transition: 'all 0.2s',
            }}
            onMouseEnter={(e) => {
              if (hasChanges && !reloading) {
                e.currentTarget.style.background = '#4a4d9e';
              }
            }}
            onMouseLeave={(e) => {
              if (hasChanges && !reloading) {
                e.currentTarget.style.background = '#5c5fbc';
              }
            }}
          >
            {reloading ? (
              <>
                <svg style={{ animation: 'spin 1s linear infinite', height: '16px', width: '16px' }} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                  <circle style={{ opacity: 0.25 }} cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
                  <path style={{ opacity: 0.75 }} fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                </svg>
                <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>
                {t("skillHub.reloading")}
              </>
            ) : hasChanges ? (
              <>
                <span style={{
                  display: 'inline-flex',
                  alignItems: 'center',
                  justifyContent: 'center',
                  width: '20px',
                  height: '20px',
                  fontSize: '11px',
                  fontWeight: 700,
                  background: '#fff',
                  color: '#5c5fbc',
                  borderRadius: '50%',
                }}>
                  {pendingChanges.size}
                </span>
                {t("skillHub.applyAndReload")}
              </>
            ) : (
              t("skillHub.reload")
            )}
          </button>
        </div>
      </div>

      {uploading && uploadingFileName && (
        <div className="p-4 bg-blue-50 border-l-4 border-blue-400 rounded-r-lg">
          <div className="flex items-start">
            <svg className="animate-spin h-5 w-5 text-blue-600 mr-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
              <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
              <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
            </svg>
            <div className="flex-1">
              <p className="text-sm font-semibold text-blue-900">{t("skillHub.uploadingSkill")}</p>
              <p className="text-xs text-blue-700 mt-0.5 truncate">{uploadingFileName}</p>
            </div>
          </div>
        </div>
      )}

      {uploadSuccess && (
        <div className="p-4 bg-green-50 border-l-4 border-green-400 rounded-r-lg">
          <div className="flex items-start">
            <span className="text-green-400 text-lg mr-3">✓</span>
            <p className="text-sm text-green-700">{uploadSuccess}</p>
          </div>
        </div>
      )}

      {uploadError && (
        <div className="p-4 bg-red-50 border-l-4 border-red-400 rounded-r-lg">
          <div className="flex items-start">
            <span className="text-red-400 text-lg mr-3">⚠️</span>
            <div className="flex-1">
              <p className="text-sm font-semibold text-red-900">{t("skillHub.uploadFailed")}</p>
              <p className="text-xs text-red-700 mt-0.5">{uploadError}</p>
            </div>
          </div>
        </div>
      )}

      {error && (
        <div className="p-4 bg-red-50 border-l-4 border-red-400 rounded-r-lg">
          <div className="flex items-start">
            <span className="text-red-400 text-lg mr-3">⚠️</span>
            <p className="text-sm text-red-700">{error}</p>
          </div>
        </div>
      )}

      {successMessage && (
        <div className="p-4 bg-green-50 border-l-4 border-green-400 rounded-r-lg">
          <div className="flex items-start">
            <span className="text-green-400 text-lg mr-3">✓</span>
            <p className="text-sm text-green-700">{successMessage}</p>
          </div>
        </div>
      )}

      {skills.length === 0 ? (
        <div className="text-center py-8 text-gray-500">
          {t("skillHub.empty")}
        </div>
      ) : (
        <div className="space-y-6">
          {sortedCategories.map(([category, categorySkills]) => (
            <div key={category} className="bg-white rounded-lg border border-gray-200 p-4 shadow-sm">
              <div className="flex items-center justify-between mb-3">
                <h4 className="text-sm font-bold text-gray-800 uppercase tracking-wider flex items-center gap-2">
                  <span className="inline-block w-1 h-4 bg-blue-500 rounded"></span>
                  {category}
                </h4>
                <div className="flex items-center gap-3">
                  {category === 'nutshell-skills' && (
                    <a
                      href="https://github.com/tidbcloud/nutshell-skills"
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-xs text-blue-600 hover:text-blue-700 hover:underline flex items-center gap-1"
                    >
                      <span>{t("skillHub.submitPrs")}</span>
                      <span>→</span>
                    </a>
                  )}
                  {category === 'custom' && (
                    <span className="text-xs text-gray-500 flex items-center gap-1">
                      <span>🔒</span>
                      <span>{t("skillHub.workspaceLevelOnly")}</span>
                    </span>
                  )}
                </div>
              </div>
              <div className="grid grid-cols-2 gap-3">
                {categorySkills.map((skill) => {
                  const isEnabled = getSkillEnabled(skill);
                  const hasChange = pendingChanges.has(skill.name);

                  return (
                    <div
                      key={skill.path}
                      className={`relative p-3 border-2 rounded-lg transition-all duration-200 ${
                        hasChange
                          ? 'border-blue-400 bg-blue-50 shadow-md'
                          : isEnabled
                          ? 'border-green-200 bg-green-50 hover:border-green-300 hover:shadow-sm'
                          : 'border-gray-200 bg-white hover:border-gray-300 hover:shadow-sm'
                      }`}
                      title={skill.description || skill.name}
                    >
                      <label className="flex items-start gap-3 cursor-pointer">
                        <input
                          type="checkbox"
                          checked={isEnabled}
                          onChange={() => handleToggleSkill(skill)}
                          disabled={reloading}
                          className="mt-0.5 h-5 w-5 text-blue-600 rounded border-gray-300 focus:ring-2 focus:ring-blue-500 focus:ring-offset-0 disabled:opacity-50 cursor-pointer"
                        />
                        <div className="flex-1 min-w-0">
                          <div className="text-sm font-semibold text-gray-900 truncate flex items-center gap-1.5">
                            {skill.name}
                            {hasChange && (
                              <span className="inline-flex items-center px-1.5 py-0.5 text-xs font-bold text-blue-600 bg-blue-100 rounded">
                                {t("skillHub.pending")}
                              </span>
                            )}
                          </div>
                        </div>
                      </label>
                    </div>
                  );
                })}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}
