'use client';

import { useState, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '@/infrastructure/api/api-client';
import { queryKeys } from '@/infrastructure/api/query-keys';
import { cn } from '@/lib/utils';

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

interface Permission {
  id: string;
  key: string;
  resource: string;
  action: 'create' | 'read' | 'update' | 'delete' | 'execute';
  description: string;
}

interface Role {
  id: string;
  name: string;
  isSystem: boolean;
}

interface PermissionMatrixEntry {
  roleId: string;
  permissionId: string;
  granted: boolean;
}

type PermissionsResponse = Permission[];

interface MatrixResponse {
  roles: Role[];
  permissions: Permission[];
  matrix: PermissionMatrixEntry[];
}

// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------

const ACTION_COLORS: Record<Permission['action'], string> = {
  create: 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400',
  read: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400',
  update: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400',
  delete: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400',
  execute: 'bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-400',
};

// ---------------------------------------------------------------------------
// Action badge
// ---------------------------------------------------------------------------

function ActionBadge({ action }: { action: Permission['action'] }) {
  const { t } = useTranslation('security');
  return (
    <span
      className={cn(
        'inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium capitalize',
        ACTION_COLORS[action],
      )}
    >
      {t(`permissions.actionTypes.${action}`)}
    </span>
  );
}

// ---------------------------------------------------------------------------
// Permission info dialog
// ---------------------------------------------------------------------------

function PermissionInfoDialog({
  open,
  permission,
  onClose,
}: {
  open: boolean;
  permission: Permission | null;
  onClose: () => void;
}) {
  const { t } = useTranslation('security');
  const { t: tc } = useTranslation('common');
  if (!open || !permission) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      <div className="absolute inset-0 bg-black/50" onClick={onClose} />
      <div className="relative z-10 w-full max-w-sm bg-card border rounded-lg shadow-lg p-6 mx-4">
        <h2 className="text-lg font-semibold mb-4">{t('permissions.detailDialog.title')}</h2>

        <dl className="space-y-3">
          <div>
            <dt className="text-xs text-muted-foreground uppercase tracking-wide">{t('permissions.detailDialog.key')}</dt>
            <dd className="text-sm font-medium font-mono mt-0.5">{permission.key}</dd>
          </div>
          <div>
            <dt className="text-xs text-muted-foreground uppercase tracking-wide">{t('permissions.detailDialog.resource')}</dt>
            <dd className="text-sm font-medium capitalize mt-0.5">{permission.resource}</dd>
          </div>
          <div>
            <dt className="text-xs text-muted-foreground uppercase tracking-wide">{t('permissions.detailDialog.action')}</dt>
            <dd className="mt-0.5">
              <ActionBadge action={permission.action} />
            </dd>
          </div>
          <div>
            <dt className="text-xs text-muted-foreground uppercase tracking-wide">{t('permissions.detailDialog.description')}</dt>
            <dd className="text-sm mt-0.5">{permission.description || '--'}</dd>
          </div>
        </dl>

        <div className="flex justify-end mt-6 pt-4 border-t">
          <button
            onClick={onClose}
            className="px-4 py-2 text-sm rounded-md border border-input hover:bg-accent"
          >
            {tc('close')}
          </button>
        </div>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Main page component
// ---------------------------------------------------------------------------

export default function PermissionsPage() {
  const { t } = useTranslation('security');
  const { t: tc } = useTranslation('common');
  const queryClient = useQueryClient();

  // State ----------------------------------------------------------------
  const [selectedPermission, setSelectedPermission] = useState<Permission | null>(null);
  const [resourceFilter, setResourceFilter] = useState<string>('all');

  // Queries --------------------------------------------------------------
  const { data: matrixData, isLoading, error } = useQuery({
    queryKey: queryKeys.permissions.matrix(),
    queryFn: () => apiClient<MatrixResponse>('/api/v1/auth/permissions/matrix'),
  });

  const roles = matrixData?.roles ?? [];
  const permissions = matrixData?.permissions ?? [];
  const matrixEntries = matrixData?.matrix ?? [];

  // Build lookup map: `${roleId}:${permissionId}` -> granted
  const grantedMap = useMemo(() => {
    const map = new Map<string, boolean>();
    for (const entry of matrixEntries) {
      map.set(`${entry.roleId}:${entry.permissionId}`, entry.granted);
    }
    return map;
  }, [matrixEntries]);

  // Extract unique resources
  const resources = useMemo(() => {
    const set = new Set(permissions.map((p) => p.resource));
    return Array.from(set).sort();
  }, [permissions]);

  // Filter permissions by resource
  const filteredPermissions = useMemo(() => {
    if (resourceFilter === 'all') return permissions;
    return permissions.filter((p) => p.resource === resourceFilter);
  }, [permissions, resourceFilter]);

  // Group filtered permissions by resource for display
  const groupedPermissions = useMemo(() => {
    const groups: Record<string, Permission[]> = {};
    for (const perm of filteredPermissions) {
      const resource = perm.resource || 'general';
      if (!groups[resource]) groups[resource] = [];
      groups[resource].push(perm);
    }
    return groups;
  }, [filteredPermissions]);

  // Mutations ------------------------------------------------------------
  const toggleMutation = useMutation({
    mutationFn: ({
      roleId,
      permissionId,
      grant,
    }: {
      roleId: string;
      permissionId: string;
      grant: boolean;
    }) =>
      apiClient<void>('/api/v1/auth/permissions/matrix', {
        method: 'PATCH',
        body: { roleId, permissionId, grant },
      }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: queryKeys.permissions.all });
    },
  });

  // Helpers --------------------------------------------------------------
  const isGranted = useCallback(
    (roleId: string, permissionId: string): boolean => {
      return grantedMap.get(`${roleId}:${permissionId}`) ?? false;
    },
    [grantedMap],
  );

  const handleToggle = useCallback(
    (roleId: string, permissionId: string) => {
      const currentlyGranted = isGranted(roleId, permissionId);
      toggleMutation.mutate({
        roleId,
        permissionId,
        grant: !currentlyGranted,
      });
    },
    [isGranted, toggleMutation],
  );

  // Render ---------------------------------------------------------------
  return (
    <div>
      {/* Header */}
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6">
        <div>
          <h1 className="text-2xl font-bold">{t('permissions.title')}</h1>
          <p className="text-sm text-muted-foreground mt-1">
            {t('permissions.subtitle')}
          </p>
        </div>
      </div>

      {/* Resource filter */}
      <div className="flex flex-wrap items-center gap-2 mb-6">
        <span className="text-sm text-muted-foreground">{t('permissions.resource')}:</span>
        <div className="flex gap-1 p-1 bg-muted rounded-lg flex-wrap">
          <button
            onClick={() => setResourceFilter('all')}
            className={cn(
              'px-3 py-1.5 text-sm rounded-md font-medium transition-colors',
              resourceFilter === 'all'
                ? 'bg-background text-foreground shadow-sm'
                : 'text-muted-foreground hover:text-foreground',
            )}
          >
            {tc('all')}
          </button>
          {resources.map((resource) => (
            <button
              key={resource}
              onClick={() => setResourceFilter(resource)}
              className={cn(
                'px-3 py-1.5 text-sm rounded-md font-medium transition-colors capitalize',
                resourceFilter === resource
                  ? 'bg-background text-foreground shadow-sm'
                  : 'text-muted-foreground hover:text-foreground',
              )}
            >
              {resource}
            </button>
          ))}
        </div>
      </div>

      {/* Error state */}
      {error && (
        <div className="p-4 mb-4 rounded-md border border-destructive/50 bg-destructive/10 text-destructive text-sm">
          {t('permissions.loadError')} {(error as Error).message}
        </div>
      )}

      {/* Loading state */}
      {isLoading && (
        <div className="text-sm text-muted-foreground py-12 text-center">
          {t('permissions.loading')}
        </div>
      )}

      {/* Permission matrix table - grouped by resource */}
      {!isLoading && !error && (
        <div className="space-y-6">
          {Object.keys(groupedPermissions).length === 0 ? (
            <div className="text-sm text-muted-foreground py-12 text-center">
              {t('permissions.empty')}
            </div>
          ) : (
            Object.entries(groupedPermissions).map(([resource, perms]) => (
              <div key={resource} className="border rounded-lg overflow-hidden">
                <div className="bg-muted/50 px-4 py-2 border-b">
                  <h3 className="text-sm font-semibold capitalize">{resource}</h3>
                </div>
                <div className="overflow-x-auto">
                  <table className="w-full text-sm">
                    <thead>
                      <tr className="border-b bg-muted/30">
                        <th className="text-left px-4 py-3 font-medium min-w-[200px]">
                          {t('permissions.permission')}
                        </th>
                        <th className="text-left px-4 py-3 font-medium">{t('permissions.action')}</th>
                        {roles.map((role) => (
                          <th
                            key={role.id}
                            className="text-center px-3 py-3 font-medium whitespace-nowrap min-w-[100px]"
                          >
                            <span className="capitalize">{role.name}</span>
                            {role.isSystem && (
                              <span className="block text-[10px] text-muted-foreground font-normal">
                                built-in
                              </span>
                            )}
                          </th>
                        ))}
                      </tr>
                    </thead>
                    <tbody>
                      {perms.map((perm) => (
                        <tr
                          key={perm.id}
                          className="border-b last:border-b-0 hover:bg-muted/20 transition-colors"
                        >
                          <td className="px-4 py-3">
                            <button
                              onClick={() => setSelectedPermission(perm)}
                              className="text-left hover:text-primary transition-colors"
                            >
                              <span className="font-medium text-sm">{perm.key}</span>
                              {perm.description && (
                                <p className="text-xs text-muted-foreground mt-0.5 truncate max-w-[250px]">
                                  {perm.description}
                                </p>
                              )}
                            </button>
                          </td>
                          <td className="px-4 py-3">
                            <ActionBadge action={perm.action} />
                          </td>
                          {roles.map((role) => {
                            const granted = isGranted(role.id, perm.id);
                            return (
                              <td key={role.id} className="text-center px-3 py-3">
                                <input
                                  type="checkbox"
                                  checked={granted}
                                  onChange={() => handleToggle(role.id, perm.id)}
                                  disabled={toggleMutation.isPending}
                                  className="h-4 w-4 rounded border-input text-primary focus:ring-primary cursor-pointer"
                                />
                              </td>
                            );
                          })}
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              </div>
            ))
          )}
        </div>
      )}

      {/* Summary */}
      {!isLoading && !error && permissions.length > 0 && (
        <div className="mt-6 p-4 bg-muted/30 rounded-lg border">
          <h3 className="text-sm font-semibold mb-2">{t('permissions.summary.title')}</h3>
          <div className="grid grid-cols-2 sm:grid-cols-4 gap-4">
            <div>
              <p className="text-xs text-muted-foreground">{t('permissions.summary.totalPermissions')}</p>
              <p className="text-lg font-bold">{permissions.length}</p>
            </div>
            <div>
              <p className="text-xs text-muted-foreground">{t('permissions.summary.totalRoles')}</p>
              <p className="text-lg font-bold">{roles.length}</p>
            </div>
            <div>
              <p className="text-xs text-muted-foreground">{t('permissions.summary.resources')}</p>
              <p className="text-lg font-bold">{resources.length}</p>
            </div>
            <div>
              <p className="text-xs text-muted-foreground">{t('permissions.summary.granted')}</p>
              <p className="text-lg font-bold">
                {matrixEntries.filter((e) => e.granted).length}
              </p>
            </div>
          </div>
        </div>
      )}

      {/* Permission info dialog */}
      <PermissionInfoDialog
        open={!!selectedPermission}
        permission={selectedPermission}
        onClose={() => setSelectedPermission(null)}
      />
    </div>
  );
}
