'use client';

import { useState, useMemo, useCallback, useEffect, useRef } from 'react';
import { useRouter } from 'next/navigation';
import { format } from 'date-fns';
import {
  Shield,
  Plus,
  Pencil,
  Trash2,
  Settings,
  Eye,
  EyeOff,
   Users,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Badge } from '@/components/ui/badge';
import { TableRow, TableCell } from '@/components/ui/table';
import {
  UniversalListPage,
  type UniversalListConfig,
  type TableColumn,
  type StatCard,
  type TabOption,
  type SelectionHandlers,
  type RowClickHandlers,
} from '@/components/templates/UniversalListPage';
import { ListMobileCard, InfoField } from '@/components/organisms/MobileCard';
import { DeleteConfirmDialog } from '@/components/ui/confirm-dialog';
import { toast } from 'sonner';
import type { Role, RoleStats } from './types';
import { fetchRoles, fetchRoleStats, deleteRole } from './actions';

export function PermissionManagement() {
  const router = useRouter();

  // ===== 상태 관리 =====
  const [searchQuery, setSearchQuery] = useState('');
  const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set());

  // 역할 데이터
  const [roles, setRoles] = useState<Role[]>([]);
  const [stats, setStats] = useState<RoleStats | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const isInitialLoadDone = useRef(false);
  const [error, setError] = useState<string | null>(null);

  // 삭제 확인 다이얼로그
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [roleToDelete, setRoleToDelete] = useState<Role | null>(null);
  const [isBulkDelete, setIsBulkDelete] = useState(false);
  const [isDeleting, setIsDeleting] = useState(false);

  // API에서 데이터 로드
  const loadData = useCallback(async () => {
    if (!isInitialLoadDone.current) {
      setIsLoading(true);
    }
    setError(null);

    try {
      const [rolesResult, statsResult] = await Promise.all([
        fetchRoles({ size: 1000 }), // 전체 로드 후 클라이언트 필터링
        fetchRoleStats(),
      ]);

      if (rolesResult.success && rolesResult.data) {
        setRoles(rolesResult.data.data);
      } else {
        setError(rolesResult.error || '역할 목록 조회 실패');
      }

      if (statsResult.success && statsResult.data) {
        setStats(statsResult.data);
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : '데이터 로드 실패');
    } finally {
      setIsLoading(false);
      isInitialLoadDone.current = true;
    }
  }, []);

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

  // ===== 탭 상태 =====
  const [activeTab, setActiveTab] = useState('all');

  // ===== 체크박스 핸들러 =====
  const toggleSelection = useCallback((id: string) => {
    setSelectedItems(prev => {
      const newSet = new Set(prev);
      if (newSet.has(id)) newSet.delete(id);
      else newSet.add(id);
      return newSet;
    });
  }, []);

  const _toggleSelectAll = useCallback(() => {
    if (selectedItems.size === filteredData.length && filteredData.length > 0) {
      setSelectedItems(new Set());
    } else {
      setSelectedItems(new Set(filteredData.map(item => item.id.toString())));
    }
  }, [selectedItems.size]);

  // ===== 필터링된 데이터 =====
  const filteredData = useMemo(() => {
    let result = roles;

    // 탭 필터
    if (activeTab === 'visible') {
      result = result.filter(item => !item.is_hidden);
    } else if (activeTab === 'hidden') {
      result = result.filter(item => item.is_hidden);
    }

    // 검색 필터
    if (searchQuery) {
      result = result.filter(item =>
        item.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
        (item.description?.toLowerCase().includes(searchQuery.toLowerCase()))
      );
    }

    return result;
  }, [roles, searchQuery, activeTab]);

  // ===== 핸들러 =====
  const handleAdd = () => {
    router.push('/settings/permissions?mode=new');
  };

  const handleEdit = (role: Role, e?: React.MouseEvent) => {
    e?.stopPropagation();
    router.push(`/settings/permissions/${role.id}?mode=edit`);
  };

  const handleViewDetail = (role: Role) => {
    router.push(`/settings/permissions/${role.id}?mode=view`);
  };

  const handleDelete = (role: Role, e?: React.MouseEvent) => {
    e?.stopPropagation();
    setRoleToDelete(role);
    setIsBulkDelete(false);
    setDeleteDialogOpen(true);
  };

  const handleBulkDelete = () => {
    if (selectedItems.size === 0) return;
    setIsBulkDelete(true);
    setDeleteDialogOpen(true);
  };

  const confirmDelete = async () => {
    setIsDeleting(true);

    try {
      if (isBulkDelete) {
        // 일괄 삭제
        const deletePromises = Array.from(selectedItems).map(id => deleteRole(parseInt(id)));
        const results = await Promise.all(deletePromises);
        const failedCount = results.filter(r => !r.success).length;

        if (failedCount > 0) {
          toast.error(`${failedCount}개 역할 삭제 실패`);
        } else {
          toast.success(`${selectedItems.size}개 역할 삭제 완료`);
        }
        setSelectedItems(new Set());
      } else if (roleToDelete) {
        // 단일 삭제
        const result = await deleteRole(roleToDelete.id);
        if (result.success) {
          toast.success(`"${roleToDelete.name}" 역할 삭제 완료`);
        } else {
          toast.error(result.error || '역할 삭제 실패');
        }
      }

      // 데이터 새로고침
      await loadData();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : '삭제 중 오류 발생');
    } finally {
      setIsDeleting(false);
      setDeleteDialogOpen(false);
      setRoleToDelete(null);
    }
  };

  // ===== 날짜 포맷 =====
  const formatDate = (dateStr: string) => {
    return format(new Date(dateStr), 'yyyy-MM-dd');
  };

  // ===== 탭 설정 =====
  const tabs: TabOption[] = useMemo(() => {
    const visibleCount = roles.filter(r => !r.is_hidden).length;
    const hiddenCount = roles.filter(r => r.is_hidden).length;

    return [
      { value: 'all', label: '전체', count: roles.length, color: 'blue' },
      { value: 'visible', label: '공개', count: visibleCount, color: 'green' },
      { value: 'hidden', label: '숨김', count: hiddenCount, color: 'gray' },
    ];
  }, [roles]);

  // ===== 통계 카드 =====
  const statCards: StatCard[] = useMemo(() => {
    return [
      {
        label: '전체 역할',
        value: stats?.total_roles ?? roles.length,
        icon: Shield,
        iconColor: 'text-blue-500',
      },
      {
        label: '공개',
        value: stats?.visible_roles ?? roles.filter(r => !r.is_hidden).length,
        icon: Eye,
        iconColor: 'text-green-500',
      },
      {
        label: '숨김',
        value: stats?.hidden_roles ?? roles.filter(r => r.is_hidden).length,
        icon: EyeOff,
        iconColor: 'text-gray-500',
      },
      {
        label: '사용 중',
        value: stats?.roles_with_users ?? 0,
        icon: Users,
        iconColor: 'text-purple-500',
      },
    ];
  }, [roles, stats]);

  // ===== 테이블 컬럼 =====
  const tableColumns: TableColumn[] = useMemo(() => {
    const baseColumns: TableColumn[] = [
      { key: 'index', label: '번호', className: 'text-center w-[80px]' },
      { key: 'name', label: '역할', className: 'flex-1', copyable: true },
      { key: 'description', label: '설명', className: 'flex-1', copyable: true },
      { key: 'status', label: '상태', className: 'text-center w-[100px]' },
      { key: 'createdAt', label: '등록일', className: 'text-center w-[120px]', copyable: true },
    ];

    if (selectedItems.size > 0) {
      baseColumns.push({ key: 'action', label: '작업', className: 'text-center w-[150px]' });
    }

    return baseColumns;
  }, [selectedItems.size]);

  // ===== 테이블 행 렌더링 =====
  const renderTableRow = useCallback((
    item: Role,
    index: number,
    globalIndex: number,
    handlers: SelectionHandlers & RowClickHandlers<Role>
  ) => {
    const { isSelected, onToggle } = handlers;
    const hasSelection = selectedItems.size > 0;

    return (
      <TableRow
        key={item.id}
        className="hover:bg-muted/50 cursor-pointer"
        onClick={() => handleViewDetail(item)}
      >
        <TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
          <Checkbox
            checked={isSelected}
            onCheckedChange={onToggle}
          />
        </TableCell>
        <TableCell className="text-center text-muted-foreground">
          {globalIndex}
        </TableCell>
        <TableCell className="font-medium">{item.name}</TableCell>
        <TableCell className="text-muted-foreground">{item.description || '-'}</TableCell>
        <TableCell className="text-center">
          <Badge variant={item.is_hidden ? 'secondary' : 'default'}>
            {item.is_hidden ? '숨김' : '공개'}
          </Badge>
        </TableCell>
        <TableCell className="text-center">{formatDate(item.created_at)}</TableCell>
        {hasSelection && (
          <TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
            <div className="flex justify-center gap-1">
              <Button
                variant="ghost"
                size="sm"
                onClick={() => handleViewDetail(item)}
                className="h-8 w-8 p-0"
                title="권한 설정"
              >
                <Settings className="h-4 w-4" />
              </Button>
              <Button
                variant="ghost"
                size="sm"
                onClick={(e) => handleEdit(item, e)}
                className="h-8 w-8 p-0"
                title="수정"
              >
                <Pencil className="h-4 w-4" />
              </Button>
              <Button
                variant="ghost"
                size="sm"
                onClick={(e) => handleDelete(item, e)}
                className="h-8 w-8 p-0 text-destructive hover:text-destructive"
                title="삭제"
              >
                <Trash2 className="h-4 w-4" />
              </Button>
            </div>
          </TableCell>
        )}
      </TableRow>
    );
  }, [selectedItems, toggleSelection]);

  // ===== 모바일 카드 렌더링 =====
  const renderMobileCard = useCallback((
    item: Role,
    index: number,
    globalIndex: number,
    handlers: SelectionHandlers & RowClickHandlers<Role>
  ) => {
    const { isSelected, onToggle } = handlers;
    return (
      <ListMobileCard
        id={item.id.toString()}
        title={item.name}
        headerBadges={
          <Badge variant={item.is_hidden ? 'secondary' : 'default'}>
            {item.is_hidden ? '숨김' : '공개'}
          </Badge>
        }
        isSelected={isSelected}
        onToggleSelection={onToggle}
        infoGrid={
          <div className="grid grid-cols-1 gap-3">
            <InfoField label="설명" value={item.description || '-'} />
            <InfoField label="등록일" value={formatDate(item.created_at)} />
          </div>
        }
        actions={
          <Button
            variant="outline"
            size="sm"
            className="w-full"
            onClick={() => handleViewDetail(item)}
          >
            <Settings className="h-4 w-4 mr-2" />
            권한 설정
          </Button>
        }
      />
    );
  }, []);

  // ===== 헤더 액션 =====
  const renderHeaderActions = useCallback(({ selectedItems: selItems }: {
    onCreate?: () => void;
    selectedItems: Set<string>;
    onClearSelection: () => void;
    onRefresh: () => void;
  }) => (
    <div className="flex items-center gap-2 flex-wrap ml-auto">
      {selItems.size > 0 && (
        <Button variant="destructive" size="sm" className="md:size-default" onClick={handleBulkDelete}>
          <Trash2 className="h-4 w-4 md:mr-2" />
          <span className="hidden md:inline">선택 삭제 ({selItems.size})</span>
        </Button>
      )}
      <Button size="sm" className="md:size-default" onClick={handleAdd}>
        <Plus className="h-4 w-4 md:mr-2" />
        <span className="hidden md:inline">역할 등록</span>
      </Button>
    </div>
  ), [handleBulkDelete, handleAdd]);

  // ===== 에러 상태 =====
  if (error) {
    return (
      <div className="flex flex-col items-center justify-center h-96 gap-4">
        <p className="text-destructive">{error}</p>
        <Button onClick={loadData}>다시 시도</Button>
      </div>
    );
  }

  // ===== UniversalListPage 설정 =====
  const permissionConfig: UniversalListConfig<Role> = {
    title: '권한관리',
    description: '역할 기반 권한을 관리합니다',
    icon: Shield,
    basePath: '/settings/permissions',

    idField: 'id',

    actions: {
      getList: async () => ({
        success: true,
        data: roles,
        totalCount: roles.length,
      }),
    },

    columns: tableColumns,

    tabs: tabs,
    defaultTab: activeTab,

    stats: statCards,

    searchPlaceholder: '역할명, 설명 검색...',

    itemsPerPage: 20,

    clientSideFiltering: true,

    searchFilter: (item, searchValue) => {
      return (
        item.name.toLowerCase().includes(searchValue.toLowerCase()) ||
        (item.description?.toLowerCase().includes(searchValue.toLowerCase()) ?? false)
      );
    },

    tabFilter: (item, tabValue) => {
      if (tabValue === 'all') return true;
      if (tabValue === 'visible') return !item.is_hidden;
      if (tabValue === 'hidden') return item.is_hidden;
      return true;
    },

    headerActions: renderHeaderActions,

    renderTableRow,
    renderMobileCard,

    renderDialogs: () => (
      <DeleteConfirmDialog
        open={deleteDialogOpen}
        onOpenChange={setDeleteDialogOpen}
        onConfirm={confirmDelete}
        title="역할 삭제"
        description={
          <>
            {isBulkDelete
              ? `선택한 ${selectedItems.size}개의 역할을 삭제하시겠습니까?`
              : `"${roleToDelete?.name}" 역할을 삭제하시겠습니까?`
            }
            <br />
            <span className="text-destructive">
              이 역할을 사용 중인 사원이 있으면 해당 사원의 역할이 초기화됩니다.
            </span>
          </>
        }
        loading={isDeleting}
      />
    ),
  };

  // ===== 목록 화면 =====
  return (
    <UniversalListPage<Role>
      config={permissionConfig}
      initialData={roles}
      initialTotalCount={roles.length}
      externalSelection={{
        selectedItems,
        onToggleSelection: (id: string) => {
          setSelectedItems(prev => {
            const newSet = new Set(prev);
            if (newSet.has(id)) {
              newSet.delete(id);
            } else {
              newSet.add(id);
            }
            return newSet;
          });
        },
        onToggleSelectAll: () => {
          setSelectedItems(prev => {
            if (prev.size > 0) {
              return new Set();
            }
            return new Set(roles.map(r => String(r.id)));
          });
        },
        getItemId: (item: Role) => String(item.id),
      }}
      onTabChange={setActiveTab}
      onSearchChange={setSearchQuery}
      externalIsLoading={isLoading}
    />
  );
}