// app/components/admin/roles/RolesTable.tsx
'use client';

import { useState, useEffect, useCallback } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import toast from 'react-hot-toast';
import { usePermissions } from '@/hooks/usePermissions';
import { PERMISSIONS } from '@/lib/permissions';
import { useAlert } from '@/contexts/AlertContext';
import DataTable from '@/app/components/admin/CommonComponents/DataTable';
import TablePagination from '@/app/components/admin/CommonComponents/TablePagination';
import TableFilters from '@/app/components/admin/CommonComponents/TableFilters';
import { BaseTableItem, FilterConfig, FilterValues, PaginationData, TableColumn, TableAction } from '@/types/admin-table';

interface Role extends BaseTableItem {
  id: string;
  name: string;
  description: string;
  permissions_count: number;
  users_count: number;
  created_at: string;
}

interface RolesTableProps {
  initialData?: {
    roles: Role[];
    pagination: PaginationData;
  };
}

export default function RolesTable({ initialData }: RolesTableProps) {
  const router = useRouter();
  const [roles, setRoles] = useState<Role[]>(initialData?.roles || []);
  const [loading, setLoading] = useState(false);
  const [showFilters, setShowFilters] = useState(false); // Filter toggle state
  const [pagination, setPagination] = useState<PaginationData>(
    initialData?.pagination || { page: 1, limit: 10, total: 0, pages: 0 }
  );
  const [filters, setFilters] = useState<FilterValues>({
    search: '',
  });

  const { hasPermission } = usePermissions();
  const { showAlert } = useAlert();

  // Check permissions for different actions
  const canCreateRole = hasPermission(PERMISSIONS.ROLES_CREATE);
  const canEditRole = hasPermission(PERMISSIONS.ROLES_UPDATE);
  const canDeleteRole = hasPermission(PERMISSIONS.ROLES_DELETE);
  const canBulkDelete = hasPermission(PERMISSIONS.ROLES_BULK_DELETE);

  // Filter configuration
  const filterConfigs: FilterConfig[] = [
    {
      key: 'search',
      label: 'Search Roles',
      type: 'search',
      placeholder: 'Search by role name...'
    }
  ];

  // Fetch roles with filters and pagination
  const fetchRoles = useCallback(async (page = 1, newFilters = filters) => {
    setLoading(true);
    try {
      const params = new URLSearchParams({
        page: page.toString(),
        limit: pagination.limit.toString(),
        ...newFilters
      });

      const response = await fetch(`/api/backend/admin/roles?${params}`);
      const data = await response.json();

      if (response.ok) {
        setRoles(data.roles);
        setPagination(data.pagination);
      } else {
        toast.error(data.error || 'Failed to fetch roles');
      }
    } catch {
      toast.error('Failed to fetch roles');
    } finally {
      setLoading(false);
    }
  }, [filters, pagination.limit]);

  // Handle filter changes
  const handleFilterChange = (newFilters: FilterValues) => {
    setFilters(newFilters);
    fetchRoles(1, newFilters);
  };

  // Handle page change
  const handlePageChange = (page: number) => {
    fetchRoles(page);
  };

  // Toggle filters visibility
  const toggleFilters = () => {
    setShowFilters(!showFilters);
  };

  // Handle role deletion with custom alert
  const handleDeleteClick = (role: Role) => {
    if (!canDeleteRole) {
      toast.error('You do not have permission to delete roles');
      return;
    }

    // Check if role has users before showing alert
    if (role.users_count > 0) {
      showAlert({
        title: 'Cannot Delete Role',
        message: `The role "${role.name}" is currently assigned to ${role.users_count} user(s). Please remove this role from all users before deleting.`,
        confirmText: 'OK',
        cancelText: '',
        type: 'warning',
        onConfirm: () => {},
      });
      return;
    }

    showAlert({
      title: 'Delete Role',
      message: `Are you sure you want to delete the role "${role.name}"? This action cannot be undone and will remove all permissions associated with this role.`,
      confirmText: 'Delete Role',
      cancelText: 'Cancel',
      type: 'danger',
      onConfirm: () => deleteRole(role.id),
    });
  };

  // Actual delete function
  const deleteRole = async (roleId: string) => {
    try {
      const response = await fetch(`/api/backend/admin/roles/${roleId}`, {
        method: 'DELETE',
      });

      const data = await response.json();

      if (response.ok) {
        toast.success(data.message || 'Role deleted successfully');
        fetchRoles(pagination.page);
      } else {
        if (response.status === 409) {
          toast.error(data.error || 'Cannot delete role assigned to users');
        } else {
          toast.error(data.error || 'Failed to delete role');
        }
      }
    } catch {
      toast.error('Failed to delete role');
    }
  };

  // Handle bulk delete
  const handleBulkDelete = async (selectedIds: string[]) => {
    // Check if any selected roles have users
    const rolesWithUsers = roles.filter(
      role => selectedIds.includes(role.id) && role.users_count > 0
    );

    if (rolesWithUsers.length > 0) {
      const roleNames = rolesWithUsers.map(r => r.name).join(', ');
      showAlert({
        title: 'Cannot Delete Some Roles',
        message: `The following roles have users assigned and cannot be deleted: ${roleNames}. These roles will be skipped automatically.`,
        confirmText: 'Continue with remaining roles',
        cancelText: 'Cancel',
        type: 'warning',
        onConfirm: () => performBulkDelete(selectedIds),
      });
      return;
    }

    performBulkDelete(selectedIds);
  };

  const performBulkDelete = async (selectedIds: string[]) => {
    try {
      const response = await fetch('/api/backend/admin/roles/bulk-delete', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ids: selectedIds }),
      });

      const data = await response.json();

      if (response.ok) {
        if (data.skipped && data.skipped.length > 0) {
          // Show detailed toast with skipped items
          const skippedNames = data.skipped.map((s: {name: string}) => s.name).join(', ');
          toast.success(
            `${data.deletedCount} role${data.deletedCount !== 1 ? 's' : ''} deleted, ${data.skipped.length} skipped: ${skippedNames}`
          );
        } else {
          toast.success(data.message);
        }
        fetchRoles(pagination.page);
      } else {
        toast.error(data.error || 'Bulk delete failed');
      }
    } catch {
      toast.error('Bulk delete failed');
    }
  };

  // Bulk actions configuration
  const bulkActions = [
    ...(canBulkDelete ? [{
      key: 'bulk-delete',
      label: 'Delete selected',
      icon: (
        <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
            d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
        </svg>
      ),
      className: 'bg-red-100 text-red-700 hover:bg-red-200 dark:bg-red-900/30 dark:text-red-400 dark:hover:bg-red-900/50',
      requiresConfirm: true,
      confirmTitle: 'Delete selected roles',
      confirmMessage: (count: number) => {
        return `Are you sure you want to delete ${count} role${count !== 1 ? 's' : ''}? Roles that have users assigned will be skipped automatically. This action cannot be undone.`;
      },
      onClick: handleBulkDelete,
    }] : []),
  ];

  // Table columns configuration
  const columns: TableColumn<Role>[] = [
    {
      key: 'role',
      label: 'Role',
      render: (role) => (
        <div>
          <div className="text-sm font-semibold text-var-text">{role.name}</div>
          <div className="text-sm text-var-text-muted mt-1">{role.description}</div>
        </div>
      )
    },
    {
      key: 'permissions',
      label: 'Permissions',
      render: (role) => (
        <span className={`inline-flex items-center px-3 py-1 rounded-full text-xs font-medium ${
          role.permissions_count > 0 
            ? 'bg-var-info-bg text-var-info-text' 
            : 'bg-var-primary-muted text-var-text-muted'
        }`}>
          {role.permissions_count} permission{role.permissions_count !== 1 ? 's' : ''}
        </span>
      )
    },
    {
      key: 'users',
      label: 'Users',
      render: (role) => (
        <span className={`inline-flex items-center px-3 py-1 rounded-full text-xs font-medium ${
          role.users_count > 0 
            ? 'bg-var-primary-muted text-var-primary-text' 
            : 'bg-var-surface-hover text-var-text-muted'
        }`}>
          {role.users_count} user{role.users_count !== 1 ? 's' : ''}
        </span>
      )
    },
    {
      key: 'created_at',
      label: 'Created',
      render: (role) => (
        <span className="text-sm text-var-text-muted">
          {new Date(role.created_at).toLocaleDateString()}
        </span>
      )
    }
  ];

  // Table actions configuration
  const actions: TableAction<Role>[] = [
    // Edit button
    ...(canEditRole ? [{
      key: 'edit',
      icon: (
        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
        </svg>
      ),
      onClick: (role: Role) => {
        router.push(`/admin/dashboard/employees/roles/edit/${role.id}`);
      },
      className: 'text-var-primary hover:text-var-primary-hover hover:bg-var-primary-muted',
      title: 'Edit role'
    }] : []),

    // Delete button
    ...(canDeleteRole ? [{
      key: 'delete',
      icon: (
        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
        </svg>
      ),
      onClick: (role: Role) => handleDeleteClick(role),
      className: (role: Role) => 
        role.users_count > 0
          ? 'text-var-text-disabled cursor-not-allowed'
          : 'text-var-danger hover:text-var-danger hover:bg-var-danger-bg',
      title: (role: Role) => 
        role.users_count > 0 
          ? 'Cannot delete role with assigned users' 
          : 'Delete role'
    }] : [])
  ];

  useEffect(() => {
    if (!initialData) {
      fetchRoles();
    }
  }, [fetchRoles, initialData]);

  return (
    <div className="bg-var-surface rounded-2xl shadow-var-card border border-var-border overflow-hidden">
      {/* Header */}
      <div className="px-6 py-4 border-b border-var-border bg-var-surface-raised/50">
        <div className="flex flex-col lg:flex-row lg:items-center lg:justify-between space-y-4 lg:space-y-0">
          <div>
            <h2 className="text-lg font-semibold text-var-text">Roles Management</h2>
            <p className="text-sm text-var-text-muted mt-1">
              {pagination.total} role{pagination.total !== 1 ? 's' : ''} found
            </p>
          </div>
          
          <div className="flex items-center space-x-3">
            {/* Filter Toggle Button */}
            <button
              onClick={toggleFilters}
              className="inline-flex items-center px-3 py-2 text-sm font-medium rounded-xl transition-all duration-200 bg-var-surface border border-var-border text-var-text-secondary hover:bg-var-surface-hover hover:text-var-text"
              aria-label={showFilters ? "Hide filters" : "Show filters"}
            >
              <svg className="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} 
                  d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z" 
                />
              </svg>
              {showFilters ? 'Hide Filters' : 'Show Filters'}
            </button>

            {canCreateRole && (
              <Link
                href="/admin/dashboard/employees/roles/new"
                className="inline-flex items-center px-4 py-2 bg-var-primary text-white font-medium rounded-xl hover:bg-var-primary-hover transition-all duration-200 shadow-var-button hover:shadow-var-card"
              >
                <svg className="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
                </svg>
                Add Role
              </Link>
            )}
          </div>
        </div>

        {/* Filters - Conditionally visible */}
        {showFilters && (
          <div className="mt-4 transition-all duration-300 ease-in-out">
            <TableFilters
              filters={filterConfigs}
              onFilterChange={handleFilterChange}
              initialValues={filters}
            />
          </div>
        )}
      </div>

      {/* Table */}
      <DataTable
        data={roles}
        columns={columns}
        actions={actions}
        bulkActions={bulkActions}
        loading={loading}
        emptyMessage="No roles found"
        emptyDescription="Try adjusting your search or create a new role"
        onCreateNew={canCreateRole ? () => {
          router.push('/admin/dashboard/employees/roles/new');
        } : undefined}
        createNewLabel="Create your first role →"
        keyExtractor={(role) => role.id}
      />

      {/* Pagination */}
      <TablePagination
        pagination={pagination}
        onPageChange={handlePageChange}
      />
    </div>
  );
}