import { useState, useEffect, type ReactElement } from 'react';
import {
  PrimaryButton,
  StatusBadge,
  ActionDropdown,
  NewRoleModal,
  ViewRoleModal,
  EditRoleModal,
  DeleteConfirmationModal,
  DataTable,
  Pagination,
  FilterDropdown,
  type Column,
} from '@/components/shared';
import { Plus, Download, ArrowUpDown } from 'lucide-react';
import { roleService } from '@/services/role-service';
import type { Role, CreateRoleRequest, UpdateRoleRequest } from '@/types/role';
import { showToast } from '@/utils/toast';
import { formatDate } from '@/utils/format-date';

// Helper function to get scope badge variant
const getScopeVariant = (scope: string): 'success' | 'failure' | 'process' => {
  switch (scope.toLowerCase()) {
    case 'platform':
      return 'success';
    case 'tenant':
      return 'process';
    case 'module':
      return 'failure';
    default:
      return 'success';
  }
};

interface RolesTableProps {
  tenantId?: string | null; // If provided, fetch roles for this tenant only
  showHeader?: boolean; // Show header with title and actions (default: true)
  compact?: boolean; // Compact mode for tabs (default: false)
}

export const RolesTable = ({ tenantId, showHeader = true, compact = false }: RolesTableProps): ReactElement => {
  const [roles, setRoles] = useState<Role[]>([]);
  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [error, setError] = useState<string | null>(null);
  const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
  const [isCreating, setIsCreating] = useState<boolean>(false);

  // Pagination state
  const [currentPage, setCurrentPage] = useState<number>(1);
  const [limit, setLimit] = useState<number>(compact ? 10 : 20);
  const [pagination, setPagination] = useState<{
    page: number;
    limit: number;
    total: number;
    totalPages: number;
    hasMore: boolean;
  }>({
    page: 1,
    limit: compact ? 10 : 20,
    total: 0,
    totalPages: 1,
    hasMore: false,
  });

  // Filter state
  const [scopeFilter, setScopeFilter] = useState<string | null>(null);
  const [orderBy, setOrderBy] = useState<string[] | null>(null);

  // View, Edit, Delete modals
  const [viewModalOpen, setViewModalOpen] = useState<boolean>(false);
  const [editModalOpen, setEditModalOpen] = useState<boolean>(false);
  const [deleteModalOpen, setDeleteModalOpen] = useState<boolean>(false);
  const [selectedRoleId, setSelectedRoleId] = useState<string | null>(null);
  const [selectedRoleName, setSelectedRoleName] = useState<string>('');
  const [isUpdating, setIsUpdating] = useState<boolean>(false);
  const [isDeleting, setIsDeleting] = useState<boolean>(false);

  const fetchRoles = async (
    page: number,
    itemsPerPage: number,
    scope: string | null = null,
    sortBy: string[] | null = null
  ): Promise<void> => {
    try {
      setIsLoading(true);
      setError(null);
      const response = tenantId
        ? await roleService.getByTenant(tenantId, page, itemsPerPage, scope, sortBy)
        : await roleService.getAll(page, itemsPerPage, scope, sortBy);
      if (response.success) {
        setRoles(response.data);
        setPagination(response.pagination);
      } else {
        setError('Failed to load roles');
      }
    } catch (err: any) {
      setError(err?.response?.data?.error?.message || 'Failed to load roles');
    } finally {
      setIsLoading(false);
    }
  };

  useEffect(() => {
    fetchRoles(currentPage, limit, scopeFilter, orderBy);
  }, [currentPage, limit, scopeFilter, orderBy, tenantId]);

  const handleCreateRole = async (data: CreateRoleRequest): Promise<void> => {
    try {
      setIsCreating(true);
      const response = await roleService.create(data);
      const message = response.message || `Role created successfully`;
      const description = response.message ? undefined : `${data.name} has been added`;
      showToast.success(message, description);
      setIsModalOpen(false);
      await fetchRoles(currentPage, limit, scopeFilter, orderBy);
    } catch (err: any) {
      throw err;
    } finally {
      setIsCreating(false);
    }
  };

  // View role handler
  const handleViewRole = (roleId: string): void => {
    setSelectedRoleId(roleId);
    setViewModalOpen(true);
  };

  // Edit role handler
  const handleEditRole = (roleId: string, roleName: string): void => {
    setSelectedRoleId(roleId);
    setSelectedRoleName(roleName);
    setEditModalOpen(true);
  };

  // Update role handler
  const handleUpdateRole = async (id: string, data: UpdateRoleRequest): Promise<void> => {
    try {
      setIsUpdating(true);
      const response = await roleService.update(id, data);
      const message = response.message || `Role updated successfully`;
      const description = response.message ? undefined : `${data.name} has been updated`;
      showToast.success(message, description);
      setEditModalOpen(false);
      setSelectedRoleId(null);
      setSelectedRoleName('');
      await fetchRoles(currentPage, limit, scopeFilter, orderBy);
    } catch (err: any) {
      throw err;
    } finally {
      setIsUpdating(false);
    }
  };

  // Delete role handler
  const handleDeleteRole = (roleId: string, roleName: string): void => {
    setSelectedRoleId(roleId);
    setSelectedRoleName(roleName);
    setDeleteModalOpen(true);
  };

  // Confirm delete handler
  const handleConfirmDelete = async (): Promise<void> => {
    if (!selectedRoleId) return;

    try {
      setIsDeleting(true);
      await roleService.delete(selectedRoleId);
      setDeleteModalOpen(false);
      setSelectedRoleId(null);
      setSelectedRoleName('');
      await fetchRoles(currentPage, limit, scopeFilter, orderBy);
    } catch (err: any) {
      throw err; // Let the modal handle the error display
    } finally {
      setIsDeleting(false);
    }
  };

  // Load role for view/edit
  const loadRole = async (id: string): Promise<Role> => {
    const response = await roleService.getById(id);
    return response.data;
  };

  // Table columns
  const columns: Column<Role>[] = [
    {
      key: 'name',
      label: 'Name',
      render: (role) => (
        <span className="text-sm font-normal text-[#0f1724]">{role.name}</span>
      ),
    },
    {
      key: 'code',
      label: 'Code',
      render: (role) => (
        <span className="text-sm font-normal text-[#0f1724] font-mono">{role.code}</span>
      ),
    },
    {
      key: 'scope',
      label: 'Scope',
      render: (role) => (
        <StatusBadge variant={getScopeVariant(role.scope)}>{role.scope}</StatusBadge>
      ),
    },
    {
      key: 'description',
      label: 'Description',
      render: (role) => (
        <span className="text-sm font-normal text-[#6b7280]">
          {role.description || 'N/A'}
        </span>
      ),
    },
    {
      key: 'is_system',
      label: 'System Role',
      render: (role) => (
        <span className="text-sm font-normal text-[#0f1724]">
          {role.is_system ? 'Yes' : 'No'}
        </span>
      ),
    },
    {
      key: 'created_at',
      label: 'Created Date',
      render: (role) => (
        <span className="text-sm font-normal text-[#6b7280]">{formatDate(role.created_at)}</span>
      ),
    },
    {
      key: 'actions',
      label: 'Actions',
      align: 'right',
      render: (role) => (
        <div className="flex justify-end">
          <ActionDropdown
            onView={() => handleViewRole(role.id)}
            onEdit={() => handleEditRole(role.id, role.name)}
            onDelete={() => handleDeleteRole(role.id, role.name)}
          />
        </div>
      ),
    },
  ];

  // Mobile card renderer
  const mobileCardRenderer = (role: Role) => (
    <div className="p-4">
      <div className="flex items-start justify-between gap-3 mb-3">
        <div className="flex-1 min-w-0">
          <h3 className="text-sm font-medium text-[#0f1724] truncate">{role.name}</h3>
          <p className="text-xs text-[#6b7280] mt-0.5 font-mono">{role.code}</p>
        </div>
        <ActionDropdown
          onView={() => handleViewRole(role.id)}
          onEdit={() => handleEditRole(role.id, role.name)}
          onDelete={() => handleDeleteRole(role.id, role.name)}
        />
      </div>
      <div className="grid grid-cols-2 gap-3 text-xs">
        <div>
          <span className="text-[#9aa6b2]">Scope:</span>
          <div className="mt-1">
            <StatusBadge variant={getScopeVariant(role.scope)}>{role.scope}</StatusBadge>
          </div>
        </div>
        <div>
          <span className="text-[#9aa6b2]">Created:</span>
          <p className="text-[#0f1724] font-normal mt-1">{formatDate(role.created_at)}</p>
        </div>
        {role.description && (
          <div className="col-span-2">
            <span className="text-[#9aa6b2]">Description:</span>
            <p className="text-[#0f1724] font-normal mt-1">{role.description}</p>
          </div>
        )}
      </div>
    </div>
  );

  if (compact) {
    // Compact mode for tabs
    return (
      <>
        <div className="flex flex-col gap-4">
          <div className="flex items-center justify-between">
            <h3 className="text-lg font-semibold text-[#0f1724]">Roles</h3>
            <div className="flex items-center gap-2">
              <FilterDropdown
                label="Scope"
                options={[
                  { value: '', label: 'All Scope' },
                  { value: 'platform', label: 'Platform' },
                  { value: 'tenant', label: 'Tenant' },
                  { value: 'module', label: 'Module' },
                ]}
                value={scopeFilter || ''}
                onChange={(value) => {
                  setScopeFilter(Array.isArray(value) ? null : value || null);
                  setCurrentPage(1);
                }}
                placeholder="Filter by scope"
              />
              <PrimaryButton
                size="default"
                className="flex items-center gap-2"
                onClick={() => setIsModalOpen(true)}
              >
                <Plus className="w-3.5 h-3.5" />
                <span className="text-xs">New Role</span>
              </PrimaryButton>
            </div>
          </div>
          <DataTable
            data={roles}
            columns={columns}
            keyExtractor={(role) => role.id}
            mobileCardRenderer={mobileCardRenderer}
            emptyMessage="No roles found"
            isLoading={isLoading}
            error={error}
          />
          {pagination.totalPages > 1 && (
            <Pagination
              currentPage={currentPage}
              totalPages={pagination.totalPages}
              totalItems={pagination.total}
              limit={limit}
              onPageChange={(page: number) => {
                setCurrentPage(page);
              }}
              onLimitChange={(newLimit: number) => {
                setLimit(newLimit);
                setCurrentPage(1);
              }}
            />
          )}
        </div>

        {/* Modals */}
        <NewRoleModal
          isOpen={isModalOpen}
          onClose={() => setIsModalOpen(false)}
          onSubmit={handleCreateRole}
          isLoading={isCreating}
          defaultTenantId={tenantId || undefined}
        />

        <ViewRoleModal
          isOpen={viewModalOpen}
          onClose={() => {
            setViewModalOpen(false);
            setSelectedRoleId(null);
          }}
          roleId={selectedRoleId}
          onLoadRole={loadRole}
        />

        <EditRoleModal
          isOpen={editModalOpen}
          onClose={() => {
            setEditModalOpen(false);
            setSelectedRoleId(null);
            setSelectedRoleName('');
          }}
          roleId={selectedRoleId}
          onLoadRole={loadRole}
          onSubmit={handleUpdateRole}
          isLoading={isUpdating}
          defaultTenantId={tenantId || undefined}
        />

        <DeleteConfirmationModal
          isOpen={deleteModalOpen}
          onClose={() => {
            setDeleteModalOpen(false);
            setSelectedRoleId(null);
            setSelectedRoleName('');
          }}
          onConfirm={handleConfirmDelete}
          title="Delete Role"
          message={`Are you sure you want to delete this role`}
          itemName={selectedRoleName}
          isLoading={isDeleting}
        />
      </>
    );
  }

  // Full mode with header
  return (
    <>
      {/* Table Container */}
      <div className="bg-white border border-[rgba(0,0,0,0.08)] rounded-lg shadow-[0px_4px_24px_0px_rgba(0,0,0,0.02)] overflow-hidden">
        {/* Table Header with Filters */}
        {showHeader && (
          <div className="border-b border-[rgba(0,0,0,0.08)] px-4 md:px-5 py-3 flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3">
            {/* Filters */}
            <div className="flex flex-wrap items-center gap-3">
              {/* Scope Filter */}
              <FilterDropdown
                label="Scope"
                options={[
                  { value: 'platform', label: 'Platform' },
                  { value: 'tenant', label: 'Tenant' },
                  { value: 'module', label: 'Module' },
                ]}
                value={scopeFilter}
                onChange={(value) => {
                  setScopeFilter(value as string | null);
                  setCurrentPage(1);
                }}
                placeholder="All"
              />

              {/* Sort Filter */}
              <FilterDropdown
                label="Sort by"
                options={[
                  { value: ['name', 'asc'], label: 'Name (A-Z)' },
                  { value: ['name', 'desc'], label: 'Name (Z-A)' },
                  { value: ['code', 'asc'], label: 'Code (A-Z)' },
                  { value: ['code', 'desc'], label: 'Code (Z-A)' },
                  { value: ['created_at', 'asc'], label: 'Created (Oldest)' },
                  { value: ['created_at', 'desc'], label: 'Created (Newest)' },
                  { value: ['updated_at', 'asc'], label: 'Updated (Oldest)' },
                  { value: ['updated_at', 'desc'], label: 'Updated (Newest)' },
                ]}
                value={orderBy}
                onChange={(value) => {
                  setOrderBy(value as string[] | null);
                  setCurrentPage(1);
                }}
                placeholder="Default"
                showIcon
                icon={<ArrowUpDown className="w-3.5 h-3.5 text-[#475569]" />}
              />
            </div>

            {/* Actions */}
            <div className="flex items-center gap-2">
              {/* Export Button */}
              <button
                type="button"
                className="flex items-center gap-1.5 px-3 py-2 bg-white border border-[rgba(0,0,0,0.08)] rounded-md text-xs text-[#0f1724] hover:bg-gray-50 transition-colors cursor-pointer"
              >
                <Download className="w-3.5 h-3.5" />
                <span>Export</span>
              </button>

              {/* New Role Button */}
              <PrimaryButton
                size="default"
                className="flex items-center gap-2"
                onClick={() => setIsModalOpen(true)}
              >
                <Plus className="w-3.5 h-3.5" />
                <span className="text-xs">New Role</span>
              </PrimaryButton>
            </div>
          </div>
        )}

        {/* Data Table */}
        <DataTable
          data={roles}
          columns={columns}
          keyExtractor={(role) => role.id}
          mobileCardRenderer={mobileCardRenderer}
          emptyMessage="No roles found"
          isLoading={isLoading}
          error={error}
        />

        {/* Table Footer with Pagination */}
        {pagination.total > 0 && (
          <Pagination
            currentPage={currentPage}
            totalPages={pagination.totalPages}
            totalItems={pagination.total}
            limit={limit}
            onPageChange={(page: number) => {
              setCurrentPage(page);
            }}
            onLimitChange={(newLimit: number) => {
              setLimit(newLimit);
              setCurrentPage(1);
            }}
          />
        )}
      </div>

      {/* Modals */}
      <NewRoleModal
        isOpen={isModalOpen}
        onClose={() => setIsModalOpen(false)}
        onSubmit={handleCreateRole}
        isLoading={isCreating}
        defaultTenantId={tenantId || undefined}
      />

      <ViewRoleModal
        isOpen={viewModalOpen}
        onClose={() => {
          setViewModalOpen(false);
          setSelectedRoleId(null);
        }}
        roleId={selectedRoleId}
        onLoadRole={loadRole}
      />

      <EditRoleModal
        isOpen={editModalOpen}
        onClose={() => {
          setEditModalOpen(false);
          setSelectedRoleId(null);
          setSelectedRoleName('');
        }}
        roleId={selectedRoleId}
        onLoadRole={loadRole}
        onSubmit={handleUpdateRole}
        isLoading={isUpdating}
        defaultTenantId={tenantId || undefined}
      />

      <DeleteConfirmationModal
        isOpen={deleteModalOpen}
        onClose={() => {
          setDeleteModalOpen(false);
          setSelectedRoleId(null);
          setSelectedRoleName('');
        }}
        onConfirm={handleConfirmDelete}
        title="Delete Role"
        message={`Are you sure you want to delete this role`}
        itemName={selectedRoleName}
        isLoading={isDeleting}
      />
    </>
  );
};
