'use client';

import { useState, useEffect, useCallback } from 'react';
import { PageLayout } from '@/components/organisms/PageLayout';
import { PageHeader } from '@/components/organisms/PageHeader';
import { FolderTree, Plus, GripVertical, Pencil, Trash2, Loader2 } from 'lucide-react';
import { ReorderButtons } from '@/components/molecules';
import { ContentSkeleton } from '@/components/ui/skeleton';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Card, CardContent } from '@/components/ui/card';
import { CategoryDialog } from './CategoryDialog';
import { DeleteConfirmDialog } from '@/components/ui/confirm-dialog';
import { toast } from 'sonner';
import type { Category } from './types';
import { isNextRedirectError } from '@/lib/utils/redirect-error';
import {
  getCategories,
  createCategory,
  updateCategory,
  deleteCategory,
  reorderCategories,
} from './actions';

export function CategoryManagement() {
  // 카테고리 데이터
  const [categories, setCategories] = useState<Category[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [isSubmitting, setIsSubmitting] = useState(false);

  // 입력 필드
  const [newCategoryName, setNewCategoryName] = useState('');

  // 다이얼로그 상태
  const [dialogOpen, setDialogOpen] = useState(false);
  const [dialogMode, setDialogMode] = useState<'add' | 'edit'>('add');
  const [selectedCategory, setSelectedCategory] = useState<Category | undefined>();

  // 삭제 확인 다이얼로그
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [categoryToDelete, setCategoryToDelete] = useState<Category | null>(null);

  // 드래그 상태
  const [draggedItem, setDraggedItem] = useState<number | null>(null);

  // 데이터 로드
  const loadCategories = useCallback(async () => {
    try {
      setIsLoading(true);
      const result = await getCategories();
      if (result.success && result.data) {
        setCategories(result.data);
      } else {
        toast.error(result.error || '카테고리 목록을 불러오는데 실패했습니다.');
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('카테고리 목록 조회 실패:', error);
      toast.error('카테고리 목록을 불러오는데 실패했습니다.');
    } finally {
      setIsLoading(false);
    }
  }, []);

  // 초기 데이터 로드
  useEffect(() => {
    loadCategories();
  }, [loadCategories]);

  // 카테고리 추가 (입력 필드에서 직접)
  const handleQuickAdd = async () => {
    if (!newCategoryName.trim() || isSubmitting) return;

    try {
      setIsSubmitting(true);
      const result = await createCategory({ name: newCategoryName.trim() });
      if (result.success && result.data) {
        setCategories(prev => [...prev, result.data!]);
        setNewCategoryName('');
        toast.success('카테고리가 추가되었습니다.');
      } else {
        toast.error(result.error || '카테고리 추가에 실패했습니다.');
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('카테고리 추가 실패:', error);
      toast.error('카테고리 추가에 실패했습니다.');
    } finally {
      setIsSubmitting(false);
    }
  };

  // 카테고리 수정 다이얼로그 열기
  const handleEdit = (category: Category) => {
    setSelectedCategory(category);
    setDialogMode('edit');
    setDialogOpen(true);
  };

  // 카테고리 삭제 확인
  const handleDelete = (category: Category) => {
    setCategoryToDelete(category);
    setDeleteDialogOpen(true);
  };

  // 삭제 실행
  const confirmDelete = async () => {
    if (!categoryToDelete || isSubmitting) return;

    try {
      setIsSubmitting(true);
      const result = await deleteCategory(categoryToDelete.id);
      if (result.success) {
        setCategories(prev => prev.filter(c => c.id !== categoryToDelete.id));
        toast.success('카테고리가 삭제되었습니다.');
      } else {
        // 삭제 실패 유형에 따른 메시지
        toast.error(result.error || '카테고리 삭제에 실패했습니다.');
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('카테고리 삭제 실패:', error);
      toast.error('카테고리 삭제에 실패했습니다.');
    } finally {
      setIsSubmitting(false);
      setDeleteDialogOpen(false);
      setCategoryToDelete(null);
    }
  };

  // 다이얼로그 제출
  const handleDialogSubmit = async (name: string) => {
    if (dialogMode === 'edit' && selectedCategory) {
      try {
        setIsSubmitting(true);
        const result = await updateCategory(selectedCategory.id, { name });
        if (result.success) {
          setCategories(prev => prev.map(c =>
            c.id === selectedCategory.id ? { ...c, name } : c
          ));
          toast.success('카테고리가 수정되었습니다.');
        } else {
          toast.error(result.error || '카테고리 수정에 실패했습니다.');
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        console.error('카테고리 수정 실패:', error);
        toast.error('카테고리 수정에 실패했습니다.');
      } finally {
        setIsSubmitting(false);
      }
    }
    setDialogOpen(false);
  };

  // 드래그 시작
  const handleDragStart = (e: React.DragEvent, index: number) => {
    setDraggedItem(index);
    e.dataTransfer.effectAllowed = 'move';
  };

  // 드래그 종료 - 서버에 순서 저장
  const handleDragEnd = async () => {
    if (draggedItem === null) return;

    setDraggedItem(null);

    // 순서 변경 API 호출
    try {
      const items = categories.map((category, idx) => ({
        id: category.id,
        sort_order: idx + 1,
      }));
      const result = await reorderCategories(items);
      if (result.success) {
        toast.success('순서가 변경되었습니다.');
      } else {
        toast.error(result.error || '순서 변경에 실패했습니다.');
        loadCategories();
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('순서 변경 실패:', error);
      toast.error('순서 변경에 실패했습니다.');
      // 실패시 원래 순서로 복구
      loadCategories();
    }
  };

  // 드래그 오버
  const handleDragOver = (e: React.DragEvent, index: number) => {
    e.preventDefault();
    if (draggedItem === null || draggedItem === index) return;

    const newCategories = [...categories];
    const draggedCategory = newCategories[draggedItem];
    newCategories.splice(draggedItem, 1);
    newCategories.splice(index, 0, draggedCategory);

    // 순서 업데이트 (로컬)
    const reorderedCategories = newCategories.map((category, idx) => ({
      ...category,
      order: idx + 1
    }));

    setCategories(reorderedCategories);
    setDraggedItem(index);
  };

  // 화살표 버튼으로 순서 변경
  const handleMoveItem = async (fromIndex: number, toIndex: number) => {
    const newCategories = [...categories];
    const [moved] = newCategories.splice(fromIndex, 1);
    newCategories.splice(toIndex, 0, moved);
    const reordered = newCategories.map((category, idx) => ({ ...category, order: idx + 1 }));
    setCategories(reordered);

    try {
      const items = reordered.map((category, idx) => ({
        id: category.id,
        sort_order: idx + 1,
      }));
      const result = await reorderCategories(items);
      if (result.success) {
        toast.success('순서가 변경되었습니다.');
      } else {
        toast.error(result.error || '순서 변경에 실패했습니다.');
        loadCategories();
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      toast.error('순서 변경에 실패했습니다.');
      loadCategories();
    }
  };

  // 키보드로 추가 (한글 IME 조합 중에는 무시)
  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.nativeEvent.isComposing) {
      handleQuickAdd();
    }
  };

  return (
    <PageLayout>
      <PageHeader
        title="카테고리관리"
        description="카테고리를 등록하고 관리합니다. 화살표 버튼 또는 드래그하여 순서를 변경할 수 있습니다."
        icon={FolderTree}
      />

      <div className="space-y-4">
        {/* 카테고리 추가 입력 영역 */}
        <Card>
          <CardContent className="p-4">
            <div className="flex gap-2">
              <Input
                value={newCategoryName}
                onChange={(e) => setNewCategoryName(e.target.value)}
                onKeyDown={handleKeyDown}
                placeholder="카테고리를 입력해주세요"
                className="flex-1"
                disabled={isSubmitting}
              />
              <Button
                onClick={handleQuickAdd}
                disabled={!newCategoryName.trim() || isSubmitting}
              >
                {isSubmitting ? (
                  <Loader2 className="h-4 w-4 mr-2 animate-spin" />
                ) : (
                  <Plus className="h-4 w-4 mr-2" />
                )}
                추가
              </Button>
            </div>
          </CardContent>
        </Card>

        {/* 카테고리 목록 */}
        <Card>
          <CardContent className="p-0">
            {isLoading ? (
              <ContentSkeleton type="list" rows={5} />
            ) : (
              <div className="divide-y">
                {categories.map((category, index) => (
                  <div
                    key={category.id}
                    draggable
                    onDragStart={(e) => handleDragStart(e, index)}
                    onDragEnd={handleDragEnd}
                    onDragOver={(e) => handleDragOver(e, index)}
                    className={`flex items-center gap-3 px-4 py-3 hover:bg-muted/50 transition-colors cursor-move ${
                      draggedItem === index ? 'opacity-50 bg-muted' : ''
                    }`}
                  >
                    {/* 드래그 핸들 (PC만) */}
                    <GripVertical className="h-5 w-5 text-muted-foreground flex-shrink-0 hidden md:block" />

                    {/* 순서 변경 버튼 */}
                    <ReorderButtons
                      onMoveUp={() => handleMoveItem(index, index - 1)}
                      onMoveDown={() => handleMoveItem(index, index + 1)}
                      isFirst={index === 0}
                      isLast={index === categories.length - 1}
                      disabled={isSubmitting}
                      size="xs"
                    />

                    {/* 순서 번호 */}
                    <span className="text-sm text-muted-foreground w-8">
                      {index + 1}
                    </span>

                    {/* 카테고리명 */}
                    <span className="flex-1 font-medium">{category.name}</span>

                    {/* 액션 버튼 */}
                    <div className="flex gap-1">
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => handleEdit(category)}
                        className="h-8 w-8 p-0"
                        disabled={isSubmitting}
                      >
                        <Pencil className="h-4 w-4" />
                        <span className="sr-only">수정</span>
                      </Button>
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => handleDelete(category)}
                        className="h-8 w-8 p-0 text-destructive hover:text-destructive"
                        disabled={isSubmitting}
                      >
                        <Trash2 className="h-4 w-4" />
                        <span className="sr-only">삭제</span>
                      </Button>
                    </div>
                  </div>
                ))}

                {categories.length === 0 && (
                  <div className="px-4 py-8 text-center text-muted-foreground">
                    등록된 카테고리가 없습니다.
                  </div>
                )}
              </div>
            )}
          </CardContent>
        </Card>

        {/* 안내 문구 */}
        <p className="text-sm text-muted-foreground">
          ※ 화살표 버튼으로 순서를 변경할 수 있습니다.
        </p>
      </div>

      {/* 수정 다이얼로그 */}
      <CategoryDialog
        isOpen={dialogOpen}
        onOpenChange={setDialogOpen}
        mode={dialogMode}
        category={selectedCategory}
        onSubmit={handleDialogSubmit}
        isLoading={isSubmitting}
      />

      {/* 삭제 확인 다이얼로그 */}
      <DeleteConfirmDialog
        open={deleteDialogOpen}
        onOpenChange={setDeleteDialogOpen}
        onConfirm={confirmDelete}
        title="카테고리 삭제"
        description={
          <>
            &quot;{categoryToDelete?.name}&quot; 카테고리를 삭제하시겠습니까?
            {categoryToDelete?.isDefault && (
              <>
                <br />
                <span className="text-destructive font-medium">
                  기본 카테고리는 삭제가 불가합니다.
                </span>
              </>
            )}
          </>
        }
        loading={isSubmitting}
        confirmDisabled={categoryToDelete?.isDefault}
      />
    </PageLayout>
  );
}
