import { useCallback, useEffect, useRef, useState } from 'react';
import Editor from '@monaco-editor/react';
import { ArrowLeft, FileCode, FolderOpen, Lock, Pencil, Save, Trash2 } from 'lucide-react';
import { ListPanel, ListItem } from '@/components/shared/ListPanel';
import { ItemCard, ItemCardBadge } from '@/components/shared/ItemCard';
import { EditorPanelEmptyState } from '@/components/shared';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { useToast } from '@/components/ui/use-toast';
import { useTheme } from '@/contexts/ThemeContext';
import { useSwipeBack } from '@/hooks/useSwipeBack';
import {
  createSkill,
  deleteSkill,
  getSkill,
  listSkills,
  updateSkill,
} from '@/services/skillsService';
import { SkillSummary } from '@/types/skills';

interface SkillListItem extends ListItem {
  description: string;
  origin: SkillSummary['origin'];
  can_edit: boolean;
}

export function Skills() {
  const { toast } = useToast();
  const toastRef = useRef(toast);
  toastRef.current = toast;

  const { resolvedTheme } = useTheme();
  const [skills, setSkills] = useState<SkillSummary[]>([]);
  const [selectedName, setSelectedName] = useState<string | null>(null);
  const [draftContent, setDraftContent] = useState('');
  const [originalContent, setOriginalContent] = useState('');
  const [loadingList, setLoadingList] = useState(true);
  const [loadingDetail, setLoadingDetail] = useState(false);
  const [saving, setSaving] = useState(false);

  const selectedSkill = selectedName ? skills.find(s => s.name === selectedName) ?? null : null;
  const isDirty = draftContent !== originalContent;

  useSwipeBack({
    onSwipeBack: () => setSelectedName(null),
    enabled: !!selectedSkill && window.innerWidth < 1024,
  });

  const refreshSkills = useCallback(async () => {
    setLoadingList(true);
    try {
      const data = await listSkills();
      setSkills(data);
      setSelectedName(current => (current && data.some(s => s.name === current) ? current : null));
    } catch (error) {
      toastRef.current({
        title: 'Failed to load skills',
        description: error instanceof Error ? error.message : 'Unknown error',
        variant: 'destructive',
      });
    } finally {
      setLoadingList(false);
    }
  }, []);

  useEffect(() => {
    refreshSkills();
  }, [refreshSkills]);

  useEffect(() => {
    let isActive = true;

    if (!selectedName) {
      setDraftContent('');
      setOriginalContent('');
      return;
    }

    setLoadingDetail(true);
    getSkill(selectedName)
      .then(detail => {
        if (!isActive) return;
        setDraftContent(detail.content);
        setOriginalContent(detail.content);
      })
      .catch(error => {
        if (!isActive) return;
        toastRef.current({
          title: 'Failed to load skill',
          description: error instanceof Error ? error.message : 'Unknown error',
          variant: 'destructive',
        });
      })
      .finally(() => {
        setLoadingDetail(false);
      });

    return () => {
      isActive = false;
    };
  }, [selectedName]);

  const handleSelect = (name: string) => {
    if (isDirty && selectedName !== name) {
      if (!window.confirm('Discard unsaved changes?')) return;
    }
    setSelectedName(name);
  };

  const handleSave = async () => {
    if (!selectedSkill) return;
    setSaving(true);
    try {
      await updateSkill(selectedSkill.name, draftContent);
      setOriginalContent(draftContent);
      toast({ title: 'Skill saved', description: `${selectedSkill.name} updated.` });
      await refreshSkills();
    } catch (error) {
      toast({
        title: 'Failed to save skill',
        description: error instanceof Error ? error.message : 'Unknown error',
        variant: 'destructive',
      });
    } finally {
      setSaving(false);
    }
  };

  const handleCreate = async (name?: string): Promise<boolean> => {
    if (!name) return false;
    const trimmed = name.trim().toLowerCase();
    if (!/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(trimmed)) {
      toast({
        title: 'Invalid skill name',
        description:
          'Name must be alphanumeric with optional hyphens, starting and ending with a letter or digit.',
        variant: 'destructive',
      });
      return false;
    }
    try {
      await createSkill(trimmed, trimmed);
      toast({ title: 'Skill created', description: `${trimmed} is ready to edit.` });
      await refreshSkills();
      setSelectedName(trimmed);
      return true;
    } catch (error) {
      toast({
        title: 'Failed to create skill',
        description: error instanceof Error ? error.message : 'Unknown error',
        variant: 'destructive',
      });
      return false;
    }
  };

  const handleDelete = async () => {
    if (!selectedSkill) return;
    if (!window.confirm(`Delete skill "${selectedSkill.name}"? This cannot be undone.`)) return;
    try {
      await deleteSkill(selectedSkill.name);
      toast({ title: 'Skill deleted', description: `${selectedSkill.name} removed.` });
      setSelectedName(null);
      await refreshSkills();
    } catch (error) {
      toast({
        title: 'Failed to delete skill',
        description: error instanceof Error ? error.message : 'Unknown error',
        variant: 'destructive',
      });
    }
  };

  const listItems: SkillListItem[] = skills.map(s => ({
    id: s.name,
    display_name: s.name,
    description: s.description,
    origin: s.origin,
    can_edit: s.can_edit,
  }));

  const renderSkill = (skill: SkillListItem, isSelected: boolean) => {
    const badges: ItemCardBadge[] = [
      { content: skill.origin, variant: 'secondary' as const, icon: FolderOpen },
      {
        content: skill.can_edit ? 'Editable' : 'Read-only',
        variant: skill.can_edit ? ('default' as const) : ('outline' as const),
        icon: skill.can_edit ? Pencil : Lock,
      },
    ];

    return (
      <ItemCard
        id={skill.id}
        title={skill.display_name}
        description={skill.description}
        isSelected={isSelected}
        onClick={handleSelect}
        badges={badges}
      />
    );
  };

  return (
    <div className="grid grid-cols-1 lg:grid-cols-12 gap-3 sm:gap-4 h-full">
      <div
        className={`col-span-1 lg:col-span-4 h-full overflow-hidden ${
          selectedSkill ? 'hidden lg:block' : 'block'
        }`}
      >
        <ListPanel<SkillListItem>
          title="Skills"
          icon={FileCode}
          items={listItems}
          selectedId={selectedName || undefined}
          onItemSelect={handleSelect}
          renderItem={renderSkill}
          showSearch={true}
          searchPlaceholder="Search skills..."
          showCreateButton={true}
          creationMode="inline-form"
          createPlaceholder="Skill name..."
          createButtonText="New"
          onCreateItem={handleCreate}
          emptyIcon={FileCode}
          emptyMessage={loadingList ? 'Loading skills...' : 'No skills found'}
          emptySubtitle={
            loadingList
              ? 'Fetching skill list from the server'
              : 'Add skills under ~/.mindroom/skills to get started'
          }
        />
      </div>
      <div
        className={`col-span-1 lg:col-span-8 h-full overflow-hidden ${
          selectedSkill ? 'block' : 'hidden lg:block'
        }`}
      >
        {!selectedSkill ? (
          <EditorPanelEmptyState icon={FileCode} message="Select a skill to view" />
        ) : (
          <Card className="h-full flex flex-col overflow-hidden">
            <CardHeader className="pb-3 flex-shrink-0">
              <div className="flex items-start justify-between gap-4">
                <div className="flex items-start gap-2">
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => setSelectedName(null)}
                    className="lg:hidden -ml-2 mt-1"
                  >
                    <ArrowLeft className="h-4 w-4" />
                  </Button>
                  <div>
                    <CardTitle className="flex items-center gap-2">
                      <FileCode className="h-5 w-5" />
                      {selectedSkill.name}
                    </CardTitle>
                    <p className="text-sm text-muted-foreground mt-1">
                      {selectedSkill.description}
                    </p>
                  </div>
                </div>
                {selectedSkill.can_edit && (
                  <div className="flex items-center gap-1">
                    <Button
                      variant="default"
                      size="sm"
                      onClick={handleSave}
                      disabled={!isDirty || saving}
                    >
                      <Save className="h-4 w-4 sm:mr-1" />
                      <span className="hidden sm:inline">{saving ? 'Saving...' : 'Save'}</span>
                    </Button>
                    <Button variant="ghost" size="sm" onClick={handleDelete}>
                      <Trash2 className="h-4 w-4 text-destructive" />
                    </Button>
                  </div>
                )}
              </div>
              <div className="flex flex-wrap items-center gap-2 mt-3">
                <Badge variant="secondary">{selectedSkill.origin}</Badge>
                {!selectedSkill.can_edit && <Badge variant="outline">Read-only</Badge>}
              </div>
            </CardHeader>
            <CardContent className="flex-1 min-h-0 p-0">
              {loadingDetail ? (
                <div className="h-full flex items-center justify-center text-sm text-muted-foreground">
                  Loading skill contents...
                </div>
              ) : (
                <Editor
                  height="100%"
                  language="markdown"
                  theme={resolvedTheme === 'dark' ? 'vs-dark' : 'vs'}
                  value={draftContent}
                  onChange={value => setDraftContent(value ?? '')}
                  loading={
                    <div className="h-full flex items-center justify-center text-sm text-muted-foreground">
                      Loading editor...
                    </div>
                  }
                  options={{
                    readOnly: !selectedSkill.can_edit,
                    minimap: { enabled: false },
                    fontSize: 13,
                    scrollBeyondLastLine: false,
                    wordWrap: 'on',
                    padding: { top: 12, bottom: 12 },
                  }}
                />
              )}
            </CardContent>
          </Card>
        )}
      </div>
    </div>
  );
}
